单片机原理及应用课程设计报告

更新时间:2023-08-12 21:05:01 阅读量: 初中教育 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

单片机原理及应用课程设计报告

《单片机原理及应用》

课程设计报告

目:

电子钟通信工程

专业名称:班学姓

级: 1班号: 710705135名:

周茂宁

2010年 6月10

单片机原理及应用课程设计报告

课程设计报告

1.基本内容

1.1课程设计的基本内容(包括设计目标):1.1.1实现可手动调整的时钟,闹钟功能1.1.2按键可长按,也可短按。1.1.3可指示工作模式

1.1.4可直观地区别,当前修改时分还是秒1.1.5具有整点提示功能1.1.6日误差<4S1.2基本的环境条件:

硬件:WAVE单片机仿真器、单片机实验板

软件:KEIL C51单片机仿真调试软件,伟福V系列仿真调试软件,PROTEUS单片机系统仿真软件

2.方案论证

2.1

方案比较:采用外部时钟信号较麻烦,需要外部时钟,因此采用内部时钟方式

图2-1内部时钟方式图2-2外部时钟方式

本设计是定时闹钟的设计,由单片机AT89C51芯片和LED数码管为核心,辅以必要的电路,构成的一个单片机电子定时闹钟。电子钟设计可采用数字电路实现,也可以采用单片机来完成。数字电子钟是用数字集成电路构成的,用数码管显示“时”,“分”,“秒”的现

代计时装置。若用数字电路完成,所设计的电路相当复杂,大概需要十几片数字集成块,其功

单片机原理及应用课程设计报告

能也主要依赖于数字电路的各功能模块的组合来实现,焊接的过程比较复杂,成本也非常高。若用单片机来设计制作完成,由于其功能的实现主要通过软件编程来完成,那么就降低了硬件电路的复杂性,而且其成本也有所降低,所以在该设计中采用单片机利用AT89C51,它是低功耗、高性能的CMOS型8位单片机。片内带有4KB的Flash存储器,且允许在系统内改写或用编程器编程。另外, AT89C51的指令系统和引脚与8051完全兼容,片内有128B的RAM、32条I/O口线、2个16位定时计数器、5个中断源、一个全双工串行口等。AT89C51单片机结合七段显示器设计的简易定时闹铃时钟,可以设置现在的时间及显示闹铃设置时间,若时间到则发出一阵声响,进—步可以扩充控制电器的启停。2.2设计原理

P0口输出显示码,P2口为位选端口,数码管用最简单的三极管驱动。用来显示时间。P1口作按键输入口,用二极管作为指示灯,蜂鸣器也采用三极管驱动。

利用中断进行计时,每次计时50ms,计20次达到1S,60秒为一分,60分为一小时,24小时为第二天0时。按键S13用来设定工作模式(设置闹钟、正常计时、修改时间)为了避免按键按下时数码管闪烁过于强烈,采用中断显示,这样就可以很稳定亮度的输出。为了利用P1口的二极管指示工作模式,将键盘的反转法改进。这样可以有三个二极管可以用来指示模式。当设置闹钟和修改时间时,当前正在修改的两个数码管较亮,其它4个较暗(如改小时,分和秒的显示较暗),更直观。当闹钟响的时候,若不取消响声,默认响30秒,要取中止响声,可按S15按键停止。当整点时,以“嘀”声提示。2.3硬件模块2.3.1各模块

电路图

图2-3-1扬声器模块图2-3-2

数码显示模块

单片机原理及应用课程设计报告

按键模块(如图

2-3-3,2-3-4)

图2-3-5按键模块图2-3-6按键指示灯模块

2.3.2

总电路图

图2-3-7

电子钟总电路图

图2-3-8正常计时模式(第5

个二极管亮)

单片机原理及应用课程设计报告

图2-3-9正常计时模式截图

3.软件流程图

图3-1主程序流程图

单片机原理及应用课程设计报告

4.设计过程

先明确要做的电子钟具有哪些功能,这些功能用单片机中的哪些资源来实现,画个大体流程图,先从简单的功能入手。首先编调试出计时的程序,即保证可以输出正常显示。刚开始是在主程序中用动态显示。

接着增加按键功能,让按键控制电子钟的停与计时。此时发现数码管的显示不稳定,当按键按下后显示明显闪烁强烈,考虑用中断来显示,即把显示程序,交给中断处理程序了。这时考虑到二极管指示模式,因此,将键盘反转法改进为只用5根线,即1行4个按键。于是二极管就剩下3个可以做为三种不同模式的指示灯。

