时钟控制器(电子时钟)
基于电子钟的控制器,其实相当于是闹钟的功能。学习来源是根据宋雪松老师的《手把手教你学单片机》。通过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); //清显示
[*]}
复制代码
二:矩阵按键模块
[*]#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 = { //矩阵按键编号到标准键盘键码的印射表
[*] {'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 = {
[*] {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 = {
[*] {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 != backup)
[*] {
[*] if (backup != 0)
[*] {
[*] KeyAction(KeyCodeMap); //通过按键位置来执行相应的程序
[*] }
[*] backup = keysta;
[*] }
[*] }
[*] }
[*]}
[*]
[*]/*按键扫描函数,通过定时器0中断来完成1ms扫描一次*/
[*]void KeyScan()
[*]{
[*] static unsigned char keyout = 0;
[*] static unsigned char keybuff = { //用来消抖
[*] {0xff, 0xff, 0xff, 0xff},{0xff, 0xff, 0xff, 0xff},
[*] {0xff, 0xff, 0xff, 0xff},{0xff, 0xff, 0xff, 0xff}
[*] };
[*] unsigned char i;
[*]
[*] //将一行的4个按键值移入缓冲区
[*] keybuff = (keybuff << 1)|keyin1;
[*] keybuff = (keybuff << 1)|keyin2;
[*] keybuff = (keybuff << 1)|keyin3;
[*] keybuff = (keybuff << 1)|keyin4;
[*] //消抖后更新按键状态
[*] for (i = 0; i < 4; i++)
[*] {
[*] if ((keybuff&0x0f) == 0x0f)
[*] {//连续4次扫描值为1,即4*4ms内都是弹起状态时,可以认为按键已稳定弹起
[*] keysta = 1;
[*] }
[*] else if ((keybuff&0x0f) == 0x00)
[*] {//连续4次扫描值为0,即4*4ms内都是按下状态时,可以认为按键已稳定按下
[*] keysta = 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;
[*] }
[*]}
复制代码
三: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;
[*]
[*] DS1302BurstRead(buf);
[*] time->year = buf + 0x2000;
[*] time->week = buf;
[*] time->mon = buf;
[*] time->day = buf;
[*] time->hour = buf;
[*] time->min = buf;
[*] time->sec = buf;
[*]}
[*]
[*]/*设置实时时间,dat-要写入的数据的结构体*/
[*]void SetRealTime(struct sTime * dat)
[*]{
[*] unsigned char buf;
[*]
[*] buf = 0x00;
[*] buf = dat->year;
[*] buf = dat->week;
[*] buf = dat->mon;
[*] buf = dat->day;
[*] buf = dat->hour;
[*] buf = dat->min;
[*] buf = 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); //添加写保护
[*]}
复制代码
四:设置时间函数
[*]#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); //不保存数据
[*] }
[*]}
复制代码
五:主程序
[*]#include <reg52.h>
[*]//控制小灯的位
[*]sbit led1 = P2^0;
[*]sbit led2 = P2^1;
[*]sbit led3 = P2^2;
[*]
[*]//小灯开启时间表
[*]ledstarthour = {0x10, 0x10, 0x10};
[*]ledstartmin = {0x00, 0x02, 0x05};
[*]//小灯关闭时间表
[*]ledclosehour = {0x10, 0x10, 0x10};
[*]ledclosemin = {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;
[*] if (x == 15) //对“周”的特殊照顾
[*] {
[*] buf = (dat&0x0f)+'0';
[*] buf = '\0';
[*] }
[*] else
[*] {
[*] buf = (dat>>4)+'0';
[*] buf = (dat&0x0f)+'0';
[*] buf = '\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;
[*] }
[*]}
复制代码
页:
[1]