打印
[单片机资料]

时钟控制器(电子时钟)

[复制链接]
2416|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
两只袜子|  楼主 | 2021-8-23 11:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
基于电子钟的控制器,其实相当于是闹钟的功能。学习来源是根据宋雪松老师的《手把手教你学单片机》。通过stc89c52+LCD1602+DS1302+矩阵按键+LED小灯实现的。具体现象,到固定时间小灯会自主亮灭。程序分为5个部分。程序所实现的现象为在10:00,10:02,10:05开始亮,在10:01,10:04,10:06开始灭。
protues的仿真图在下方

一:LCD1602液晶模块




  • #include <reg52.h>
  • //控制LCD1602的位
  • #define LCD1602_DB P0        //数据位
  • sbit LCD1602_RS = P2^6;        //指令/数据选择信号
  • sbit LCD1602_RW = P2^5;        //读写选择信号
  • sbit LCD1602_E = P2^7;        //使能信号
  • /*LCD1602状态检测函数DB7为忙标志位,为1时禁止,为0是工作*/
  • void LcdWaitReady()
  • {
  •         unsigned char sta;                //用来缓存LCD1602_DB的值
  •         LCD1602_DB = 0xff;                //赋初值
  •         LCD1602_RS = 0;
  •         LCD1602_RW = 1;
  •         do {
  •                 LCD1602_E = 1;
  •                 sta = LCD1602_DB;
  •                 LCD1602_E = 0;
  •         }while (sta&0x80);         //当DB7为0时结束循环
  • }
  • /*LCD1602写指令函数,形参cmd-要输入的指令*/
  • void LcdWriteCmd(unsigned char cmd)
  • {
  •         LcdWaitReady();                //检测状态函数
  •         LCD1602_RS = 0;                //根据LCD1602时序图所写
  •         LCD1602_RW = 0;
  •         LCD1602_DB = cmd;
  •         LCD1602_E = 1;
  •         LCD1602_E = 0;
  • }
  • /*LCD1602设置坐标函数,形参(x,y)-书写坐标*/
  • void LcdSetCursor(unsigned char x, unsigned char y)
  • {
  •         unsigned char addr;                        //书写地址
  •         if (y == 0)
  •                 addr = x + 0x00;
  •         else
  •                 addr = x + 0x40;
  •         LcdWriteCmd(addr | 0x80);  //写入书写的地址
  • }
  • /*LCD1602写入数据函数,形参dat-要写入的数据*/
  • void LcdWriteDat(unsigned char dat)
  • {
  •         LcdWaitReady();                                //状态检测函数
  •         LCD1602_RS = 1;
  •         LCD1602_RW = 0;
  •         LCD1602_DB = dat;
  •         LCD1602_E = 1;
  •         LCD1602_E = 0;
  • }
  • /*LCD1602开光标函数*/
  • void LcdOpenCursor()
  • {
  •         LcdWriteCmd(0x0f);
  • }
  • /*LCD1602关闭光标函数*/
  • void LcdCloseCursor()
  • {
  •         LcdWriteCmd(0x0c);
  • }
  • /*LCD1602显示字符函数,形参(x,y)-代表书写坐标,str-所写字符串的指针*/
  • void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
  • {
  •         LcdSetCursor(x, y);                        //设置坐标函数
  •         while (*str != '\0')
  •         {
  •                 LcdWriteDat(*str++);         //写数据函数
  •         }
  • }
  • /*LCD1602液晶初始化函数*/
  • void InitLcd1602()
  • {
  •         LcdWriteCmd(0x38);        //写指令函数。功能设置,8位数据总线,两行显示,5*7点阵
  •         LcdWriteCmd(0x0c);        //显示开关控制,开显示,游标不显示
  •         LcdWriteCmd(0x06);        //完成一个字符码传送后,光标右移,地址自动加1
  •         LcdWriteCmd(0x01);        //清显示
  • }


[color=rgb(51, 102, 153) !important]复制代码