再下来是增加修改时间程序模块,增加设置闹钟程序,这两个比较相似。为了能够比较直观地看出正在修改的是时还是分或秒。即不使数值变化可直接看出正在修改的位。修改过程中发现,需要修改的数离当前值相差较多时,修改很麻烦,因此设置了按键的长按功能。

最后添加整点报时,以及闹钟提示音。以及闹钟响时,切断响声设置。

实现可手动调整的时钟,包括闹钟功能(当时间超过10S左右还原到计时模式,以避免长时间未操作),时间可调,按键可长按,也可短按,4个按键(其中一个为功能键,一个为确定要修改的是小时,还是分钟,还是秒,另外两个按键1个加,1个减)8个二极管从左到右,第5个为计时模式指示灯,第6个为设置闹钟的模式指示灯,第7个为修改时间指示灯。不管是在闹钟设置模式还是修改时间模式,当修改小时数值时,分和秒的数码管较暗,以示区别,修改分钟或秒时,类似的。当闹钟响时,若无取消则响30s,按第15键可取消响声。

5.心得体会

这次课程设计真正地让我们走出了课堂里,只有我们听,老师讲课的情况。完完全全由自已组建起一个电子钟。课程设计根据设计要求,查找资料,然后按要求根据已学过的时钟程序编写定时闹钟的程序,依据程序利用proteus软件进行了仿真试验,对出现的问题进行分析和反复修改源程序,最终用硬件实验板进行调试修改,得到正确并符合要求的结果。这个设计将所学的知识很好地联系在一起。虽然本设计经过规划,但是还有不足的地方,如没有秒表功能,倒计时功能。可把T1中断显示放到T0中,再进行相应的修改,就可以空出T1用来倒计时或秒表功能使用,这时就不会与正常计时相干扰了。签于时间关系,以及所

用的知识是和上面的工作相同,因此就不做出具体实际程序了。

单片机原理及应用课程设计报告

附录程序:

/*说明:按键从左至右

按KEY 13 1次设定闹钏钟:

按KEY 14 1次设SECOND

单击15加1长按10倍单位时间加单击16减1长按10倍单位时间减

2次设MINUTE

单击15加1长按10倍单位时间加单击16减1长按10倍单位时间减

3次设HOUR

单击15加1长按10倍单位时间加单击16减1长按10倍单位时间减

按KEY 13 2次还原计时

按KEY 13 3次修改时间:可进入修改时间状态,否则10s后还原初始状态,

按KEY 14 1次设SECOND

单击15加1长按10倍单位时间加单击16减1长按10倍单位时间减

2次设MINUTE

单击15加1长按10倍单位时间加单击16减1长按10倍单位时间减

3次设HOUR

单击15加1长按10倍单位时间加单击16减1长按10倍单位时间减

按KEY 13 4次开始计时状态说明:改时间第 7个二极管亮改闹钟第 6个二极管亮正常计时第 5个二极管亮

可整点报时,闹钟(可手动设置)30s闹钟响时,可通过按第4排第3个键停即key15在设定闹钟状成态和修改时间状态,数码管相对较亮的两个表示现在可以调这两个位的数值*/

#include <reg51.h>

#define uchar unsigned char#define uint unsigned intsbit P1_4=P1^4;sbit P1_5=P1^5;sbit P1_6=P1^6;sbit P1_7=P1^7;sbit P2_0=P2^0;sbit P2_1=P2^1;sbit P2_2=P2^2;sbit P2_3=P2^3;sbit P2_4=P2^4;sbit P2_5=P2^5;uchar

table1[]={0x20,0x10,0x08,0x04,0x02,0x01};uchar table2[]={0x3f,0x06,0x5b,0x4f,0x66,

0x6d,0x7d,0x07,0x7f,0x6f};

//显示码

uchar table3[]={0,0,0,0,0,0};//用来显示的数

uchar setalarm[]={0,0,0,0,0,0};//用来存储闹钟时间的

uchartcount,tcount02s,tcount03;//tcount为正常计时中断次数,tcount02为30S闹钟响的时间变量,tcount03为当在改闹钟状态超过10s没有操作则自动返回到计时状态uchar

keycode1,keycode2,keycode3,keycode4,keytcount;//keycode1用来计键13按下的次数(在不同模式下切换),keycode2用来计键14的次数(在改时,改闹钟状态用来确定改变的是时或分或秒),keycode3用来加,keycode4用来减char

second,minute,hour,alarm_second,alarm_minute,alarm_hour;void delay(){

uint i;

//延时

单片机原理及应用课程设计报告

for(i=400;i>0;i--){}}

void delay10ms(void){

unsigned char i,u; for(i=20;i>0;i--) for(u=200;u>0;u--);}

