《单片机原理及接口》课程设计报告题目:时钟系统设计专业名称:电子信息工程班级: 092 学号: 910706220 姓名:2011年 12月时钟系统设计陈(电子信息工程学系)中文摘要:本设计基于单片机仿真技术,以单片机芯片AT89C52作为核心控制器,通过硬件电路的制作以及软件程序的编制,设计制作出一个多功能数字时钟系统。
单片机扩展的LCD显示器用来显示秒、分、时计数单元中的值。
整个设计包括两大部分:硬件部分和软件部分,以单片机为核心,蜂鸣器,数码管,晶体管等为外围器件,设计一个正常走时,报时、初始化、闹钟的数字时钟。
关键词:单片机;数字时钟;AT89C52;闹钟1、设计目标设计一时钟系统,系统具有时钟功能,能准确显示时、分、秒,系统还应具有校正功能:能够修改当前的时间。
2、设计环境Windows7 Keil uVision3 Proteus7.53、系统硬件设计3.1单片机控制系统:本设计基于单片机技术原理,以单片机芯片AT89C52作为核心控制器,通过硬件电路的制作以及软件程序的编制,利用单片机的控制作用通过LCD来直接时、分、秒,并能对其分别进行设置、修改;利用对蜂鸣器的控制来实现闹钟功能。
同时使用C语言程序来控制整个时钟显示,使得编程变得更容易,这样通过三个模块:键盘、芯片、显示屏即可满足设计要求。
3.2各部分功能实现:单片机采用52系列单片机。
由ATMEL公司生产的AT89S52是一种低功耗、高性能CMOS8位微控制器,具有8K在系统可编程Flash存储器。
使用Atmel公司高密度非易失性存储器技术制造,与工业80C51产品指令和引脚完全兼容。
在单芯片上,拥有灵巧的8位CPU和在线系统可编程Flash,使得AT89S52为众多嵌入式控制应用系统提供高灵活、有效的解决方案。
AT89S52具有以下标准功能:8K字节Flash,256字节RAM,32位I/O口线,2个数据指针,三个16位定时器/计数器,一个6向量2级中断结构,全双工串行口,片内晶振及时钟电路。
空闲模式下,CPU停止工作,允许RAM、定时器/计数器、串口、中断继续工作。
掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。
而且,它还具有一个看门狗(WDT)定时/计数器,如果程序没有正常工作,就会强制整个系统复位,还可以在程序陷入死循环的时候,让单片机复位而不用整个系统断电,从而保护你的硬件电路。
3.3单片机最小系统:单片机最小系统主要由复位电路,晶振电路,电源等几部分组成。
复位电路如图1:图1 复位电路复位电路有两种方式:上电复位和按钮复位,我们主要用按钮复位方式。
如图2所示:晶振电路:晶振电路如图三所示:图2 晶振模块原理图选取原则:电容选取22pF,晶振为12MHz。
电源:AT89S52单片机的供电电源是5V的直流电。
EA非/Vpp脚:我们没有用外部扩展ROM,因此EA非/Vpp为高电平,即接+5V电源。
3.4键盘控制系统设计:按键需要4个,分别实现为时间调整、时间的加、时间的减、闹钟调整四个功能。
用单片机的4个I/O口接收控制信号,其电路如图3所示:图3 按键调时电路通过控制键来控制所要调节的是时、分、还是秒。
在控制键按下后LCD中会在相应的位置出现光标,这时在通过加数键或减数键来控制时分秒的加或减。
在调闹钟键按下后LCD中也会在相应的位置出现光标,这时也通过加数键或减数键来设置闹钟。
显示电路:显示电路图如图4所示:图4 显示电路图闹钟部分:闹钟部分主要由蜂鸣器,三极管,电阻组成。
其电路图如图5所示:图5 闹钟电路当单片机的P1^5接口输出为高电平时,蜂鸣器响,当输出为低电平时,蜂鸣器停止。
时钟连接图如图6:图6 电路图4、软件设计软件流程图:初始化判断显示内容动态显示按键扫描是否按键 执行相应功能是主程序流程开始否重新赋初值闪烁显示控制是否开闹钟 是否开闹钟计时是否整点报时 整点报时是否 回到主程序T1定时器中断流程5、系统调试首先运行keil软件,并新建一工程并保存,然后再新建一C文件并输入程序代码(见附录)调试运行生成.hex文件,然后打开protues软件并打开新建的.hex文件,之后点击单片机出现如图7窗口:图 7 添加hex文件窗口最后单击窗口中该按钮添加hex文件并点击确定按钮,运行文件出现如图8所示仿真结果:图8 仿真结果6、软件编程程序主要分为两个部分,即显示部分和控制按键部分。
由于本设计采用的是用按键分别控制,可以在主函数中调用一个键盘扫描的函数,当相应的不同按键按下后通过控制单片机P2的输出,从而控制液晶的显示。
源程序见附录二所示:编程思路:在确定了时钟要实现的功能后按照上述各按键所实现的效果编写程序。
本程序包含液晶写指令函数(write-com())、写数据函数(write-data())、初始化函数(init())、写入时分秒函数(write-sfm())和键盘扫描函数,这些程序围绕主函数相互调用。
7、总结与体会在本次设计的过程中,我发现很多的问题,同时也让我认识到单片机课程设计重点就在于软件算法的设计,需要有很巧妙的程序算法。
从这次的课程设计中,我真真正正意识到,在写程序时,逻辑思维要清晰,要有耐心。
在以后的学习中,要理论联系实际,把我们所学的理论知识用到实际当中,学习单片机更是如此,程序只有经常写和读才能提高,这就是我在这次设计中的最大收获。
参考文献:[1].李光才.单片机课程设计实例指导[M].北京:北京航空航天大学出版社, 2004.[2] 朱定华.单片机原理及接口技术实验[M].北京:北方交通大学出版社,2002.11[3] 刘湘涛.江世明.单片机原理与应用[M]. 北京:电子工业出版社,2006.[4] 何立民.单片机应用系统设计[M].北京:北京航空航天大学出版社,1993.[5] 楼然笛.单片机开发[M].北京:人民邮电出版社,1994.[6] 付家才.单片机控制工程实践技术[M].北京:化学工业出版社,2004.3.附录:#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit beep=P1^5; //定义蜂鸣器的io口sbit rw=P2^1; //定义读写的io口sbit rs=P2^0; //定义接收与发送指令的io口sbit lcden=P2^2; //定义使能端的io口sbit k1=P3^0; //定义调时键的io口sbit k2=P3^1; //定义加数键的io口sbit k3=P3^2; //定义减数键的io口sbit k4=P3^3; //定义调闹钟键的io口uchar count,count1,num,num1,num2;char h,min,sec,h1,min1,sec1;uchar table[]={" 11:59:57"};uchar table1[]={" 12:30:00"};void delay(uint z) //延时程序{int x,y;for(x=z;x>0;x--)for(y=120;y>0;y--);}delay1(uchar z) //延时程序{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void write_com(uchar com) //写指令函数{rs=0;rw=0;lcden=0;P0=com;delay(1);lcden=1;delay(1);lcden=0;}void write_data(uchar date) //写数据函数rs=1;rw=0;lcden=0;P0=date;delay(5);lcden=1;delay(5);lcden=0;}void write_pos(uchar pos) //设定地址{write_com(pos | 0x80); //数据指针=80+地址变量}void write_sfm(uchar add,uchar date) //设定时分秒及其显示与地址{uint shi,ge;shi=date/10;ge=date%10;write_com(0x80+0x40+add);write_data(0x30+shi);write_data(0x30+ge);}void write_sfm1(uchar add,uchar date) //设置闹钟时分秒及其显示与地址{uint shi,ge;shi=date/10;ge=date%10;write_com(0x80+add);write_data(0x30+shi);write_data(0x30+ge);}void keyscan() //键盘扫描{if(k1==0){delay1(5);if(k1==0){while(!k1);num++;if(num==1)TR0=0;write_com(0x80+0x40+11);write_com(0x0f);}if(num==2){write_com(0x80+0x40+8);}if(num==3){write_com(0x80+0x40+5);}if(num==4){num=0;write_com(0x0c);TR0=1;}}}if(num!=0){if(k2==0){delay1(5);if(k2==0){while(!k2)if(num==1){sec++;if(sec==60)sec=0;write_sfm(10,sec);write_com(0x80+0x40+0x10);}if(num==2){min++;if(min==60)min=0;write_sfm(7,min);write_com(0x80+0x40+8);if(num==3){h++;if(h==24)h=0;write_sfm(4,h);write_com(0x80+0x40+5);}}}if(k3==0){delay1(5);if(k3==0){while(!k3);if(num==1){sec--;if(sec==-1)sec=59;write_sfm(10,sec);write_com(0x80+0x40+0x10);}if(num==2){min--;if(min==-1)min=59;write_sfm(7,min);write_com(0x80+0x40+8);}if(num==3){h--;if(h==-1)h=23;write_sfm(4,h);write_com(0x80+0x40+5);}}}}if(k4==0){delay1(5);if(k4==0){while(!k4);num1++;if(num1==1){write_sfm1(10,sec1);write_sfm1(7,min1);write_sfm1(4,h1);}if(num1==2){write_com(0x80+11);write_com(0x0f);}if(num1==3){write_com(0x80+8);}if(num1==4){write_com(0x80+5);}if(num1==5){num1=0;write_com(0x0c);write_sfm(10,sec);write_sfm(7,min);write_sfm(4,h);}}}if(num1!=0){if(k2==0){delay1(5);if(k2==0){while(!k2)if(num1==2){sec1++;if(sec1==60)sec1=0;write_sfm1(10,sec1);write_com(0x80+0x10);}if(num1==3){min1++;if(min1==60)min1=0;write_sfm1(7,min1);write_com(0x80+8);}if(num1==4){h1++;if(h1==24)h1=0;write_sfm1(4,h1);write_com(0x80+5);}}}if(k3==0){delay1(5);if(k3==0){while(!k3);if(num1==2){sec1--;if(sec1==-1)sec1=59;write_sfm1(10,sec1);write_com(0x80+0x10);}if(num1==3){min1--;if(min1==-1)min=59;write_sfm1(7,min1);write_com(0x80+8);}if(num1==4){h1--;if(h1==-1)h1=23;write_sfm1(4,h1);write_com(0x80+5);}}}}}void init() //程序初始化函数{uint i;h=11;min=59;sec=57;h1=12;min1=30;sec1=00;num=0;lcden=0;write_com(0x38); //设置16乘2格式delay(1);write_com(0x0c); //显示开,关光标delay(1);write_com(0x06); //移动光标delay(1);write_com(0x01); //清除LCD的显示内容delay(1);i=0;while(table1[i] != '\0') //显示闹钟(静态){write_data(table1[i]);i++;}i=0;write_pos(0x40);while(table[i] != '\0') //显示时间(静态){write_data(table[i]);i++;}TMOD=0x01; //定时器TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1; //开启定时器ET0=1;TR0=1;}void main(){init();while(1){keyscan();if(min==min1&&h==h1) //闹钟启动条件{if(sec<=3) //响三秒{beep=1;}elsebeep=0;}elsebeep=0;}}void timer0() interrupt 1 //定时器时间设定{TH0=(65536-50000)/256;TL0=(65536-50000)%256;count++;if(count==20){count=0;sec++;if(sec==60){sec=0;min++;if(min==60){min=0;h++;if(h==24){h=0;}write_sfm(4,h);}write_sfm(7,min);}write_sfm(10,sec);}}。