Tuesday, September 2, 2008

Make MCU Board - Digital Clock (LCD Display) module

To calculate time by using delay method, it will causes obvious time deviation, and display the digital value on a LCD panel.

The LCD type is PVC160203PGL01.

The MCU is PIC 16F877A, define IO as following:

RA2 LCD_EN
RA1 LCD_RW
RA0 LCD_RS
PORTD LCD_DATA

If MCU uses AT89S51/52/53, IO definition is:

P1_2 LCD_EN
P1_1 LCD_RW
P1_0 LCD_RS
P2 LCD_DATA

The circuit schematic:



Main program is as following:

/*******************************************************************************

 Copyright (c) 2008 Wizign Ltd.
 All Rights Reserved.

 main.c: Main program for demo LCD display

 Date: Aug 29, 2008

 Author: YenHung Chen

 E-mail: yhchen@wizign.com

 Revision:
 ---------- -----------------------------------------------------------------
 2008/08/29 Created by YenHung Chen, demo LCD display for both 8051 and PIC

******************************************************************************/
/*******************************************************************************



<>For AT89S52

There are 8 data pins, which are connected P2.
The control pins are connected to P1_0, P1_1, and P1_2.


<>For PIC16F877A

There are 8 data pins, which are connected PORTD
The control pins are connected to RA0, RA1, and RA2.


******************************************************************************/

#include "global.h"
#include "delay.h"
#include "lcd.h"

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// define IO and global variables

#ifdef MCU_PIC

// Configurations
typedef unsigned int config;
config at 0x2007 __CONFIG = _XT_OSC & _PWRTE_OFF & _BODEN_OFF & _WDT_OFF & _LVP_OFF;

#endif

int gTmYr;
unsigned char gTmMon;
unsigned char gTmDay;
unsigned char gTmHr;
unsigned char gTmMin;
unsigned char gTmSec;


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// define functions

/* Initialize the begin time */
void InitCurrentTime(int y, unsigned char m, unsigned char d,
                  unsigned char hr, unsigned char min, unsigned char sec){
 gTmYr = y;
 gTmMon = m;
 gTmDay = d;
 gTmHr = hr;
 gTmMin = min;
 gTmSec = sec;
}

/* Calculate the progressing time */
void CalculateTime(void)
{
 gTmSec++;
 if(gTmSec >= 60){
     gTmSec = 0;
     gTmMin++;
     if(gTmMin >= 60){
         gTmMin = 0;
         gTmHr++;
         if(gTmHr >= 24){
             gTmHr = 0;
             gTmDay++;
             switch(gTmMon){
             case 2:
                 if(((gTmYr%4)==0)&&((gTmYr%100)!=0)&&((gTmYr%400)==0)){
                     if(gTmDay >= 29){
                         gTmDay = 1;
                         gTmMon++;
                     }
                 }else{
                     if(gTmDay >= 28){
                         gTmDay = 1;
                         gTmMon++;
                     }
                 }
                 break;
             case 4:
             case 6:
             case 9:
             case 11:
                 if(gTmDay >= 30){
                     gTmDay = 1;
                     gTmMon++;
                 }
                 break;
             default:    // 31 days/month
                 if(gTmDay >= 31){
                     gTmDay = 1;
                     gTmMon++;
                     if(gTmMon >= 12){
                         gTmMon = 1;
                         gTmYr++;
                     }
                 }
                 break;
             }
         }
     }
 }
}

/* Initilize parameters before run the main loop */
void InitParams(void)
{
 lcd_init();
 InitCurrentTime(2008, 9, 1, 10, 24, 12);
}

/* Power value of 10 */
int PowerTen(int p)
{
 int ret = 1;
 while(--p > 0){
     ret *= 10;
 }
 return ret;
}

/* Convert value to string */
void NumToStr(char* pMsg, int v, int len)
{
 int i;
 int p;
 for(i=0; i
     p = PowerTen(len-i);
     pMsg[i] = 0x30 + (int)(v/p);
     v %= p;
 }
}

/* Convert time value to string message */
void GetTimeMsg(char *pMsg)
{
 NumToStr(&pMsg[0], gTmMon, 2);
 pMsg[2] = '/';
 NumToStr(&pMsg[3], gTmDay, 2);
 pMsg[5] = ' ';
 NumToStr(&pMsg[6], gTmHr, 2);
 pMsg[8] = ':';
 NumToStr(&pMsg[9], gTmMin, 2);
 pMsg[11] = ':';
 NumToStr(&pMsg[12], gTmSec, 2);
 pMsg[14] = 0x00;
}

/* Display message on LCD panel */
void DisplayMessage(void)
{
 char tmMsg[16];

 lcd_goto(0);    // goto 1st line
 lcd_puts("  WIZIGN LTD.  ");

 // Convert value to string
 GetTimeMsg(tmMsg);
 lcd_goto(0x40);    // goto 2nd line
 lcd_puts(tmMsg);
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// main program

void main(void)
{
 // Initilize parameters
 InitParams();

 /* do loop */
 while(1){
     CalculateTime();
     DisplayMessage();
     // The LCD display and the calculation of time
     // will consume times, so, the delay time is less than 1000 ms.
     DelayMs(900);
 }
}

No comments: