1、图 1.1.1 器件设计图基于单片机 89C52 的液晶数字钟设计摘要 设计采用定时计数器工作方式 1 进行数值上的累加,经过延时程序,lcd1602 驱动程序和时间格式转换程序,实现了数字钟的正常运转以及显示。添加整点报时,用 1 个 if语句设置整点条件调用蜂鸣器程序实现功能;添加闹钟功能,通过当前时间与闹钟时间的对比促使蜂鸣器发声。关键词 定时计数器 LCD1602 闹钟 单片机 89C52 1. 电路设计1.1 主体设计1.1.1 设计原理P1(0.1.2.3)At89c525 个四脚独立键(有复位)LCD1602晶振蜂鸣器如器件设计图所示,这是器件摆放的位置图。Lcd1602 的 D
2、B 端接单片机的 P0 端,使用P0 端要外接上拉电阻,这里放置 10k 阻值的排阻。蜂鸣器需要三极管放大后方可使用。开关用四脚独立按键,接 P1 端。使用 12MHz 的晶振。1.2 各部分设计1.2.1 时钟设计单片机的时钟有两种方式产生,分 别是内部方式和外部方式。设计采用内部方式。产生时钟的是振荡电路。由一个 12MHz 的晶振和两个 30pF 的串联着的电容并联在一起,形成谐振电路。晶振和电容大小涉及电 路振荡频率的稳定性和大小,以及起振响应速度。1.2.2 复位设计复位有两种,区别在于是否有开关。按一次开关,电位变化形成一次脉冲,使单片机复位。采用 10k 电阻和 10uF 的电解
3、电容。1.2.3 按键设计有三种模式,分别是工作模式,当前时间设置模式,闹铃时间设置模式。(1)工作模式。就是正常数字钟 功能,有整点 报时功能。(2)当前时间设置模式。1 键进 入该模式,之后,1 键调时,2 键调分, 3 键确认。(3)闹铃时间设置模式。3 键进 入该模式,之后,1 键调时,2 键调分, 3 键确认,4 键打开闹铃。工作模式 2 键可以查看闹铃时间。1.2.4lcd1602 设计Lcd1602 的 DB 端接单片机的 P0 端,2 和 15 脚接 5v,其他的接地。加 10k 排阻,程序正确,电路无差错,可正常使用。1.2.5 蜂鸣器设计蜂鸣器通过三极管放大后使用,作用有闹
4、铃和整点报时的发声。三极管采用 pnp 型规格。图 1.3 仿真图1.3 软件仿真 Proteus 7.5设计仿真用到的器件在此版本软件上都能找到。仿真实现了,证明程序无错,可以使用。开关 BUTTON,单片机 AT89C51,晶振 CRVSTAL,电容 CAP,电解电容 CAP-POL,电阻 RES,排阻 RES-PACK-8,液晶 LMD16L,pnp 三极管,蜂鸣器用扬声器代替 SPEAKER。连接好线路,调好器件电压 5v,就可以下载程序,仿真成功实现了。图 1.4PCB 设计1.4 硬件 Altium Designer 10硬件需要此软件绘制电路印制图。器件封装有自带的,也需要自己绘
5、制,建议封装均检查一遍。3.硬件分析3.1 硬件的使用按键采用的是四脚独立按键,实质上用到的是两个引脚两个距离比较窄的脚。复位电路中电解电容的使用,不是限制电流的大小,而是控制复位时间,晶振要靠近 51 芯片3.2 调试先仿真后做实物,遇到的问题较少。调试过程,先检查最小系统,包括晶振电路,复位电路。复位时发现,若用瓷片电容,则调换为电容接地,电阻接 5V。注意 1602 接排阻。实物检测1.上电后,正常液晶显示,并报时。2.设置时间,按 1 键进入,按 1 键调时,2 键调分,3 键完成。3.设置闹钟,按 1 键进入,按 1 键调时,2 键调分,3 键完成,4 键打开。4.到整点响铃,闹钟时
6、间到响铃。2 键可查看闹钟时间。功能全部实现,除复位键,每个键两个功能。5.结论设计主要是程序上的运用,辅以相应的器件。用到的器件都是常见,所以操作上并不难。仿真用来查看程序缺漏,减少实物制作过程的失败率,以及防止设计偏离方向。硬件设计上,分部好地线和火线,火线内部,地线外部,两根主线的设计方便器件正确插入。焊接是最后的工序,容易出错,先前工序无错,也容易找出错的地方。论文讲了项目的程序思想,电路原理,器件的选择以及需要注意的事项。6. 程序#include#include#define uint unsigned int#define uchar unsigned char#define L
7、CD1602_DB P0 /定义 1602 的 DB 口为 P0 口uchar code table=“CurrentTime“; /当前时间uchar code table1=“00:00:00“;uchar key1Flag = 0;/定义按键关闭符uchar key2Flag = 0;uchar key3Flag = 0;uchar key4Flag = 0;uchar temp = 0;uchar sec = 0;/秒uchar min = 0;/分uchar hour = 0;/小时uchar clkHour = 0;/闹钟小时uchar clkMin = 0;/分uchar clk
8、Flag = 0;/ 定义闹钟关闭符uchar beepNum = 0;/声音sbit LCD1602_RS = P20; /指令 1/数据 0 选择端sbit LCD1602_RW = P21; /读 1 写 0 选择端sbit LCD1602_E = P22; /读 1 写 0 使能端sbit Key1 = P10;/定义键位符sbit Key2 = P11;sbit Key3 = P12;sbit Key4 = P13;sbit Speaker = P25;/定义蜂鸣 器void Delay1ms() /12.000MHzuchar i, j;i = 12;j = 169;dowhile
9、 (-j); while (-i);void Delay20ms() /12.000MHzuchar i, j, k;_nop_();_nop_();i = 1;j = 234;k = 113;dodowhile (-k); while (-j); while (-i);void Beep() /蜂鸣器警报 Speaker = 0;Delay20ms();Speaker = 1;void LcdWaitReady()uchar sta;LCD1602_DB = 0xFF;LCD1602_RS = 0;LCD1602_RW = 1;do LCD1602_E = 1;sta = LCD1602_D
10、B;LCD1602_E = 0;while(sta void LcdWriteCmd(uchar cmd)LcdWaitReady();LCD1602_RS = 0;LCD1602_RW = 0;LCD1602_DB = cmd;LCD1602_E = 1;LCD1602_E = 0;void LcdWriteDat(uchar dat)LcdWaitReady();LCD1602_RS = 1;LCD1602_RW = 0;LCD1602_DB = dat;LCD1602_E = 1;LCD1602_E = 0;void LcdSetCursor(uchar x, uchar y)/时间设置
11、uchar addr;if(y = 0)addr = 0x00 + x;elseaddr = 0x40 + x;LcdWriteCmd(addr | 0x80);void LcdShowStr(uchar x, uchar y, uchar *str) LcdSetCursor(x, y);while(*str != 0)LcdWriteDat(*str+); void InitLcd1602() LcdWriteCmd(0x38);LcdWriteCmd(0x0C);LcdWriteCmd(0x06);LcdWriteCmd(0x01);void WriteAddress(uchar x)L
12、cdWriteCmd(0x80 + x);void DisplayMinTens() /显 示分十位WriteAddress(0x49);LcdWriteDat(min / 10) + 0);Delay1ms();void DisplayMinUnits() /显示分个位 WriteAddress(0x4A);LcdWriteDat(min % 10) + 0);Delay1ms();void DisplayHourTens() /显 示时十位WriteAddress(0x46);LcdWriteDat(hour / 10) + 0);Delay1ms();void DisplayHourUn
13、its()/显示时个位 WriteAddress(0x47);LcdWriteDat(hour % 10) + 0);Delay1ms();void DisplayClkMinTens() /显示闹钟分十位 WriteAddress(0x49);LcdWriteDat(clkMin / 10) + 0);Delay1ms();void DisplayClkMinUnits() /显 示闹钟分个位 WriteAddress(0x4A);LcdWriteDat(clkMin % 10) + 0);Delay1ms();void DisplayClkHourTens() /显示闹钟时十位WriteA
14、ddress(0x46);LcdWriteDat(clkHour / 10) + 0);Delay1ms();void DisplayClkHourUnits() /显示闹钟时个位 WriteAddress(0x47);LcdWriteDat(clkHour % 10) + 0);Delay1ms();void DisplayClkSecTens() /显示秒十位 WriteAddress(0x4C);LcdWriteDat(sec / 10) + 0);Delay1ms();void DisplayClkSecUnits() /显示秒个位WriteAddress(0x4D);LcdWrite
15、Dat(sec % 10) + 0);Delay1ms();void ScanKey4()if(Key4 = 0)if(Key4 = 0)beepNum = 0;key4Flag = 0;void InitTimer0()/初始化定时器 0 TMOD = 0x01; TH0 = (65536 - 50000) / 256;TL0 = (65536 - 50000) % 256;EA = 1;ET0 = 1;TR0 = 1;void main() InitLcd1602();LcdShowStr(0,0,table);LcdShowStr(6,1,table1);InitTimer0();whi
16、le(1) if(sec = 60) sec = 0;min+;if(min = 60) min = 0;hour+;if(hour = 24) hour = 0;LcdShowStr(0,0,table);DisplayHourTens();DisplayHourUnits();LcdShowStr(8,1,“:“);DisplayMinTens();DisplayMinUnits();LcdShowStr(11,1,“:“);DisplayClkSecUnits();DisplayClkSecTens();/=if(Key1 = 0)if(Key1 = 0)InitLcd1602();Lc
17、dShowStr(0,0,“SetCurrentTime“);DisplayHourTens();DisplayHourUnits();LcdShowStr(8,1,“:“);DisplayMinTens();DisplayMinUnits();key1Flag = 1;while(key1Flag = 1) if(Key1 = 0) Delay20ms();if(Key1 = 0) hour+;if(hour = 24) hour = 0;DisplayHourTens();DisplayHourUnits();LcdShowStr(8,1,“:“);DisplayMinTens();Dis
18、playMinUnits();if(Key2 = 0) Delay20ms();if(Key2 = 0) min+;if(min = 60) min = 0;hour+;DisplayHourTens();DisplayHourUnits();LcdShowStr(8,1,“:“);DisplayMinTens();DisplayMinUnits();if(Key3 = 0)if(Key3 = 0)LcdShowStr(0,0,table);DisplayHourTens();DisplayHourUnits();LcdShowStr(8,1,“:“);DisplayMinTens();Dis
19、playMinUnits();LcdShowStr(11,1,“:“);DisplayClkSecUnits();DisplayClkSecTens();key1Flag = 0;TR0 = 1;/=if(min=0)Delay20ms();/=if(Key2 = 0)if(Key2 = 0)InitLcd1602();while(key2Flag = 1) LcdShowStr(0,0,“Clock Time“);DisplayClkHourTens();DisplayClkHourUnits();LcdShowStr(8,1,“:“);DisplayClkMinTens();Display
20、ClkMinUnits();if(Key2 = 0) Delay20ms();if(Key2 = 0) key2Flag = 0;InitLcd1602();DisplayHourTens();DisplayHourUnits();LcdShowStr(8,1,“:“);DisplayMinTens();DisplayMinUnits();LcdShowStr(11,1,“:“);DisplayClkSecUnits();DisplayClkSecTens(); /=if(Key3 = 0)if(Key3 = 0)InitLcd1602();LcdShowStr(0,0,“SetClockTi
21、me“);DisplayClkHourTens();DisplayClkHourUnits();LcdShowStr(8,1,“:“);DisplayClkMinTens();DisplayClkMinUnits();key3Flag = 1;while(key3Flag = 1) if(Key1 = 0) Delay20ms();if(Key1 = 0) clkHour+;if(clkHour = 24) clkHour = 0;DisplayClkHourTens();DisplayClkHourUnits();LcdShowStr(8,1,“:“);DisplayClkMinTens()
22、;DisplayClkMinUnits();if(Key2 = 0) Delay20ms();if(Key2 = 0) clkMin+;if(clkMin = 60) clkHour+;clkMin = 0;DisplayClkHourTens();DisplayClkHourUnits();LcdShowStr(8,1,“:“);DisplayClkMinTens();DisplayClkMinUnits();if(Key3 = 0) /退出设置闹钟时间Delay20ms();if(Key3 = 0) key3Flag = 0;InitLcd1602();TR0 = 1;DisplayHou
23、rTens();DisplayHourUnits();LcdShowStr(8,1,“:“);DisplayMinTens();DisplayMinUnits();LcdShowStr(11,1,“:“);DisplayClkSecUnits();DisplayClkSecTens();/=if(Key4 = 0)if(Key4 = 0)InitLcd1602();LcdShowStr(0,0,“Clock ON“);Delay20ms();Beep();Delay20ms();Beep();Delay20ms();Beep();Delay20ms();Delay20ms();if(Key4
24、= 0)if(Key4 = 0)InitLcd1602(); LcdShowStr(0,0,“Clock OFF“);Beep();Delay20ms();Delay20ms();Delay20ms();Delay20ms();/=if(key4Flag = 1) /闹钟时间到InitLcd1602();LcdShowStr(0,0,“Times up“);while(clkFlag = 1) Beep();ScanKey4();Delay20ms();ScanKey4();Delay20ms();ScanKey4();Delay20ms();ScanKey4();Delay20ms();ScanKey4();beepNum+;if(beepNum = 20) clkFlag = 0;beepNum = 0;key4Flag = 0;void Timer0() interrupt 1 temp+;if(temp = 20) sec+;temp = 0;TH0 = (65536 - 50000) / 256;TL0 = (65536 - 50000) % 256;