目录1. 设计要求 12. 时钟总体设计思路 13. 系统硬件设计 13.1单片机控制系统 33.2键盘控制系统设计 33.3显示电路 43.4硬件原理及说明 43.5主要性能参数 54. 软件设计 54.1软件功能 54.2软件设计 64.3汇编源程序 55. Proteus 仿真 116. 课程设计总结 12参考文献 131. 设计要求以AT89C51单片机为核心的时钟,在LED显示器上显示当前的时间: 使用字符型LCD显示器显示当前时间显示格式为“时时:分分:秒秒”用4个功能键操作来设置当前时间功能键K1〜K4功能如下K1—设置小时K2—设置分钟K3—设置秒数程序执行后工作指示灯LED闪动,表示程序开始执行,LED显示“00: 00: 00”, 然后开始计时单片机是一种集成电路芯片,采集超大规模集成电路技术把具有数据处理能 力(如算数运算、逻辑运算、数据传送、中断处理)的微型处理器,随机存取数 据存储器(RAM)、只读程序存储器(ROM)、输入/输出电路(I/O),可能还包 括定时/计数器、串行通信口(SCI)、显示驱动电路(LCD或LED驱动电路)、 脉宽调制电路(PWM)、模拟多路转化器及A/D转化器等电路集成到一片芯片上, 构成一个最小而又完善的计算机系统。
这些电路能在软件的控制下准确、迅速、 高效的完成程序设计者事先规定的任务2. 时钟的总体设计思路按照系统的设计功能要求,本时钟系统的设计必须采用单片机软件系统实 现,用单片机的自动控制能力配合按键控制,来控制时钟的调整及显示图一系统总原理图3. 系统硬件设计3.1单片机控制系统本次设计时钟电路,采用了 ATC89C51单片机芯片控制电路,这种单片机芯片 比较简单,并且省去了很多复杂的线路,更容易表达和理解,通过按钮来调节电 子钟的时、分、秒并且这次电路我采用了一个按钮控制一个显示的方案,在调 节小时/分钟/秒数时,只需要按下对其控制的按钮进行调节就行了,不要普遍所 见的需要进入调节界面同时这次我采用了 c语言控制整个时钟的显示,这样通 过三个模块:单片机芯片、LED显示屏、按钮控制电路即可达到设计要求3.2键盘控制系统设计按键需要3个,分别实现为调整小时、分钟、秒数三个功能用单片机的3 个I/O 口接收控制信号,其电路如图下:图五按键调时电路通过控制键来控制所要调节的是时、分、还是秒在按下小时/分/秒键后 将对小时/分/秒进行调整调整,从而调整到自己所需要的时间3.3显示电路显示电路如图所示:图六显示电路LM016L液晶模块采用HD44780控制器,hd44780具有简单而功能较强的指 令集,可以实现字符移动,闪烁等功能,LM016L与单片机MCU通讯可采用8 位或4位并行传输两种方式,hd44780控制器由两个8位寄存器,指令寄存器(IR) 和数据寄存器(DR)忙标志(BF),显示数RAM (DDRAM),字符发生器ROMA (CGOROM)字符发生器RAM (CGRAM),地址计数器RAM(AC)。
IR用于寄 存指令码,只能写入不能读出,DR用于寄存数据,数据由内部操作自动写入 DDRAM和CGRAM,或者暂存从DDRAM和CGRAM读出的数据,BF为1时, 液晶模块处于内部模式,不响应外部操作指令和接受数据,DDTAM用来存储显 示的字符,能存储80个字符码, CGROM由8位字符码生成5*7点阵字符160中和5*10点阵字符32种.8位字符编码和字符的对应关系,CGRAM是为用户 编写特殊字符留用的,它的容量仅64字节,可以自定义8个5*7点阵字符或者 4个5*10点阵字符,AC可以存储DDRAM和CGRAM的地址,如果地址码随 指令写入IR,则IR自动把地址码装入AC,同时选择DDRAM或CGRAM 4.1软件功能 4 0[3] 丁元杰•单片微机原理及应用•北京:机械工业出版社,1994 133.4硬件原理及说明AT89C51是美国Intel公司生产的低电压,高性能CHMOS8位单片机,片 内含有4k bytes的可反复擦写的只读程序存储器(PEROM)和128 bytes的随机 存取数据存储器(RAM),器件采用Intel公司的高密度、非易失性存储技术生产, 片内置通用4位中央处理器(CPU)和Flash存储单元,功能强大AT89C51单片 机适合于许多较为复杂控制应用场合。
3.5主要性能参数与MCS-51产品指令和引脚完全兼容4k字节可重擦写Flash闪速存储器1000次擦写周期全静态操作:0Hz—24MHz三级加密程序存储器128X8字节内部RAM32个可编程I/O 口线2个16位定时/计数器5个中断源可编程串行UART通道低功耗空闲和掉电模式4. 软件设计4.1软件主要完成的功能(1) 显示时间程序用软件调节时间,通过程序的调节,最后用LED现实时钟(2) 调节时间程序按键调节时间,能实现时、分的调节4.2软件设计的主要流程时间控制程序时间控制程序,用中断准确的控制时间,采用60进制,60秒为一分钟,60 分钟为一个小时,全天设置为24小时程序用C语言编写编程时采用KEIL C,而仿真用PROTUES,仿真时仿 真图如图所示TO中斷保护现场计时rr\到1秒了吗?N+ Y秒单元加1+7<到60秒了吗?秒单元清零,分单元加11Y到60分了吗?N1Y分单元清零*时单元加1*7<到24时了吗?1Y时单元清零恢复现场中斷返回图七定时中断流程图4.3 汇编源程序#include 〈reg51.h〉#include 〈intrins.h〉#define uchar unsigned char#define uint unsigned int#define DelayN0P() {_nop_();_nop_();_nop_();_nop_();} sbit KI 二P「0;sbit K2 二P「l;sbit K3 二P「2;sbit K4 二P「3;sbit SPK=P3'0;sbit RS 二P2"0;sbit RW =P2"1;sbit E 二P2"2;uchar code St r1[] = "" Curren t Time ""; //一下两个字符串的串长均为 16 uchar code Str 2[] = ""Se t New Time..."";uchar HMS_S tring[]="" 00:00:00 "";//带显示的时间串bit Sett ime=0; //是否修改时间bit Change_H_or_M =1;//1表示修改时.0表示修改分 uchar MilliSecond,Hour =0,Minute=0, Second =0;//延时函数void DelayMS(uint x){uchar i; while(x—) for(i=0;i〈120;i++);}//LCD忙状态检测bit LCD_Busy_Check(){bit result;RS = 0;RW = 1;E = l;DelayNOP();result = (bi t)(PO & 0x80);E = 0; return result;}//写LCD命令void LCD_Write_Command(uchar cmd){while(LCD_Busy_Check());//判断 LCD 是否忙碌RS = 0;RW = 0;E = 0;_nop_();_nop_();P0 = cmd; DelayNOP();E = 1;DelayNOP();E = 0;}//设置LCD显示位置void LCD_Set_Pos(uchar pos){LCD_Write_Command(pos | 0x80);}//写LCD数据void LCD_Write_Data(uchar dat){while(LCD_Busy_Check());//判断 LCD 是否忙碌RS = 1;RW = 0;E = 0;P0 = dat; DelayNOP();E = 1;DelayNOP();E = 0;}//LCD初始化void LCD_Initialize(){LCD_Write_Command(0x38);DelayMS(l);LCD_Write_Command(0x0c);DelayMS(l);LCD_Write_Command(0x06);DelayMS(l);LCD_Write_Command(0x01);DelayMS(l);}//显示函数,在LCD指定的行上显示字符串void Display_String(uchar*str, uchar LineNo){uchar k;LCD_Set_Pos(LineNo); for(k=0;k〈16;k++) LCD_Write_Data(str[k]);}//蜂鸣函数 void Beep(){uchar i, j = 70;for(i=0;i〈200;i++){while(—j);SPK= ~SPK;}DelayMS(300); SPK=0;}//时分秒显示void Display_HMS(uchar h,m,s){辻(Se tt ime) HMS_S tring[3] = '〉';//显示修改标志 else HMS_S tring[3] = ' '; //不显示修改标志HMS_String[4]=h/10+'0';//时HMS_String[5]=h%10+'0';HMS_String[7]=m/10+'0';//分HMS_String[8]=m%10+'0';HMS_String[10]=s/10+'0';//秒HMS_String[ll]=s%10+'0';Display_String(HMS_String,0x40);}//设置时间void Change_Time(){Settime=0;if(Kl==0||K2==0||K3==0) //按下k1 k2 k3中的任何一个键即进入修改状态{TRO = 0;Display_S tring(S tr2,0x00); //第一行提示修改时间Settime = 1;}while (Settime){if(K1 == 0) //确定调整小时还是分钟{Beep();while(K1 == 0)Change_H_or_M = !Change_H_or_M;}else 辻(K2 == 0) //增加{Beep(); while(K2 == 0); if(Change_H_or_M==l) {if (++Hour == 24) Hour = 0;} else{if (++Minute == 60) Minute = 0;}}else 辻(K3 == 0) //减少{Beep(); while(K3 == 0);if(Change_H_or_M == 1){if(—Hour == 0xff) Hour 。