当前位置: 代码迷 >> 单片机 >> 来指导上。小弟我用C语言写了两天的日历时钟,有闹钟功能、计时功能
  详细解决方案

来指导上。小弟我用C语言写了两天的日历时钟,有闹钟功能、计时功能

热度:62   发布时间:2016-04-28 15:49:54.0
高手进来指导下。我用C语言写了两天的日历时钟,有闹钟功能、计时功能。
C/C++ code
#include<reg52.h>#include<stdlib.h>#define UCHAR unsigned char#define UINT unsigned intvoid init();void delay(UINT);void displayWeek(UCHAR week);void displayTime(UCHAR first, UCHAR second);void writeCmd(UCHAR cmd);void writeData(UCHAR dat);UCHAR keyscan();void keyUpDown(UCHAR *value, bit up, bit down);bit processDayMon(UCHAR *day, UCHAR *month);void display(UCHAR *seconds, UCHAR *minute, UCHAR *hour, UCHAR *day, UCHAR *week, UCHAR *month, bit displayOn);UCHAR getWeek(UCHAR day, UCHAR month, UINT year);void timeUpdate(UCHAR *value, UCHAR *nextValue, UCHAR largest, UCHAR smallest);void displayCounter(UCHAR *minute, UCHAR *seconds, UCHAR *tenMs);void recoverClock();void update();  sbit rs = P1^1;    //rs 数据/命令选择端 sbit lcden = P1^2;sbit beep = P1^0;UCHAR seconds,minute,hour, week, day, month;  UCHAR alarmMinute, alarmHour;UCHAR countMinute, countSeconds, countTenMs;UCHAR keyValue, key1Times, key2Times, key3Times, key5Times, key6Times, key7Times, key9Times;UINT year;UINT cnt0, cnt1; bit leapYear, alarmOn;bit flagTimer0, flagTimer1;bit timeUp, timeDown;UCHAR code weekTable[][3] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};UCHAR code monthTable[][12] = {    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};void main(){    init();    while(1)    {        update();    }}void update(){    keyValue = keyscan();        switch(keyValue)    {        case 1:while(keyscan() == 1); //等待按键松开             if(++key1Times == 2) //第二次按下恢复时钟界面             {                key1Times = 0;                recoverClock();                 break;                         }            writeCmd(0x01); //第一次按下清屏              displayCounter(&countMinute, &countSeconds, &countTenMs);//初始化计时界面             break;        case 2:while(keyscan() == 2);if(++key2Times == 7)key2Times = 0;break;        case 3:while(keyscan() == 3);            if(++key3Times == 3)             {                key3Times = 0;                beep = 1; //关闭闹钟                 writeCmd(0x80 + 0x4e); //第二次按下清除 "On"标记                  writeData(' ');                writeData(' ');            }            break;                case 5:while(keyscan() == 5);timeUp = 1;break;        case 6:while(keyscan() == 6);timeDown = 1;break;        case 7:while(keyscan() == 7);if(++key7Times == 3)key7Times = 0;break;        case 9:while(keyscan() == 9);if(++key9Times == 3)key9Times = 1;break;            }    keyValue = 0;    if(flagTimer0) /*每增加一秒时刷新时间变量 */      {        flagTimer0 = 0;        seconds++;        if(key3Times != 1 && key1Times != 1)  //在时钟状态下才刷新时间变量及其屏幕显示             display(&seconds, &minute, &hour, &day, &week, &month, 1);         else   //仅刷新时间变量,不刷新显示             display(&seconds, &minute, &hour, &day, &week, &month, 0);    }            /*当调整时间时,根据按下key2键的次数         *将光标移到相应的位置进行闪烁      */    if(key2Times && key3Times != 1 && key1Times != 1) //在时钟状态下按下key2     {           writeCmd(0x0f); //显示光标         switch(key2Times) //根据按下key2Times的次数把光标移到相应的位置进行闪烁         {             case 1:writeCmd(0x80 + 0x4a); //光标移到秒处进行闪烁                  keyUpDown(&seconds, timeUp, timeDown);                break;             case 2:writeCmd(0x80 + 0x47);//分                 keyUpDown(&minute, timeUp, timeDown);                break;             case 3:writeCmd(0x80 + 0x44);  //时                 keyUpDown(&hour ,timeUp, timeDown);                break;             case 4:writeCmd(0x80 + 0x0a);  //日                 keyUpDown(&day, timeUp, timeDown);                break;             case 5:writeCmd(0x80 + 0x07); //月                 keyUpDown(&month, timeUp, timeDown);                break;             case 6:writeCmd(0x80 + 0x04); //年                 if(timeUp == 1)  //加一                    year++;                else if(timeDown == 1) //减一                    year--;                break;             case 7:writeCmd(0x0c);key2Times = 0;break; //正常显示时钟          }        if(timeUp || timeDown)  //如果有按下调整时间的键盘则刷新时间         {               display(&seconds, &minute, &hour, &day, &week, &month, 1);              timeUp = timeDown = 0; //刷新完时间后让调整时间的变量标记归0          }                     }    if(key3Times == 1) //第一次按下设置闹钟时间      {        writeCmd(0x0c);        writeCmd(0x80 + 0x4d);        writeData('S');    //显示"Set",进入设置闹钟界面         writeData('e');        writeData('t');        writeCmd(0x0f);        switch(key7Times)        {                        case 1:writeCmd(0x80 + 0x47);//进入设置分的状态                 keyUpDown(&alarmMinute, timeUp, timeDown);                break;             case 2:writeCmd(0x80 + 0x44);  //时                 keyUpDown(&alarmHour ,timeUp, timeDown);                break;            }        if(timeUp || timeDown)        {            timeUpdate(&alarmMinute, &alarmHour, 59, 0);            if(alarmHour == 24)                alarmHour = 0;             writeCmd(0x80 + 0x47);            displayTime(alarmMinute / 10, alarmMinute % 10);            writeCmd(0x80 + 0x44);            displayTime(alarmHour / 10, alarmHour % 10);             timeUp = timeDown = 0;                }    }    else if(key3Times == 2) //设置好闹钟返回时钟界面并开启闹钟     {        writeCmd(0x0c);        writeCmd(0x80 + 0x4d);        writeData(' ');         writeData('O'); //显示"On",提示闹钟已开启         writeData('n');        if(alarmMinute == minute && alarmHour == hour)        {            alarmOn = 1; //闹钟时间到了                 }        if(alarmOn == 1)        {               beep = ~beep;            delay(rand() % 100);            //超时三分钟自动关闭闹钟             if(hour == alarmHour && minute - alarmMinute > 2)            {                alarmOn = 0;            }            else if(hour > alarmHour && minute + 60 - alarmMinute > 2)            {                alarmOn = 0;            }        }               }     if(key1Times)  //计时器界面     {   //displayCounter(&countMinute, &countSeconds, &countTenMs);        if(key9Times == 1)        {            TR1 = 1;            if(flagTimer1)            {                countTenMs++;                displayCounter(&countMinute, &countSeconds, &countTenMs);                flagTimer1 = 0;            }        }         else if(key9Times == 2)        {            TR1 = 0;        }                  }         } void writeCmd(UCHAR cmd){    rs = 0; //命令选择端     P0 = cmd;    lcden = 1;    delay(1);    lcden = 0;   }void writeData(UCHAR dat){    rs = 1; //数据选择端       P0 = dat;    lcden = 1;    delay(1); //延时让数据写到液晶上去     lcden = 0;  }      void init(){       alarmOn = 0;    alarmHour = 12;    alarmMinute = 1;    countMinute = countSeconds = countTenMs = 0;    TMOD = 0X11;    EA = 1;    ET0 = 1;    ET1 = 1;    TR0 = 1;    writeCmd(0x38); //设置显示模式       writeCmd(0x0c); //设置显示开关及光标         /*下面初始化时间变量      *2010-05-26  Wed         12:00:00     */    year = 2010;    month = 5;    day = 26;    week = 3; //星期三     hour = 12;    minute = 0;    seconds = 0;    leapYear = (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);    /*初始化时液晶显示 */    writeCmd(0x80 + 0x02);    displayTime(year / 1000, year / 100 % 10);    displayTime(year % 100 / 10, year % 10);    writeData('-');    displayTime(month / 10, month % 10);    writeData('-');    displayTime(day / 10, day % 10);    writeData(' '); //光标向前移动一 位     displayWeek(week);    writeCmd(0x80 + 0x44);    displayTime(hour / 10, hour % 10);    writeData(':');    displayTime(minute / 10, minute % 10);    writeData(':');    displayTime(seconds / 10, seconds % 10);          }  void timer0() interrupt 1{    TH0 = (65536 - 46080) / 256;  //定时时间为50ms    TL0 = (65536 - 46080) % 256;    if(++cnt0 == 20)    {        cnt0 = 0;        flagTimer0 = 1;                 }     }void timer1() interrupt 3{    TH0 = (65536 - 9216) / 256; //定时时间为 10ms;    TL0 = (65536 - 9216) % 256;    if(++cnt1 == 1)    {        cnt1 = 0;        flagTimer1 = 1;    }}          void delay(UINT ms){    UINT x, y;    for(x = ms; x; x--)        for(y = 197; y; y--)            ;}
  相关解决方案