二:矩阵按键模块




  • #include <reg52.h>
  • //控制按键的位
  • sbit keyout1 = P1^7;
  • sbit keyout2 = P1^6;
  • sbit keyout3 = P1^5;
  • sbit keyout4 = P1^4;
  • sbit keyin1 = P1^3;
  • sbit keyin2 = P1^2;
  • sbit keyin3 = P1^1;
  • sbit keyin4 = P1^0;
  • unsigned char code KeyCodeMap[4][4] = {         //矩阵按键编号到标准键盘键码的印射表
  •         {'1', '2', '3', 0x26},                                 //数字键1,数字键2,数字键3,向上键
  •         {'4', '5', '6', 0x25},                                 //数字键4,数字键5,数字键6,向左键
  •         {'7', '8', '9', 0x28},                                 //数字键7,数字键8,数字键9,向下键
  •         {'0', 0x1b, 0x0d, 0x27}                                 //数字键0,ESC键,回车键,向右键
  • };
  • //用来保存按键的状态
  • unsigned char keysta[4][4] = {
  •         {1, 1, 1, 1},{1, 1, 1, 1},{1, 1, 1, 1},{1, 1, 1, 1}
  • };
  • extern void KeyAction(unsigned char keycode);
  • /*按键驱动函数,用来调用按键*/
  • void KeyDriver()
  • {        //用来保存上一次按键的状态
  •         static unsigned char backup[4][4] = {
  •                 {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
  •         };
  •         unsigned char i;
  •         unsigned char j;
  •         for (i = 0; i < 4; i++)        //构建两层循环来完成对矩阵按键的扫描
  •         {
  •                 for (j = 0; j < 4; j++)
  •                 {
  •                         if (keysta[j] != backup[j])
  •                         {
  •                                 if (backup[j] != 0)
  •                                 {
  •                                         KeyAction(KeyCodeMap[j]); //通过按键位置来执行相应的程序
  •                                 }
  •                                 backup[j] = keysta[j];
  •                         }
  •                 }
  •         }
  • }
  • /*按键扫描函数,通过定时器0中断来完成1ms扫描一次*/
  • void KeyScan()
  • {
  •         static unsigned char keyout = 0;
  •         static unsigned char keybuff[4][4] = {        //用来消抖
  •                 {0xff, 0xff, 0xff, 0xff},{0xff, 0xff, 0xff, 0xff},
  •                 {0xff, 0xff, 0xff, 0xff},{0xff, 0xff, 0xff, 0xff}
  •         };
  •         unsigned char i;
  •         //将一行的4个按键值移入缓冲区
  •         keybuff[keyout][0] = (keybuff[keyout][0] << 1)|keyin1;
  •         keybuff[keyout][1] = (keybuff[keyout][1] << 1)|keyin2;
  •         keybuff[keyout][2] = (keybuff[keyout][2] << 1)|keyin3;
  •         keybuff[keyout][3] = (keybuff[keyout][3] << 1)|keyin4;
  •         //消抖后更新按键状态
  •         for (i = 0; i < 4; i++)
  •         {
  •                 if ((keybuff[keyout]&0x0f) == 0x0f)
  •                 {//连续4次扫描值为1,即4*4ms内都是弹起状态时,可以认为按键已稳定弹起
  •                         keysta[keyout] = 1;
  •                 }
  •                 else if ((keybuff[keyout]&0x0f) == 0x00)
  •                 {//连续4次扫描值为0,即4*4ms内都是按下状态时,可以认为按键已稳定按下
  •                         keysta[keyout] = 0;
  •                 }
  •         }
  •         keyout++;
  •         if (keyout >= 4)
  •                 keyout = 0;
  •         switch (keyout)
  •         {  //每次拉低一个按键的值
  •                 case 0:keyout1=0;keyout2=1;keyout3=1;keyout4=1;break;
  •                 case 1:keyout1=1;keyout2=0;keyout3=1;keyout4=1;break;
  •                 case 2:keyout1=1;keyout2=1;keyout3=0;keyout4=1;break;
  •                 case 3:keyout1=1;keyout2=1;keyout3=1;keyout4=0;break;
  •                 default:break;
  •         }
  • }



[color=rgb(51, 102, 153) !important]复制代码


三:DS1302时钟芯片模块(单字节读出函数未使用)




  • #include <reg52.h>
  • #include <intrins.h>
  • //控制DS1302时钟的位
  • sbit DS1302_SK = P3^6;                        //时钟信号端,通过控制其高低电平来输入/输出数据
  • sbit DS1302_IO = P3^4;                        //输入输出数据端
  • sbit DS1302_CE = P3^5;                        //使能端,高电平时有效
  • struct sTime {                                           //定义时间结构体
  •         unsigned char year;                        //年
  •         unsigned char mon;                        //月
  •         unsigned char day;                        //日
  •         unsigned char hour;                        //时
  •         unsigned char min;                        //分
  •         unsigned char sec;                        //秒
  •         unsigned char week;                        //星期
  • };
  • /*DS1302读出函数,根据时序图编写,返回值为读出的数据*/
  • unsigned char DS1302ByteRead()
  • {
  •         unsigned char dat = 0;
  •         unsigned char mask;
  •         for (mask=0x01; mask!=0; mask<<=1)
  •         {
  •                 if (DS1302_IO != 0)
  •                         dat |= mask;
  •                 DS1302_SK = 1;        //先准备好数据,然后拉高SK
  •                 _nop_();
  •                 DS1302_SK = 0;        //拉低SK
  •                 _nop_();
  •         }
  •         return dat;
  • }
  • /*DS1302写入函数,根据时序图编写,dat-写入的数据*/
  • void DS1302ByteWrite(unsigned char dat)
  • {
  •         unsigned char mask;
  •         for (mask=0x01; mask!=0; mask<<=1)
  •         {
  •                 if ((mask&dat) != 0) //将输入数据的位从最低位依次输入
  •                         DS1302_IO = 1;
  •                 else
  •                         DS1302_IO = 0;
  •                 DS1302_SK = 1;                 //先准备好数据,拉高SK,数据采样
  •                 _nop_();
  •                 DS1302_SK = 0;                 //拉低SK,数据输出
  •                 _nop_();
  •         }
  •         DS1302_IO = 1;                            //释放IO引脚
  • }
  • /*DS1302单字节读出函数,addr-写入要读字节的寄存器地址,返回值为读出的数据*/
  • unsigned char DS1302SingleRead(unsigned char addr)
  • {
  •         unsigned char dat;
  •         DS1302_CE = 1;
  •         _nop_();
  •         DS1302ByteWrite(addr);
  •         dat = DS1302ByteRead();
  •         DS1302_CE = 0;
  •         _nop_();
  •         return dat;
  • }
  • /*DS1302单字节写入函数,addr-写入字节的寄存器地址,dat-写入数据*/
  • void DS1302SingleWrite(unsigned addr, unsigned dat)
  • {
  •         DS1302_CE = 1;
  •         _nop_();
  •         DS1302ByteWrite(addr);
  •         DS1302ByteWrite(dat);
  •         DS1302_CE = 0;
  •         _nop_();
  • }
  • /*DS1302burst写入模式,一次写入8个字节,dat-写入数据的指针*/
  • void DS1302BurstWrite(unsigned char *dat)
  • {
  •         unsigned char i;
  •         DS1302_CE = 1;
  •         _nop_();
  •         DS1302ByteWrite(0xbe);
  •         for (i = 0; i < 8; i++)
  •         {
  •                 DS1302ByteWrite(*dat++);
  •         }
  •         DS1302_CE = 0;
  •         _nop_();
  • }
  • /*DS1302Burst读出模式,一次读出8个字节,dat-存储读出数据的指针*/
  • void DS1302BurstRead(unsigned char * dat)
  • {
  •         unsigned char i;
  •         DS1302_CE = 1;
  •         _nop_();
  •         DS1302ByteWrite(0xbf);
  •         for (i = 0; i < 8; i++)
  •         {
  •                 *dat++ = DS1302ByteRead();
  •         }
  •         DS1302_CE = 0;
  •         _nop_();
  • }
  • /*获取实时时间,time-存储时间的结构体*/
  • void GetRealTime(struct sTime * time)
  • {
  •         unsigned char buf[8];
  •         DS1302BurstRead(buf);
  •         time->year = buf[6] + 0x2000;
  •         time->week = buf[5];
  •         time->mon = buf[4];
  •         time->day = buf[3];
  •         time->hour = buf[2];
  •         time->min = buf[1];
  •         time->sec = buf[0];
  • }
  • /*设置实时时间,dat-要写入的数据的结构体*/
  • void SetRealTime(struct sTime * dat)
  • {
  •         unsigned char buf[8];
  •         buf[7] = 0x00;
  •         buf[6] = dat->year;
  •         buf[5] = dat->week;
  •         buf[4] = dat->mon;
  •         buf[3] = dat->day;
  •         buf[2] = dat->hour;
  •         buf[1] = dat->min;
  •         buf[0] = dat->sec;
  •         DS1302BurstWrite(buf);
  • }
  • /*初始化DS1302函数*/
  • void InitDS1302()
  • {
  •         struct sTime code InitTime[] = {0x2019, 0x10, 0x11, 0x09, 0x59, 0x50, 0x05};
  •         DS1302_CE = 0;
  •         _nop_();                                       //延时一个机器周期
  •         DS1302_SK = 0;
  •         _nop_();
  •         DS1302SingleWrite(0x8e, 0x00); //撤销写保护,0x8e-写保护位的地址,0x00-撤销写保护
  •         SetRealTime(InitTime);                   //设置初始时间
  •         DS1302SingleWrite(0x8e, 0x80); //添加写保护
  • }


[color=rgb(51, 102, 153) !important]复制代码



四:设置时间函数




  • #include <reg52.h>
  • struct sTime {                                        //定义时间结构体
  •         unsigned char year;                        //年
  •         unsigned char mon;                    //月
  •         unsigned char day;                        //日
  •         unsigned char hour;                        //时
  •         unsigned char min;                        //分
  •         unsigned char sec;                        //秒
  •         unsigned char week;                        //星期
  • };
  • struct sTime bufTime;                        //时间缓冲区
  • unsigned char setIndex = 0;                //设置标志位
  • /*函数声明*/
  • extern void RefreshTime();
  • extern void LcdSetCursor(unsigned char x, unsigned char y);
  • extern void SetRealTime(struct sTime * dat);
  • extern void LcdCloseCursor();
  • extern void LcdOpenCursor();
  • /*刷新当前设置位的光标指示*/
  • void RefreshSetShow()
  • {
  •         switch(setIndex)
  •         {
  •                 case 1:LcdSetCursor(2, 0);break;
  •                 case 2:LcdSetCursor(3, 0);break;
  •                 case 3:LcdSetCursor(5, 0);break;
  •                 case 4:LcdSetCursor(6, 0);break;
  •                 case 5:LcdSetCursor(8, 0);break;
  •                 case 6:LcdSetCursor(9, 0);break;
  •                 case 7:LcdSetCursor(15, 0);break;
  •                 case 8:LcdSetCursor(4, 1);break;
  •                 case 9:LcdSetCursor(5, 1);break;
  •                 case 10:LcdSetCursor(7, 1);break;
  •                 case 11:LcdSetCursor(8, 1);break;
  •                 case 12:LcdSetCursor(10, 1);break;
  •                 case 13:LcdSetCursor(11, 1);break;
  •                 default:break;
  •         }
  • }
  • /***********************************************************************/
  • //递增或递减分,秒的BCD码
  • /*递增一个BCD码的高位*/
  • unsigned char IncTimeBcdHigh(unsigned char bcd)
  • {
  •         if ((bcd&0xf0) < 0x50)
  •                 bcd += 0x10;
  •         else
  •                 bcd &= 0x0f;
  •         return bcd;
  • }
  • /*递减一个BCD码的高位*/
  • unsigned char DecTimeBcdHigh(unsigned char bcd)
  • {
  •         if ((bcd&0xf0) > 0x00)
  •                 bcd -= 0x10;
  •         else
  •                 bcd |= 0x50;
  •         return bcd;
  • }
  • //递增或递减时,分,秒的BCD码
  • /********************************************************************/
  • /*递增一个BCD码的高位*/
  • unsigned char IncBcdHigh(unsigned char bcd)
  • {
  •         if ((bcd&0xf0) < 0x90)
  •                 bcd += 0x10;
  •         else
  •                 bcd &= 0x0f;
  •         return bcd;
  • }
  • /*递增一个BCD码的低位*/
  • unsigned char IncBcdLow(unsigned char bcd)
  • {
  •         if ((bcd&0x0f) < 0x09)
  •                 bcd += 0x01;
  •         else
  •                 bcd &= 0xf0;
  •         return bcd;
  • }
  • /*递减一个BCD码的高位*/
  • unsigned char DecBcdHigh(unsigned char bcd)
  • {
  •         if ((bcd&0xf0) > 0x00)
  •                 bcd -= 0x10;
  •         else
  •                 bcd |= 0x90;
  •         return bcd;
  • }
  • /*递减一个BCD码的低位*/
  • unsigned char DecBcdLow(unsigned char bcd)
  • {
  •         if ((bcd&0x0f) > 0x00)
  •                 bcd -= 0x01;
  •         else
  •                 bcd |= 0x09;
  •         return bcd;
  • }
  • /*递增周的BCD码*/
  • unsigned char IncWeekBcd(unsigned char bcd)
  • {
  •         if ((bcd&0x0f) < 0x07)
  •                 bcd += 0x01;
  •         else
  •                 bcd = 0x00;
  •         return bcd;
  • }
  • /*递减周的BCD码*/
  • unsigned char DecWeekBcd(unsigned char bcd)
  • {
  •         if ((bcd&0x0f) > 0x00)
  •                 bcd -= 0x01;
  •         else
  •                 bcd = 0x07;
  •         return bcd;
  • }
  • /*递增时间当前设置位的值*/
  • void IncSetTime()
  • {
  •         switch(setIndex)
  •         {
  •                 case 1:bufTime.year = IncBcdHigh(bufTime.year);break;
  •                 case 2:bufTime.year = IncBcdLow(bufTime.year);break;
  •                 case 3:bufTime.mon = IncBcdHigh(bufTime.mon);break;
  •                 case 4:bufTime.mon = IncBcdLow(bufTime.mon);break;
  •                 case 5:bufTime.day = IncBcdHigh(bufTime.day);break;
  •                 case 6:bufTime.day = IncBcdLow(bufTime.day);break;
  •                 case 7:bufTime.week = IncWeekBcd(bufTime.week);break;
  •                 case 8:bufTime.hour = IncBcdHigh(bufTime.hour);break;
  •                 case 9:bufTime.hour = IncBcdLow(bufTime.hour);break;
  •                 case 10:bufTime.min = IncTimeBcdHigh(bufTime.min);break;
  •                 case 11:bufTime.min = IncBcdLow(bufTime.min);break;
  •                 case 12:bufTime.sec = IncTimeBcdHigh(bufTime.sec);break;
  •                 case 13:bufTime.sec = IncBcdLow(bufTime.sec);break;
  •                 default:break;
  •         }
  •         RefreshTime();
  •         RefreshSetShow();
  • }
  • /*递减时间当前设置位的值*/
  • void DecSetTime()
  • {
  •         switch(setIndex)
  •         {
  •                 case 1:bufTime.year = DecBcdHigh(bufTime.year);break;
  •                 case 2:bufTime.year = DecBcdLow(bufTime.year);break;
  •                 case 3:bufTime.mon = DecBcdHigh(bufTime.mon);break;
  •                 case 4:bufTime.mon = DecBcdLow(bufTime.mon);break;
  •                 case 5:bufTime.day = DecBcdHigh(bufTime.day);break;
  •                 case 6:bufTime.day = DecBcdLow(bufTime.day);break;
  •                 case 7:bufTime.week = DecWeekBcd(bufTime.week);break;
  •                 case 8:bufTime.hour = DecBcdHigh(bufTime.hour);break;
  •                 case 9:bufTime.hour = DecBcdLow(bufTime.hour);break;
  •                 case 10:bufTime.min = DecTimeBcdHigh(bufTime.min);break;
  •                 case 11:bufTime.min = DecBcdLow(bufTime.min);break;
  •                 case 12:bufTime.sec = DecTimeBcdHigh(bufTime.sec);break;
  •                 case 13:bufTime.sec = DecBcdLow(bufTime.sec);break;
  •                 default:break;
  •         }
  •         RefreshTime();
  •         RefreshSetShow();
  • }
  • /*光标左移函数*/
  • void LeftShift()
  • {
  •         if (setIndex != 0)
  •         {
  •                 if (setIndex > 1)
  •                 {
  •                         setIndex--;
  •                 }
  •                 else
  •                 {
  •                         setIndex = 13;
  •                 }
  •                 RefreshSetShow();
  •         }
  • }
  • /*光标右移函数*/
  • void RightShift()
  • {
  •         if (setIndex != 0)
  •         {
  •                 if (setIndex < 13)
  •                 {
  •                         setIndex++;
  •                 }
  •                 else
  •                 {
  •                         setIndex = 1;
  •                 }
  •                 RefreshSetShow();
  •         }
  • }
  • /*退出时间设置函数,save-是否保存标志*/
  • void ExitSetTime(bit save)
  • {
  •         setIndex = 0;
  •         if (save)
  •         {
  •                 SetRealTime(&bufTime);
  •         }
  •         LcdCloseCursor();
  • }
  • /*进入时间设置函数*/
  • void EnterSetTime()
  • {
  •         setIndex = 2;                        //先把设置标志位设为2,再向左移
  •         LeftShift();
  •         LcdOpenCursor();
  • }
  • /*按键执行函数,keycode-所传递的哪一个按键被按下*/
  • void KeyAction(unsigned char keycode)
  • {
  •         if (keycode >= '0' && keycode <= '9')
  •         {
  •         //数字按键不执行任何动作
  •         }
  •         else if (keycode == 0x26)          //数字键加
  •         {
  •                 IncSetTime();
  •         }
  •         else if (keycode == 0x28)          //数字键减
  •         {
  •                 DecSetTime();
  •         }
  •         else if (keycode == 0x25)          //光标向左移动
  •         {
  •                 LeftShift();
  •         }
  •         else if (keycode == 0x27)          //光标向右移动
  •         {
  •                 RightShift();
  •         }
  •         else if (keycode == 0x0d)          //进入/退出时间设置
  •         {
  •                 if (setIndex == 0)
  •                 {
  •                         EnterSetTime();
  •                 }
  •                 else
  •                 {
  •                         ExitSetTime(1);          //保存数据并退出
  •                 }
  •         }
  •         else if (keycode == 0x1b)          //取消键
  •         {
  •                 ExitSetTime(0);                  //不保存数据
  •         }
  • }


[color=rgb(51, 102, 153) !important]复制代码



五:主程序




  • #include <reg52.h>
  • //控制小灯的位
  • sbit led1 = P2^0;
  • sbit led2 = P2^1;
  • sbit led3 = P2^2;
  • //小灯开启时间表
  • ledstarthour[3] = {0x10, 0x10, 0x10};
  • ledstartmin[3] = {0x00, 0x02, 0x05};
  • //小灯关闭时间表
  • ledclosehour[3] = {0x10, 0x10, 0x10};
  • ledclosemin[3] = {0x01, 0x04, 0x06};
  • struct sTime {                                        //定义时间结构体
  •         unsigned char year;                        //年
  •         unsigned char mon;                        //月
  •         unsigned char day;                        //日
  •         unsigned char hour;                        //时
  •         unsigned char min;                        //分
  •         unsigned char sec;                        //秒
  •         unsigned char week;                        //星期
  • };
  • bit flag200ms = 0;                                                //定时标志
  • extern struct sTime bufTime;                        //时间缓冲区
  • extern unsigned char setIndex ;                    //设置标志位
  • unsigned char T0RH = 0;                                        //定时器的高8位
  • unsigned char T0RL = 0;                                        //定时器的低8位
  • /*函数声明*/
  • extern void KeyScan();
  • void configTimer0(unsigned char ms);
  • extern void InitLcd1602();
  • extern void InitDS1302();
  • extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
  • extern void KeyDriver();
  • extern void GetRealTime(struct sTime * time);
  • void RefreshTime();
  • void LedStartMonitor();
  • void LedCloseMonitor();
  • void main()
  • {
  •         unsigned char psec = 0xaa;        //秒备份
  •         EA = 1;                                                //开总中断
  •         configTimer0(1);                        //为定时器0配置时间
  •         InitLcd1602();                                //初始化液晶显示屏
  •         InitDS1302();                                //初始化时钟
  •         //显示液晶上固定的位
  •         LcdShowStr(0, 0, "20  -  -   week ");
  •         LcdShowStr(4, 1, "  :  :  ");
  •         while (1)
  •         {
  •                 KeyDriver();                                //按键驱动
  •                 if (flag200ms && (setIndex == 0))
  •                 {
  •                         flag200ms = 0;
  •                         GetRealTime(&bufTime);                 //获取实时时间
  •                         LedStartMonitor();
  •                         LedCloseMonitor();
  •                         if (psec != bufTime.sec)        //如果秒发生变化,就刷新时间
  •                         {
  •                                 RefreshTime();
  •                                 psec = bufTime.sec;
  •                         }
  •                 }
  •         }
  • }
  • /*监控时间开启小灯函数,当到达指定时间,小灯亮*/
  • void LedStartMonitor()
  • {
  •         static unsigned char i = 0;
  •         if ((bufTime.hour == ledstarthour)&&(bufTime.min == ledstartmin))
  •         {
  •                 led1 = 0;
  •                 led2 = 0;
  •                 led3 = 0;
  •                 i++;
  •                 if (i >= 3)
  •                         i = 0;
  •         }
  • }
  • /*监控时间关闭小灯函数,当到达指定时间,小灯灭*/
  • void LedCloseMonitor()
  • {
  •         static unsigned char i = 0;
  •         if ((bufTime.hour == ledclosehour)&&(bufTime.min == ledclosemin))
  •         {
  •                 led1 = 1;
  •                 led2 = 1;
  •                 led3 = 1;
  •                 i++;
  •                 if (i >= 3)
  •                         i = 0;
  •         }
  • }
  • /*将BCD码转换为字符串*/
  • void ShowBcdByte(unsigned char x, unsigned char y, unsigned char dat)
  • {
  •         unsigned char buf[3];
  •         if (x == 15)                                 //对“周”的特殊照顾
  •         {
  •                 buf[0] = (dat&0x0f)+'0';
  •                 buf[1] = '\0';
  •         }
  •         else
  •         {
  •                 buf[0] = (dat>>4)+'0';
  •                 buf[1] = (dat&0x0f)+'0';
  •                 buf[2] = '\0';
  •         }
  •         LcdShowStr(x, y, buf);
  • }
  • /*刷新时间函数*/
  • void RefreshTime()
  • {
  •         ShowBcdByte(2, 0, bufTime.year);
  •         ShowBcdByte(5, 0, bufTime.mon);
  •         ShowBcdByte(8, 0, bufTime.day);
  •         ShowBcdByte(15, 0, bufTime.week);
  •         ShowBcdByte(4, 1, bufTime.hour);
  •         ShowBcdByte(7, 1, bufTime.min);
  •         ShowBcdByte(10, 1, bufTime.sec);
  • }
  • /*配置定时器0*/
  • void configTimer0(unsigned char ms)
  • {
  •         unsigned long temp;
  •         temp = 11059200 / 12;
  •         temp = (temp*ms)/1000;
  •         temp = 65536 - temp;
  •         T0RH = (unsigned char)(temp >> 8);
  •         T0RL = (unsigned char)temp;
  •         TMOD &= 0xf0;
  •         TMOD |= 0x01;
  •         TH0 = T0RH;
  •         TL0 = T0RL;
  •         TR0 = 1;
  •         ET0 = 1;                //打开定时器0中断
  • }
  • /*中断函数*/
  • void InterruptTimer0()                        interrupt 1
  • {
  •         static unsigned char tmr200ms = 0;
  •         TH0 = T0RH;
  •         TL0 = T0RL;
  •         KeyScan();
  •         tmr200ms++;
  •         if (tmr200ms >= 200)
  •         {
  •                 tmr200ms = 0;
  •                 flag200ms = 1;
  •         }
  • }



复制代码

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1887

主题

6517

帖子

8

粉丝