附件和图发:
51单片机源程序:
- #include<reg52.h>
- struct sTime{ //日期时间结构体申明
- unsigned int year;
- unsigned char mon;
- unsigned char day;
- unsigned char hour;
- unsigned char min;
- unsigned char sec;
- unsigned char week;
- };
- bit flag200ms = 1; //200ms 定时标志
- struct sTime bufTime; //日期时间缓冲区
- unsigned char setIndex = 0; //时间设置索引 0 0 就表示正常运行,
- unsigned char T0RH, T0RL;
- void RefreshTimeShow();
- void ConfigTimer0(unsigned int ms);
- extern void KeyScan();
- extern void KeyDriver();
- extern void InitLcd1602();
- extern void LcdOpenCursor();
- extern void LcdCloseCursor();
- extern void LcdSetCursor(unsigned char x, unsigned char y);
- extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
- extern void InitDS1302();
- extern void SetRealTime(struct sTime *time);
- extern void GetRealTime(struct sTime *time);
- void main()
- {
- unsigned char psec = 0xaa; //秒备份,初值 AA 确保首次读取时间后刷新显示
- EA = 1;
- ConfigTimer0(1);
- InitLcd1602();
- InitDS1302();
- LcdShowStr(0, 0, "20 - - Week "); //初始化屏幕上固定不变的内容
- LcdShowStr(4, 1, " : : ");
- while(1)
- {
- KeyDriver(); //调用按键驱动
- if(flag200ms && (setIndex == 0))
- {
- flag200ms = 0; //每隔200ms且未处于设置状态时,
- GetRealTime(&bufTime); //获取当前时间
- if(psec != bufTime.sec) //检测到时间有变化时刷新显示
- {
- RefreshTimeShow();
- psec = bufTime.sec; //用当前值更新上次秒数
- }
- }
- }
- }
- /* 将一个BCD码字节显示到屏幕上,(x,y)-屏幕起始坐标,bcd-待显示BCD码 */
- void ShowBCDByte(unsigned char x, unsigned char y, unsigned char bcd)
- {
- unsigned char str[4];
- str[0] = (bcd >> 4) + '0';
- str[1] = (bcd & 0x0f) + '0';
- str[2] = '\0';
- LcdShowStr(x, y, str);
- }
- void ShowBCDWeek(unsigned char x, unsigned char y, unsigned char bcd)
- {
- unsigned char str[3];
- str[0] = (bcd & 0x0f) + '0';
- str[1] = '\0';
- LcdShowStr(x, y, str);
- }
- /* 刷新日期时间的显示 */
- void RefreshTimeShow()
- {
- ShowBCDByte(2, 0, bufTime.year);
- ShowBCDByte(5, 0, bufTime.mon);
- ShowBCDByte(8, 0, bufTime.day);
- ShowBCDByte(4, 1, bufTime.hour);
- ShowBCDByte(7, 1, bufTime.min);
- ShowBCDByte(10, 1, bufTime.sec);
- ShowBCDWeek(15, 0, bufTime.week);
- }
- /* 刷新当前设置位的光标指示 */
- void RefreshSetCursorShow()
- {
- 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(4, 1); break;
- case 8: LcdSetCursor(5, 1); break;
- case 9: LcdSetCursor(7, 1); break;
- case 10: LcdSetCursor(8, 1); break;
- case 11: LcdSetCursor(15, 0); break;
- default: break;
- }
- }
- unsigned char DecrBCDHight(unsigned char bcd)
- {
- if((bcd & 0xf0) > 0x00)
- {
- bcd -= 0x10;
- }
- else
- {
- if(setIndex == 1)
- bcd |= 0x90;
- else if(setIndex == 3)
- bcd |= 0x10;
- else if(setIndex == 5)
- bcd |= 0x30;
- else if(setIndex == 7)
- bcd |= 0x20;
- else if((setIndex == 9))
- bcd |= 0x60;
- }
-
- return bcd;
- }
- unsigned char DecrBCDLow(unsigned char bcd)
- {
- if((bcd & 0x0f) > 0x00)
- {
- bcd -= 0x01;
- }
- else if(setIndex == 11)
- {
- bcd |= 0x07;
- }
- else
- {
- bcd |= 0x09;
- }
-
- return bcd;
- }
- unsigned char IncrBCDHight(unsigned char bcd)
- {
- if((setIndex == 1)&&((bcd & 0xf0)< 0x90))
- {
- bcd += 0x10;
- }
- else if((setIndex == 3)&&(bcd < 0x10))
- {
- bcd +=0x10;
- }
- else if((setIndex == 5)&&(bcd < 0x30))
- {
- bcd += 0x10;
- }
- else if((setIndex == 7)&&(bcd < 0x20))
- {
- bcd += 0x10;
- }
- else if(setIndex == 9)
- {
- bcd += 0x10;
- }
- else if(setIndex == 11)
- {
- if(bcd < 0x07)
- {
- bcd++;
- }
- else
- {
- bcd = 0x01;
- }
- }
- else
- {
- bcd &= 0x0f;
- }
-
- return bcd;
- }
- unsigned char IncrBCDLow(unsigned char bcd)
- {
- if(setIndex != 11)
- {
- if ((bcd&0x0F) < 0x09)
- bcd += 0x01;
- else
- bcd &= 0xF0;
- }
- else
- {
- if ((bcd&0x0F) < 0x07)
- bcd += 0x01;
- else
- bcd &= 0x01;
- }
-
- return bcd;
- }
- /* 递增当前设置位的值 */
- void IncrSetTime()
- {
- switch(setIndex)
- {
- case 1: bufTime.year = IncrBCDHight(bufTime.year); break;
- case 2: bufTime.year = IncrBCDLow(bufTime.year); break;
- case 3: bufTime.mon = IncrBCDHight(bufTime.mon); break;
- case 4: bufTime.mon = IncrBCDLow(bufTime.mon); break;
- case 5: bufTime.day = IncrBCDHight(bufTime.day); break;
- case 6: bufTime.day = IncrBCDLow(bufTime.day); break;
- case 7: bufTime.hour = IncrBCDHight(bufTime.hour); break;
- case 8: bufTime.hour = IncrBCDLow(bufTime.hour); break;
- case 9: bufTime.min = IncrBCDHight(bufTime.min); break;
- case 10: bufTime.min = IncrBCDLow(bufTime.min); break;
- case 11: bufTime.week = IncrBCDLow(bufTime.week); break;
- default: break;
- }
- RefreshTimeShow();
- RefreshSetCursorShow();
- }
- /* 递减当前设置位的值 */
- void DecrSetTime()
- {
- switch(setIndex)
- {
- case 1: bufTime.year = DecrBCDHight(bufTime.year); break;
- case 2: bufTime.year = DecrBCDLow(bufTime.year); break;
- case 3: bufTime.mon = DecrBCDHight(bufTime.mon); break;
- case 4: bufTime.mon = DecrBCDLow(bufTime.mon); break;
- case 5: bufTime.day = DecrBCDHight(bufTime.day); break;
- case 6: bufTime.day = DecrBCDLow(bufTime.day); break;
- case 7: bufTime.hour = DecrBCDHight(bufTime.hour); break;
- case 8: bufTime.hour = DecrBCDLow(bufTime.hour); break;
- case 9: bufTime.min = DecrBCDHight(bufTime.min); break;
- case 10: bufTime.min = DecrBCDLow(bufTime.min); break;
- case 11: bufTime.week = DecrBCDLow(bufTime.week); break;
- default: break;
- }
- RefreshTimeShow();
- RefreshSetCursorShow();
- }
- /* 左移设置位 */
- void LeftShiftTimeSet()
- {
- if(setIndex != 0)
- {
- if(setIndex > 1)
- setIndex--;
- else
- setIndex = 11;
- RefreshSetCursorShow();
- }
- }
- /* 右移设置位 */
- void RightShifTimeSet()
- {
- if(setIndex != 0)
- {
- if(setIndex < 11)
- setIndex++;
- else
- setIndex = 1;
- RefreshSetCursorShow();
- }
- }
- /* 进入设置状态 */
- void EnterTimeSet()
- {
- setIndex = 2; //把设置索引设置为2,即可进入设置状态
- LeftShiftTimeSet(); //再利用现成的左移操作移到位置1并完成显示刷新
- LcdOpenCursor(); //打开光标闪烁效果
- }
- /* 退出设置状态,save-是否保存当前设置的时间值 */
- void ExitTimeSet(bit save) //save = 1 保存,save = 0 不保存
- {
- setIndex = 0; //把设置索引设置为0,即可退出设置状态
- if(save) //需保存时即把当前设置时间写入DS1302
- SetRealTime(&bufTime);
- LcdCloseCursor(); //关闭光标显示
- }
- /* 按键动作函数,根据键码执行相应的操作,keycode-按键键码 */
- void KeyAction(unsigned char keycode)
- {
- if((keycode >= '0')&&(keycode <= '9'))//不响应字符键
- {}
- else if((keycode == 0x26)) //向上键,递增当前设置位的值
- {
- IncrSetTime();
- }
- else if(keycode == 0x28) //向下键,递减当前设置位的值
- {
- DecrSetTime();
- }
- else if(keycode == 0x25) //向左键,向左切换设置位
- {
- LeftShiftTimeSet();
- }
- else if(keycode == 0x27) //向右键,向右切换设置位
- {
- RightShifTimeSet();
- }
- else if(keycode == 0x0d) //回车键,进入设置模式/启用当前设置值
- {
- if(setIndex == 0) //不处于设置状态时,进入设置状态
- {
- EnterTimeSet();
- }
- else //已处于设置状态时,保存时间并退出设置状态
- {
- ExitTimeSet(1);
- }
- }
- else if(keycode == 0x1b) //Esc键,取消当前设置
- {
- ExitTimeSet(0);
- }
- }
- void ConfigTimer0(unsigned int ms)
- {
- unsigned long tmp;
- tmp = 11059200 / 12;
- tmp = tmp * ms / 1000;
- tmp = 65536 - tmp;
- tmp = tmp + 28;
- T0RH = (unsigned char)(tmp >> 8);
- T0RL = (unsigned char)tmp;
- TMOD = (TMOD & 0xf0)|0x01;
- TH0 = T0RH;
- TL0 = T0RL;
- ET0 = 1;
- TR0 = 1;
- }
- void IntTimer0() interrupt 1
- {
- static unsigned char tmr200ms = 0;
- TH0 = T0RH;
- TL0 = T0RL;
- KeyScan();
- tmr200ms++;
- if(tmr200ms >= 200)
- {
- tmr200ms = 0;
- flag200ms = 1;
- }
- }
复制代码
下载:
时钟.rar
(4.99 KB, 下载次数: 37)
|