void keycode(){

uchar key,i=0;int a=0;P1=0xff;P1_7=0;key=P1&0x0f;if(key!=0x0f){

delay10ms();key=P1&0x0f;if(key!=0x0f){

switch(key){

case 0x0e: keycode1++; break;//当为key13按下时,改变模式

case 0x0d: keycode2++; break;//当key14按下时,改变时或分或秒,由这个键来选择

case 0x0b: keycode3=1;break;//当为key15按下时,短按加1长按以10倍单位时间加

case 0x07: keycode4=1;break;//当为key16按下时,短按减1长按以10倍时间减}

key=key&0x0f;while(key!=0x0f){key=P1;key=key&0x0f;i++;if(i==250){i=0;a++;if(a==150)

{a=0;

keytcount++;if(keytcount==6){

keytcount=0;}}}}}}}

void set_alarm(){

if(keycode2==0){

P2_2=0;//用来区别是否在改的状态,让时分暗一些P2_3=0;P2_4=0;P2_5=0;

if(keycode3==1){

if(keytcount==0){

alarm_second++;}

alarm_second=alarm_second+keytcount*10;

//长按以10倍加keytcount=0;

if(alarm_second==60){

alarm_second=0;}

if(alarm_second>60)返回从个位开始{

alarm_second=alarm_second-60;}

keycode3=0;}

if(keycode4==1){

//减秒

//超过60

//单击以1倍加//加秒

//改秒

单片机原理及应用课程设计报告

if(keytcount==0){

alarm_second--; //单击以1倍减}

alarm_second=alarm_second-keytcount*10;

//长按以10倍减keytcount=0;

if(alarm_second==-1)回从59开始{

alarm_second=59;}

if(alarm_second<-1){

alarm_second=alarm_second+60;}

keycode4=0;}}

if(keycode2==1){P2_0=0;一些P2_1=0;P2_4=0;P2_5=0;

if(keycode3==1){

if(keytcount==0){

alarm_minute++;}

alarm_minute=alarm_minute+keytcount*10;keytcount=0;

if(alarm_minute==60){

alarm_minute=0;}

if(alarm_minute>60){

alarm_minute=alarm_minute-60;}

keycode3=0;}

//加分

//用来区别是否在改的状态,让时秒暗

//改分

//小于0返

if(keycode4==1){

if(keytcount==0){

alarm_minute--;}

//减分

alarm_minute=alarm_minute-keytcount*10;keytcount=0;

if(alarm_minute==-1){

alarm_minute=59;}

if(alarm_minute<-1){

alarm_minute=alarm_minute+60;}

keycode4=0;}}

if(keycode2==2){

P2_0=0;//用来区别是否在改的状态,让分秒暗一些P2_1=0;P2_2=0;P2_3=0;

if(keycode3==1){

if(keytcount==0){

alarm_hour++;}

alarm_hour=alarm_hour+keytcount*10;keytcount=0;if(alarm_hour==24){

alarm_hour=0;}

if(alarm_hour>24&&alarm_hour<44){

alarm_hour=alarm_hour-20;}

if(alarm_hour>=44)

{

//加时

//改时

单片机原理及应用课程设计报告

alarm_hour=alarm_hour-40;}

keycode3=0;}

if(keycode4==1)//减时

{

if(keytcount==0){

alarm_hour--;}

alarm_hour=alarm_hour-keytcount*10;keytcount=0;if(alarm_hour==-1){

alarm_hour=23;}

if(alarm_hour<-1&&alarm_hour>-24){

alarm_hour=alarm_hour+20;}

if(alarm_hour<=-24){

alarm_hour=alarm_hour+40;}

keycode4=0;}}

if(keycode2==3){

keycode2=0;}

table3[0]=table2[alarm_hour/10];

//把对应时分秒显示码赋给数组3table3[1]=table2[alarm_hour%10];table3[2]=table2[alarm_minute/10];table3[3]=table2[alarm_minute%10];table3[4]=table2[alarm_second/10];table3[5]=table2[alarm_second%10];}

void set_clock(){uchar i;TR0=0;

if(keycode2==0)

//改秒{

P2_2=0;//用来区别是否在改的状态,让时分暗一些P2_3=0;P2_4=0;P2_5=0;

if(keycode3==1)//加秒

{

if(keytcount==0)//单击以1倍加{

second++;}

second=second+keytcount*10;//长按以10

倍加

keytcount=0;if(second==60){

alarm_second=0;}

if(second>60)//超过60返回从个位

开始{

second=second-60;}

keycode3=0;}

if(keycode4==1)//减秒

{

if(keytcount==0){

second--; //单击以1倍减}

second=second-keytcount*10;//长按以10

倍减

keytcount=0;if(second==-1){

second=59;}

if(second<-1){

second=second+60;//小于0返回从

59开始

}

单片机原理及应用课程设计报告

keycode4=0;}}

if(keycode2==1){

P2_0=0;//用来区别是否在改的状态,让时秒暗一//改分

keycode4=0;}}

if(keycode2==2){

P2_0=0;//用来区别是否在改的状态,让分秒暗一//改时

些P2_1=0;P2_4=0;P2_5=0;

if(keycode3==1)//加分

{

if(keytcount==0){

minute++;}

minute=minute+keytcount*10;keytcount=0;if(minute==60){

minute=0;}

if(minute>60){

minute=minute-60;}

keycode3=0;}

if(keycode4==1)//减分{

if(keytcount==0){

minute--;}

minute=minute-keytcount*10;keytcount=0;if(minute==-1){

minute=59;}

if(minute<-1){

minute=minute+60;}

些P2_1=0;P2_2=0;P2_3=0;

for(i=6;i>0;i--){}

if(keycode3==1)//加时

{

if(keytcount==0){hour++;}

hour=hour+keytcount*10;keytcount=0;if(hour==24){hour=0;}

if(hour>24&&hour<44){

hour=hour-20;}

if(hour>=44){

hour=hour-40;}

keycode3=0;}

if(keycode4==1)//减时{

if(keytcount==0){hour--;}

hour=hour-keytcount*10;keytcount=0;

if(hour==-1)

单片机原理及应用课程设计报告

{hour=23;}

if(hour<-1&&hour>-24){

hour=hour+20;}

if(hour<=-24){

hour=hour+40;}

keycode4=0;}}

if(keycode2==3){

keycode2=0;}}

