题目:闹钟的设计学生姓名:黄书林学生学号: 1114010110 系别:电气信息工程学院专业:自动化年级: 11 级任课教师:张水锋电气信息工程学院制2013年10月目录摘要 (2)课程任务与要求 (2)方案论证 (2)闹钟流程图 (3)单元电路: (6)单片机芯片 (6)八位数码管显示电路 (7)闹钟调节按键电路 (9)晶振电路 (10)复位电路 (10)蜂鸣器体相电路 (11)总图: (12)心得体会 (13)参考文献 (13)附录 (13)闹钟的设计学生:黄书林指导教师:张水锋电气信息工程学院自动化摘要通过学习《基于Proteus的51系列单片机设计与仿真》让我知道我们不仅需要有过硬的理论知识,还应该有动手实践的能力。
并且是将理论结合实际, 提升到应用层面。
以后走上社会,还是会有很多新的知识是需要我们学习的,届时需要我们有比较强的自学能力。
此次《基于Proteus的51系列单片机设计与仿真》课程设计。
对理论结合实际的动手能力和自学能力有很强的体现。
本次设计是基于 AT89C51 单片机的数字闹钟的设计。
关键词:数字闹钟 AT89C51 Proteus。
课程任务与要求本次课程的任务就是要以51系列单片机为核心设计一个闹钟,它能通过单片机实现秒、分、小时的进位24 小时制,将当前时分秒在七段 LED 显示器上显示。
可设置闹钟的时间当前值对准一时间,设置闹铃时间,闹铃功能的关闭和开放。
要求:通过Proteus软件来实现设计的仿真,提高自己的编程水平,增加设计兴趣。
通过做自己喜欢的设计,提高自学能力。
为以后毕业走上工作岗位打下坚实的基础。
二方案论证经分析,计算器电路包括三个部分:显示部分八位数码管、闹钟时钟按键、单片机电路。
具体分析如下:1 显示部分1.1 LCD显示LCD1602作为一个成熟的产品,使用简单,模式固定,便于移植到各种类型的程序,微功耗、体积小、显示内容丰富、超薄轻巧的诸多优点,价格大概15块钱左右。
1.2数码管显示数码管是一种半导体发光器件,其基本单元是发光二极管。
数码管按段数分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元(多一个小数点显示);按能显示多少个“8”可分为1位、2位、4位等等数码管;按发光二极管单元连接方式分为共阳极数码管和共阴极数码管。
功耗小,显示单一。
适合时钟的显示。
一毛钱一个价格低,对于本次闹钟的设计来说性价比高。
所以采用八位数码管不用LCD1602.2 微控制电路2.1 AVR单片机2.1.1 AVR单片机的I/O口是真正的I/O口,能正确反映I/O口输入/输出的真实情况。
工业级产品,具有大电流(灌电流)10~40 mA,可直接驱动可控硅SSR或继电器,节省了外围驱动器件。
2.1.2.AVR单片机内带模拟比较器,I/O口可用作A/D转换,可组成廉价的A/D转换器。
ATmega48/8/16等器件具有8路10位A/D。
2.1.3 部分AVR单片机可组成零外设元件单片机系统,使该类单片机无外加元器件即可工作,简单方便,成本又低。
2.1.4 AVR单片机可重设启动复位,以提高单片机工作的可靠性。
有看门狗定时器实行安全保护,可防止程序走乱(飞),提高了产品的抗干扰能力。
实现功能非常强大,比51单片机实现功能多。
价格5.2元一块。
2.2 AT89C51单片机AT89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—FalshProgrammable and Erasable Read Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。
AT89C2051是一种带2K字节闪烁可编程可擦除只读存储器D的单片机,单片机可擦除只读存储器可以反复擦除100次。
该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,AT89C51单片机是很多嵌入式控制系统中灵活性高且价廉的芯片。
4.5元一块。
综上所述AT89C51操作简单,价格低采用AT89C51单片机。
三闹钟设计流3.1 主程序流程图图3.13.2时钟中断程序流程图图3.2四单元电路:4.1单片机控制芯片图4.1AT89C516RD+:该电路的核心控制元件是AT89C516RD+。
工作电压在3.3-5.5v之间。
最高时钟频率0-80hz,存储器字节64k。
P0口(32-39引脚)。
既可作为输入输出端口,又可作为地址数据复用总线使用。
当P0口作为输入输出口时,他是一个八位准双向口。
上电复位后处于开漏模式,P0口内部无上拉电阻所以P0口必须接10-4.7k上拉电阻,当作为地址/数据复用总线时。
无需上拉电阻。
EA(31脚)正五伏电源外接晶振或外部振荡器引脚:XTAL1 (19脚)当采用芯片内部时钟信号时,接外部时接外部12M晶振的一个引脚。
当采用外部时钟信号时,此脚应接地。
XTAL2 (18脚)当采用芯片内部时钟信号时,接外部时接外部12M晶振的一个引脚。
当采用外部时钟信号时,此脚应接地。
控制选通或电源复用引脚:RST(9脚):复位信号输入,vcc掉电时此脚可接上备用电源,在低功耗条件下保持内部RAM中数据ALE(30脚):ALE即允许地址锁存信号输出,当单片机访问外部存储器时该引脚的输出信号用于锁存P0口的低8位地址。
其输出的频率为时钟振荡频率的1/6,。
PSEN(29脚):访问外部程序存储器选通信号,低电平有效,用于外部存储器的读操作。
4.2 八位数码管显示电路图4.2LED数码管(LED Segment Displays)是由8个发光二极管构成。
按照一定的图形及排列封转在一起的显示器件。
其中7个LED构成7笔字形,1个LED构成小数点(固有时成为八段数码管)LED数码管有两大类,一类是共阴极接法,另一类是共阳极接法,共阴极就是7段的显示字码共用一个电源的负极,是高电平点亮,共阳极就是7段的显示字码共用一个电源的正极,是低电平点亮。
只要控制其中各段LED 的亮灭即可显示相应的数字、字母或符号。
数码管位数有半位,1,2,3,4,5,6,8,10位等等(及数码管的位数),了解LED的这些特性,对编程是很重要的,因为不同类型的数码管,除了它们的硬件电路有差异外,编程方法也是不同的。
图2是共阴和共阳极数码管的内部电路,它们的发光原理是一样的,只是它们的电源极性不同而已。
颜色有红,绿,蓝,黄等几种。
LED数码管广泛用于仪表,时钟,车站,家电等场合。
选用时要注意产品尺寸颜色,功耗,亮度,波长等。
这是一个7段1位带小数点8引脚的LED数码管图2 引脚定义每一笔划都是对应一个字母表示,DP是小数点。
要是数码管显示数字,有两个条件:1、是要在VT端(3/8脚)加正电源;2、要使(a,b,c,d,e,f,g,dp)端接低电平或“0”电平。
这样才能显示的。
共阳极LED数码管的内部结构原理图图4:图4 共阳极LED数码管的内部结构原理图共阴极LED数码管的内部结构原理图:图5 共阴极LED数码管的内部结构原理图表1.1 显示数字对应的二进制电平信号LED数码管要正常显示,就要用驱动电路来驱动数码管的各个段码,从而显示出我们要的数位。
静态驱动也称直流驱动。
静态驱动是指每个数码管的每一个段码都由一个单片机的I/O口进行驱动,或者使用如BCD码二-十进位转换器进行驱动。
静态驱动的优点是编程简单,显示亮度高,缺点是占用I/O口多,如驱动5个数码管静态显示则需要5×8=40根I/O口来驱动,要知道一个89S51单片机可用的I/O口才32个呢。
故实际应用时必须增加驱动器进行驱动,增加了硬体电路的复杂性。
八位数码管是将上述以为八个并联封装而成,显示时、分、秒都分两位。
个位满十后就向前进一位。
分秒的十位满六十后也向前进一位。
显示小时两位在满二十四后重新计数。
4.3 闹钟调节按键电路图4.3程序中设置 5 个开关控制,从上到下 5 个开关KEY1——KEY5 的功能分别为KEY1,调节时间,每调一次分加1。
KEY2, 调节时间,每调一次时加1。
KEY3从其它状态切换至时钟状态。
KEY4切换至闹钟设置状态。
KEY5闹钟关闭和开放.4.4 晶振电路图4.4每个单片机系统里都有晶振,全程是叫晶体震荡器,在单片机系统里晶振的作用非常大,他结合单片机内部的电路,产生单片机所必须的时钟频率,单片机的一切指令的执行都是建立在这个基础上的,晶振的提供的时钟频率越高,那单片机的运行速度也就越快。
选择合适的晶振很重要。
4.5 复位电路图4.5这个子模块是单片机的最小系统中的一部分,当程序出现乱码等情况时,按下复位程序重新开始运行,使计算继续进行。
4.6 蜂鸣器提醒电路图中RP1是一个九脚排阻为P0口增加驱动能力。
当达到定时时蜂鸣器会发声提醒。
D1为闹钟功能开关显示,当打开时二极管会法官提示。
五总图:此图为时钟电路界面此图为闹钟定时界面七实验改进与心得体会通过对数字闹钟的编程对硬件特别是单片机的原理都有了很深的了解。
更加深了对 C 语言的兴趣可以说整个文件中最麻烦的就是进位条件的判断。
编程中经常犯想当然的错误。
另外对于中断服务子程序的类型设置问题,由于以前对这个概念的理解留于表面,编程中出现了不少奇怪的错误。
再调试中尝试使用了分割法,对错误模块进行定位,再进行排查。
这次的课程设计使我认识到要将《基于Proteus的51系列单片机设计与仿真》的课学好不仅仅是要把书上的基本知识学好而且还要不断进行实践。
将所学的跟实践操作结合起来才能更好地巩固所学,才能提高自己实践能力.通过这次的设计使我认识到只停留在表面理解问题是很难使问题得到很好的解决的。
实践能力与理论知识同样重要。
所以在以后的学习中一方面我要不断的巩固自己所学的理论知识,一方面还要多参加实际操作工作以便提高自己的实际操作能力。
其实这次课程设计的最大收获应该是找到了解决问题的几个很好的途径。
1.讨论 2.通过网络,在网络上也收获了很多。
共享让我们共同进步。
此外,我学会了看硬件结构图,并学会了自己去独立的完善一个程序,对程序的效用等做思考。
并体会到问别人只能帮你开拓思路,真正解决问题还是要靠自己去摸索。
当然讨论是很好的学习途径,它会让你事半功倍.由于时间不是很充裕,程序中有很多值得改善的地方。
我尝试在其中加入更多的功能,但调试的结果没有。
参考文献【1】谭浩强著《C语言程序设计》第三版【2】康光华陈大钦张琳主编《电子技术基础模拟部分》第五版【3】康光华陈大钦张琳主编《电子技术基础数字部分》第五版【4】周荣富曾技主编《电子线路CAD》【5】《单片机原理与接口技术》清华版【6】《零基础学单片机C语言》【7】《物联网技术与应用》刘盼芝【9】《基于Protues的51系列单片机设计与仿真》陈忠平附录:#include<reg51.h>#define uchar unsigned char#define uint unsigned intuint tcount,u;data2[]={0,0,0,0,0,0,0,0};//uchar dat1[]={0,0,0,0,0,0,0,0};//时钟定时缓冲区uchar alarms[]={0,0,0,0,0,0,0,0};//闹钟定时缓冲区uchar dis_bit[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};// unsigned char code SEG7[11]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x BF,};sbit tminute=P1^0;sbit thour=P1^1;sbit shizhong=P1^2;sbit alarm=P1^3;sbit alarmswitch=P1^4;sbit P0_4=P0^4;sbit P0_0=P0^0;uint sw=0;uchar k;uchar ms=0;uchar flag=0;//闹钟切换标志位uchar sec=0;//闹钟计时秒uchar minit=0;//闹钟计时分struct time{uchar second;uchar minute;uchar hour;}time1;//定义名为time 的结构体..变量名time1uchar n,i;void delay(n)//1ms 延时函数{while(n--){for(i=120;i>0;i--);}}void modify(void)//时间调整{EA=0;if(thour==0){if(flag==0)//时钟调整每次加1{dat1[6]++;delay(200);if(dat1[6]>3&&dat1[7]==2){dat1[6]=0;dat1[7]=0;}if(dat1[6]>9){if(alarm==0)//闹钟键按下..显示00-00-00 {flag=1;alarms[0]=0;void init(void)//初始化{TMOD = 0x11;TH0 = 0xDB;TL0 =0xFF;//工作方式3..两个8 位定时/计时器..只有T0 有......定时24ET0 = 1;TR0=1;tcount=0;u=0;P0=0x00;EA = 1;//开放中断}void test(void){for(k=0;k<8;k++){if(flag==0){ P3=dis_bit[k];P2=SEG7[dat1[k]]; delay(1);P3=0X00;}if(flag==1){ P3=dis_bit[k];P2=SEG7[alarms[k]]; delay(1);P3=0X00;}}}void main(){init();delay(10);while(1) //括号的“1”表示while()判断条件为真..只要不是“0”..这个循环就一直循环{modify();test();}}void diplay() interrupt 1 //定时/计数器T0 中断{ time1.second=dat1[0]+dat1[1]*10;time1.minute=dat1[3]+dat1[4]*10;time1.hour=dat1[6]+dat1[7]*10;ET0=0;TR0=0;TH0 = 0xDB;TL0 = 0xff;TR0=1;tcount++;if(tcount==100){time1.second++;tcount=0;dat1[0]=(time1.second)%10; dat1[1]=(time1.second)/10; }if(time1.second>59){time1.second=0;time1.minute++;dat1[0]=(time1.second)%10; dat1[1]=(time1.second)/10; dat1[3]=(time1.minute)%10; dat1[4]=(time1.minute)/10; }if(time1.minute==60){time1.minute=0;time1.hour++;dat1[3]=(time1.minute)%10;dat1[4]=(time1.minute)/10;dat1[6]=time1.hour%10;dat1[7]=time1.hour/10;}if(time1.hour>23){time1.hour=0;}dat1[5]=10;dat1[2]=10;if((alarms[7]==dat1[7])&&(alarms[6]==dat1[6])&&(alarms[4]==dat 1[4])&&(alarms[3]==dat1[3])&&(sw==1)){P0=0x11;}ET0=1;}。