[电子电路]基于单片机的数字电子时钟的设计与制作内容摘要:

1Vdd2Vo3A15K16LCD1LCD1602VCCVCC8R310KR1Q11122Speaker1KR6VCC+12BT1Battery1 2PowerHeader工作模式模式辅助1 2 36 5 4PowerSWVCC+5VCC10KR5VCCKEY1KEY2KEY1KEY2RSR/WENRSR/WENRestSWRestSWRestSW 图 461 13 系统 的软件设计 系统 软件设计 系统软件包含四个部分:主程序,定时器扫描程序, 按键扫描程序, 按键处理程序 ;通过这四个部分可以实现 数字电子钟 的功能设计。 主程序设计 程序 设计主要是通过 单片机内部 TIMER0 和 TIMER1 产生系统时钟信号 , 经过单片机的运算分别得到 时间的 年 月 日 时 分 秒 和秒表的 时 分 秒 毫秒, 单片机在主程序中循环扫描按键端口 ,根据返回的键值分别将这些数据 传给 LCD1602 对应 显示出来。 实现功能 程序实现的功能是: 正常显示 年 月 日 和 时 分 秒 以及闹钟的 时 分。 若单片机检测到 key1 第一次 按下并释放则 LCD 切换到显示秒表模式 00:00:00:00, 第二次按下 key2 并释放则返回到时钟显示模式。 在时钟正常显示模式下若前 5 按下 key2 按键并释放则一次选中闹钟的 时 分和时钟的 分 时 年 月 日 ,选中位会出现光标闪烁并且时钟不自动走动 , 第 6次按下 key2 并释放之后则正常显示时钟 , 6 次为一个循环。 在光标闪烁的时候若按下 key1并且释放则可以对相应位进行校正。 若在 秒表 显示模式下 第一次 按下 key2 并释放则启动秒表计时 ,第二次按下 key2 释放后则暂停秒表 ,第三次按下 key2 释放后则秒表清零 , 三 次为一个循环。 工作流程图 通过以上分析可得图 52 系统工作流程图: 是是 否 model_flag = 0 amp。 amp。 time_change_flag = 0 amp。 amp。 shift_flag =0否结 束Shift_flag清 零写 入 显 示 时 间 代 码到 液 晶是 否 model_flag = 1 amp。 amp。 time_change_flag = 0 amp。 amp。 shift_flag =1Shift_flag置 1写 入 显 秒 表 代 码 到液 晶否 图 521 14 实现功能 当系统检测到有按键按下时返回相应非零的键值,否则返回零。 按键扫描流程图 (如图 531) t 1 清 零 , 读 取 当 前按 键 端 口 值 并 保存 ,是是 否 有 键 按 下否t 1 是 否 d e n 与 k e y _ s h a k e _ t i m e并 且 是 否 有 键 按 下否是否按 键 是 否 释 放处 理 保 存 的 键 值是返 回 零返 回 处 理 后 的 键 值 图 531 15 按键扫描部分代码 unsigned char key_scan(void) { static unsigned char value。 //键值 static unsigned char do_key。 //执行相应命令标识 static unsigned char key_scan_step。 //键盘扫描步骤 if(key_scan_step==0) { key_value = 0。 if(do_key==0) { if(KEY amp。 0x03 != 0x03) { t1=0。 do_key=1。 } } if((t1=key_shake_time)amp。 amp。 ((KEY amp。 0x03) != 0x03)) { value = KEY amp。 0x03。 do_key = 0。 key_scan_step = 1。 } } if((key_scan_step==1)amp。 amp。 ((KEY amp。 0x03) == 0x03)) { key_scan_step = 0。 switch(value) { case 0x02 : value = 1。 break。 case 0x01 : value = 2。 break。 16 case 0x03 : value = 0。 break。 default : value = 0。 break。 } return(value)。 } else return(0)。 } 时间更新函数处理程序 实现功能 通过对 t0 值的判断来得到 秒 分 时 日 月 年 的计算 工作流程图 (如图 521) 是是t0是 否 等 于 20否否否分 是 否 大 于 59结 束时 间 的 秒 加 1将 秒 写 入 液 晶秒 是 否 大 于 59秒 清 零 , 分 加 1将 分 写 入 液 晶分 清 零 , 时 加 1将 时 写 入 液 晶是时 是 否 大 于 23否时 清 零 , 将 时 写 入液 晶是 图 521 17 时间更新函数部分代码 void update_time(void) { if(t0=20) { t0=0。 ++。 if(59) { =0。 ++。 if(59) { =0。 ++。 if(23) { =0。 ++。 switch() { case 1: case 3: case 5: case 7: case 8: case 10: case 12:if(31) { =1。 ++。 18 if(12) { =1。 ++。 if( 2060) { = 2020。 } } }break。 case 4: case 6: case 9: case 11:if(30) { =1。 ++。 if(12) { =1。 ++。 if( 2060) { = 2020。 } } }break。 case2:if((()amp。 amp。 (!=0)||(ear/400==0))amp。 amp。 (29)) { 19 =1。 ++。 if(12) { =1。 ++。 if( MAX_YEAR) { = MIN_YEAR。 } } } else if(28) { =1。 ++。 if(12) { =1。 ++。 if( 2060) { = 2020。 } } }break。 default:break。 } if(model_flag == 0) { write_lcd(0x8C,WCMD)。 20 write_lcd(%10+39。 039。 ,WDATA)。 write_lcd(0x8B,WCMD)。 write_lcd(+39。 039。 ,WDATA)。 write_lcd(0x89,WCMD)。 write_lcd(%10+39。 039。 ,WDATA)。 write_lcd(0x88,WCMD)。 write_lcd(+39。 039。 ,WDATA)。 write_lcd(0x83,WCMD)。 write_lcd(()+39。 039。 ,WDATA)。 write_lcd(0x84,WCMD)。 write_lcd((%1000/100)+39。 039。 ,WDATA)。 write_lcd(0x85,WCMD)。 write_lcd((%1000%100/10)+39。 039。 ,WDATA)。 write_lcd(0x86,WCMD)。 write_lcd(%10+39。 039。 ,WDATA)。 } } if(model_flag == 0) { write_lcd(0xC1,WCMD)。 write_lcd(%10+39。 039。 ,WDATA)。 write_lcd(0xC0,WCMD)。 write_lcd(+39。 039。 ,WDATA)。 } } if(model_flag == 0) { write_lcd(0xC4,WCMD)。 write_lcd(%10+39。 039。 ,WDATA)。 write_lcd(0xC3,WCMD)。 write_lcd(+39。 039。 ,WDATA)。 21 } } if(model_flag == 0) { write_lcd(0xC7,WCMD)。 write_lcd(%10+39。 039。 ,WDATA)。 write_lcd(0xC6,WCMD)。 write_lcd(+39。 039。 ,WDATA)。 } } } 秒表 更新函数处理程序 实现功能 通过对 t1 值的判断来得到 秒表的毫秒 秒 分 时 的计算 工作流程图 (如图 551) 是是sw_t1是 否 等 于 1否否否秒 是 否 大 于 59结 束秒 表 的 毫 秒 秒 加 1将 毫 秒 写 入 液 晶秒 是 否 大 于 99毫 秒 清 零 , 秒 加 1将 秒 写 入 液 晶秒 清 零 , 分 加 1将 分 写 入 液 晶是分 是 否 大 于 59否分 清 零 , 时 加 1将 时 写 入 液 晶是时 是 否 大 于 23时 清 零将 时 写 入 液 晶是否 图 551 22 函数部分代码 void update_stop_watch(void) { if(sw_t1=1) { sw_t1=0。 ++。 if(99) { =0。 ++。 if(59) { =0。 ++。 if(59) { =0。 ++。 if(23) { =0。 } if(model_fl。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。