void time(){

if(tcount>=20){

second++;tcount=0;}

if(second>=60){

minute++;second=0;}

if(minute>=60){hour++;minute=0;}

if(hour>=24){hour=0;}}

void alarm(void){

static unsigned int flag,tcountn,fh;

//30s闹钟

{fh++;if(fh==1){RD=0;

//正常计时

//30s闹钟,可通过按第4排第3个键

if(second==alarm_second&&minute==alarm_minute&&hour==alarm_hour){flag=1;}

if(keycode3==1){flag=0;RD=1;}

if(flag==1){

if(tcount02s>=4){RD=~RD;tcount02s=0;tcountn++;}

if(tcountn>=150){RD=1;}}

if(second==0&&minute==0)

//整点报时

delay();delay();delay();delay();delay();delay();delay();delay();delay();RD=1;}}

if(second!=0)fh=0;}//主程数void main(){

TMOD=0X21;

//T0方式

1

单片机原理及应用课程设计报告

EA=1;ET0=1;ET1=1;TR1=1;

TH0=-46312/256;TL0=-46312%256;TH1=6;TL1=6;while(1){

keycode();

if(keycode1==1) //改闹钟时间{

P1_5=0;//第6个二极管作些状态指示灯P1_6=1;P1_4=1;TR0=1;set_alarm();time();}else{

if(keycode1==2){

P1_5=1;//第5个二极管作些状态指示灯P1_6=1;P1_4=0;TR0=1;time();alarm();

if(tcount03==200)改闹钟设置状态{

keycode1=4;}}

if(keycode1==3) //改时间{

P1_5=1;//第7个二极管作些状态指示灯P1_6=0;P1_4=1;set_clock();}

if(keycode1==4)

//还原计时//约10秒后,可以跳过

//还原计时

{

P1_5=1;//第5个二极管作些状态指示灯P1_6=1;P1_4=0;TR0=1;time();alarm();}

if(keycode1==5){

keycode1=1;}

table3[0]=table2[hour/10];应时分秒显示码赋给数组3table3[1]=table2[hour%10];table3[2]=table2[minute/10];table3[3]=table2[minute%10];table3[4]=table2[second/10];table3[5]=table2[second%10];}};}

void t0() interrupt 1{

tcount++;tcount02s++;tcount03++;间变量

TH0=-46312/256;TL0=-46312%256;}

void t1() interrupt 3{

static unsigned char tcount1,j;tcount1++;if(tcount1==15){

tcount1=0;j++;}

if(j==6)j=0;P0=table3[j];P2=table1[j];

} //时间累加并显示

//中断显示

//正常计时的时间变量//30闹钟响的时间变量

//跳过改时间状态的时

//50MS时间中断

//把对

//返回闹钟

本文来源:https://www.bwwdw.com/article/rvjj.html

Top