单片机定时器设计报告.docx
《单片机定时器设计报告.docx》由会员分享,可在线阅读,更多相关《单片机定时器设计报告.docx(29页珍藏版)》请在冰豆网上搜索。
单片机定时器设计报告
第一章绪论
1.1系统背景
◆1.1.1单片机的介绍
单片微型计算机简称单片机,是典型的嵌入式微控制器,常用英文字母的缩写MCU表示单片机,它最早是被用在工业控制领域。
单片机由芯片内仅有CPU的专用处理器发展而来。
最早的设计理念是通过将大量外围设备和CPU集成在一个芯片中,使计算机系统更小,更容易集成进复杂的而对体积要求严格的控制设备当中。
INTEL的Z80是最早按照这种思想设计出的处理器,从此以后,单片机和专用处理器的发展便分道扬镳。
单片机又称单片微控制器,它不是完成某一个逻辑功能的芯片,而是把一个计算机系统集成到一个芯片上。
相当于一个微型的计算机,和计算机相比,单片机只缺少了I/O设备。
概括的讲:
一块芯片就成了一台计算机。
它的体积小、质量轻、价格便宜、为学习、应用和开发提供了便利条件。
同时,学习使用单片机是了解计算机原理及结构的最佳选择。
单片机是靠程序运行的,并且可以修改。
通过不同的程序实现不同的功能,尤其是特殊的独特的一些功能,这是别的器件需要费很大力气才能做到的,有些则是花大力气也很难做到的。
一个不是很复杂的功能要是用美国50年代开发的74系列,或者60年代的CD4000系列这些纯硬件来搞定的话,电路一定是一块大PCB板!
但是如果要是用美国70年代成功投放市场的系列单片机,结果就会有天壤之别!
只因为单片机的通过你编写的程序可以实现高智能,高效率,以及高可靠性!
◆1.1.2单片机的应用
目前单片机渗透到我们生活的各个领域,几乎很难找到哪个领域没有单片机的踪迹。
导弹的导航装置,飞机上各种仪表的控制,计算机的网络通讯及数据传输,工业自动化过程的实时控制和数据处理,广泛使用的各种智能IC卡,民用豪华轿车的安全保障系统,录像机、摄像机、全自动洗衣机的控制,以及程控玩具、电子宠物等等,这些都离不开单片机。
更不用说自动控制领域的机器人、智能仪表、医疗器械以及各种智能机械了。
因此,单片机的学习、开发及应用将造就一批计算机应用及智能化控制的科学家、工程师。
单片机广泛应用于仪器仪表、家用电器、医用设备、航空航天、专用设备的智能化管理及过程控制等领域
1.2多功能家用定时器
◆1.2.1多功能家用定时器的概述
人类最早使用的定时工具是沙漏或水漏,但在钟表诞生发展成熟之后,人们开始尝试使用这种全新的计时工具来改进定时器,达到准确控制时间的目的。
1876年,英国外科医生索加取得一项定时装置的专利,用来控制煤气街灯的开关。
它利用机械钟带动开关来控制煤气阀门。
定时器确实是一项了不起的发明,使相当多需要人控制时间的工作变得简单了许多,家用电器都安装了定时器来控制开关或工作时间。
◆1.2.2多功能家用定时器的功能及实现步骤
1.能够调整数字钟、定时开启、关闭时间的显示
当时间分别显示小时、分钟状态时,按11键,实现将当前显示的小时或分钟减1;按12键时,实现将当前显示的小时或分钟加1。
2.能过实现三路定时
通过按10键来选择显示的时间。
从而实现三路定时的开启及关闭,实现三路定时功能。
3.既能够实现按键输值,也可用加减键来对其调时
当在小时状态时,不管是在数字钟还是定时状态,都可以通过按键来对其调时,同时此时如果觉得时间按错还可以通过加减键进行调整时间。
4.能够时间倒计时的秒表功能
当一开始接通是,显示的是60秒倒计时功能,这一功能有助于对准确时间更好的把握。
5.能够显示今天心情
当在时钟状态时,按加减键,可显示出今天心情。
如果按减号键时,显示sad,并且LED灯全灭;如果按加号键时,显示fine,并且灯全亮。
第二章系统电路设计
2.1系统总体设计框架结构
总体结构图如下:
图2.1总体结构图
按键输入电路:
对定时器输入定时时间、时钟时间,并对其调整。
时钟电路:
给单片机一个时钟信号,让其工作。
复位电路:
使单片机为初始状态,并从初态开始工作。
LED显示电路:
表明定时器的工作状态。
数码管显示电路:
显示数字钟时间或定时时间或心情。
继电器电路:
是用较小的电流去控制较大电流的一种“自动开关”。
2.2系统硬件单元电路设计
◆2.2.1时钟电路设计
时钟电路对单片机是不可缺的,单片机的每个功能都要以时钟电路为基础工作。
单片机内部自带一个时钟电路,外部接入定时控制元件即可构成一个稳定的自激振荡器。
其中机器周期共有12个振荡脉冲周期,因此,机器周期是时钟周期的12倍。
本实验中时钟电路中使用的晶体是12MHz,则时钟周期为(1/12)us,机器周期为1us。
实验图如下:
时钟电路图:
图2.2时钟电路图
◆2.2.2复位电路设计
复位操作有上电自动复位、按键电平复位和外部脉冲复位三钟方式,本次实验用的是按键电平复位,利用电容的充放电公式来选择所需的电容、电阻,能保证复位信号高电平持续时间大于2个机器周期。
电路图如下:
复位电路图:
图2.2按键电平复位
◆2.2.3按键电路设计
本课题要用数码管显示数字钟、定时时间。
这就需要键盘来设定,键盘可以分为独立连接式和矩阵式。
本实验用的是矩阵式。
为了减少所以的I/O口,利用三——八译码器来实现12个键盘的连接。
对于这种矩阵式的键盘连接,扫描时依次将行线置为低电平,即在置某根行线为低电平时,其它都线为高电平。
在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。
若某列为低,则该列线及置为低电平的行线交叉处的按键就是闭合的按键。
注意在按键时一定要调延时子程序来消除抖动。
矩阵式键盘如下所示:
按键电路图:
图2.3按键电路
◆2.2.4LED显示电路设计
本次实验中要用发光二极管显示状态。
由下图知发光二极管阴极以经接地,当其阳极为高电平时,二极管就发光显示所处状态。
LED显示电路图:
图2.4LED显示电路图
◆2.2.5数码管显示电路设计
实验中所用的数码管为共阴极数码管,当给其引脚加入高电平时,数码管中对应的那一段就亮。
图2.6为外部显示图,其内部结构如下:
图2.5共阴极数码管内部结构
图2.6共阴极数码管显示
◆2.2.6继电器电路设计
继电器是一种电子控制器件,它具有控制系统(又称输入回路)和被控制系统(又称输出回路),通常应用于自动控制电路中,它实际上是用较小的电流去控制较大电流的一种“自动开关”。
故在电路中起着自动调节、安全保护、转换电路等作用。
图2.7继电器电路
2.3系统硬件总电路
总电路图由时钟电路、复位电路、继电器电路、键盘电路、LED显示电路、数码管显示电路组成来实现定时功能。
其中四个数码管为共阴极的数码管。
74LS138为3—8译码器,74LS07为输出缓冲器,74LS00为及非门,7805为三端稳压器,电容的作用基本都是滤波来减少噪声对实验的影响。
电路图如下:
图2.8总电路图
第三章系统软件设计
3.1系统软件流程图
◆3.1.1主程序流程图
主程序在执行时,通过单片机内部中断对程序不断的扫描判断、刷新显示,当有键按下时,将数字钟中的时间及定时时间相比较,然后根据比较程序显示状态,并且还要延时消除抖动,之后进行按键处理,从而显示不同的状态,如此周期循环。
◆3.1.2子程序流程图
1.延时子程序流程图
此延时子程序在实验中被主程序调用,当有按键按下时,调用此程序可以达到消除振动的作用,避免发光二极管一直闪烁,此程序延时时间不能太短,要不然不能很好的起到消振作用,也不能够太长,避免按键很长时间后才反应。
并且因为此程序用C语言编程,延时时间没有汇编语言精准。
2.比较子程序流程图
此程序通过将定时时间不断及数字钟时间相比较来表明定时器是否开启。
当LED7亮的时候表明定时开启;当LED7灭的时候表明定时关闭。
3.刷新缓冲子程序流程图
此程序为刷新缓冲区流程图,其中F为状态量,当F为不同的值时,数码管显示不同的状态,同时此程序不断的刷新来显示此状态下的数码管显示的值。
4.按键处理子程序流程图
此为按键处理子程序流程图,主程序在不停的扫描中,每当有按键按下时,就会根据状态量STATE的值跳转到此程序进行处理,此程序中还包含显示时所需的状态量的定义和加减键及键值的输入,按不同的键实现不同的功能。
5.LED显示子程序流程图
此为LED显示子程序流程图,显示当STATE这个状态量为不同的值时,表明不同的状态,而这种状态通过不同的的发光二极管显示出来。
这对于判断实验的正确性提供了不可缺少的帮助。
6.数码管显示子程序流程图
此为数码管显示的流程图,此程序及刷新缓冲区流程图相似,都及状态量F相关。
不同的的F值显示不同的状态所对应的数值。
◆3.1.3中断程序流程图
1.T0中断程序流程图
此图为T0中断程序流程图,用于计数器的计时,一直执行中。
当60秒到时,分加1,秒单元清零,当60分到时,时家1,分单元清零。
24时到时,时单元清零。
2.T1中断程序流程图
此为T1中断流程图,用于键值判断和中断扫描,它一直保持着扫描按键判断是否有键按下,然后让按键处理子程序能准确的进行执行。
3.2系统程序设计
◆3.2.1系统主程序
voidmain(void)
{P1=0x00;EA=1;//CPU允许中断
TMOD|=0x01;//定时器0计时50msin12Mcrystal定时器T0选择方式0工作
其前七位没影响,开始是什么还是什么,最后一位变成0=方式0
TH0=0x3C;TL0=0xB0;//初值001111001011000065535-15536=4999950ms
ET0=1;TR0=1;//开启T0
TMOD|=0x10;//定时器1用于动态扫描T1
TH1=0xFa;//初值65535-64240=12950.13ms
TL1=0xF0;
ET1=1;TR1=1;//开启T1
while
(1)
{RefreshTab();LED_Display();
if(!
L1||!
L0){compare();Delay(200);Key_Process();}//只要有键按下,就
}比较时间,延时后进行按键处理。
}
◆3.2.2定时中断子程序
/*定时器0用于数字钟的计时*/
voidTimer0(void)interrupt1
{
TH0=0x3C;TL0=0xB0;count++;//重新赋值50ms溢出
if(count==10)LED1=~LED1;//LED1半秒亮
if(count==20){count=0;second++;//秒加120*50=1S
if(second==60){second=0;minute++;//分加1
if(minute==60){minute=0;hour++;//时加1
if(hour==24){hour=0;}//小时到24时,清零
}
}
}
}
/*定时器1中断扫描显示+键值判断*/
voidTimer1(void)interrupt3
{
TH1=0xFa;TL1=0xF0;定时2ms显示下一个数码管
switch(num)
{case0:
P2=0x0f;if(!
L1)Keyno=1;if(!
L0)Keyno=10;SEG_Display();break;
//当num为0时,选择Y0,当按下L1时,键值时1;当按下L0时,键值是10,显示
case1:
P2=0x1f;if(!
L1)Keyno=4;if(!
L0)Keyno=7;SEG_Display();break;
//当num为0时,选择Y1,当按下L1时,键值时4;当按下L0时,键值是7,显示
case2:
P2=0x2f;if(!
L1)Keyno=3;if(!
L0)Keyno=12;SEG_Display();break;
//当num为0时,选择Y2,当按下L1时,键值时3;当按下L0时,键值是12,显示
case3:
P2=0x3f;if(!
L1)Keyno=5;if(!
L0)Keyno=8;SEG_Display();break;
//当num为0时,选择Y3,当按下L1时,键值时5;当按下L0时,键值是8,显示
case4:
P2=0x4f;if(!
L1)Keyno=2;if(!
L0)Keyno=11;SEG_Display();break;
//当num为0时,选择Y4,当按下L1时,键值时2;当按下L0时,键值是11,显示
case5:
P2=0x5f;if(!
L1)Keyno=6;if(!
L0)Keyno=9;SEG_Display();break;
//当num为0时,选择Y5,当按下L1时,键值时6;当按下L0时,键值是9,显示
default:
break;
}
num++;
if(num==6)num=0;//当num为6时清零
}
◆3.2.3时间比较子程序
voidcompare(void)
{
if(sg[0]==sg[4]&&sg[1]==sg[5]&&sg[2]==sg[6]&&sg[3]==sg[7]&&flog==1)LED7=1;
//当数字钟时间及一路定时的开启时间相同时,LED7亮
if(sg[0]==sg[8]&&sg[1]==sg[9]&&sg[2]==sg[10]&&sg[3]==sg[11]&&flog==1)LED7=0;
//当数字钟时间及一路定时的关闭时间相同时,LED7灭
if(sg[0]==sg[12]&&sg[1]==sg[13]&&sg[2]==sg[14]&&sg[3]==sg[15]&&flog==1)LED7=1;
//当数字钟时间及二路定时的开启时间相同时,LED7亮
if(sg[0]==sg[16]&&sg[1]==sg[17]&&sg[2]==sg[18]&&sg[3]==sg[19]&&flog==1)LED7=0;
//当数字钟时间及二路定时的关闭时间相同时,LED7灭
if(sg[0]==sg[20]&&sg[1]==sg[21]&&sg[2]==sg[22]&&sg[3]==sg[23]&&flog==1)LED7=1;
//当数字钟时间及三路定时的开启时间相同时,LED7亮
if(sg[0]==sg[24]&&sg[1]==sg[25]&&sg[2]==sg[26]&&sg[3]==sg[27]&&flog==1)LED7=0;
//当数字钟时间及三路定时的关闭时间相同时,LED7灭
}
◆3.2.4延时子程序
voidDelay(uintx)//自定义延时约0.1ms,大约为120*x
{uintt;while(--x)
for(t=0;t<120;t++)
;
}
◆3.2.5刷新缓冲区子程序
voidRefreshTab(void)
{if(F==-2){XQ[0]=Tab[kx[0]];XQ[1]=Tab[kx[1]];XQ[2]=Tab[kx[2]];XQ[3]=Tab[kx[3]];}
//当F=-2时,数码管刷新显示今天心情
if(F==-1){MB[0]=Tab[second/10];MB[1]=Tab[second%10];}
//当F=-1时,数码管刷新显示倒计时的秒表
if(F==0){TimeTab[0]=Tab[sg[0]];TimeTab[1]=Tab[sg[1]];
TimeTab[2]=Tab[sg[2]];TimeTab[3]=Tab[sg[3]];}
//当F=0时,数码管刷新显示数字钟时间
if(F==1){STab[0]=Tab[sg[4]];STab[1]=Tab[sg[5]];STab[2]=Tab[sg[6]];STab[3]=Tab[sg[7]];}
//当F=1时,数码管刷新显示一路定时开启时间
if(F==2){FTab[0]=Tab[sg[8]];FTab[1]=Tab[sg[9]];FTab[2]=Tab[sg[10]];FTab[3]=Tab[sg[11]];}
//当F=2时,数码管刷新显示一路定时关闭时间
if(F==3){STab1[0]=Tab[sg[12]];STab1[1]=Tab[sg[13]];
STab1[2]=Tab[sg[14]];STab1[3]=Tab[sg[15]];}
//当F=3时,数码管刷新显示二路定时开启时间
if(F==4){FTab1[0]=Tab[sg[16]];FTab1[1]=Tab[sg[17]];
FTab1[2]=Tab[sg[18]];FTab1[3]=Tab[sg[19]];}
//当F=4时,数码管刷新显示二路定时关闭时间
if(F==5){STab2[0]=Tab[sg[20]];STab2[1]=Tab[sg[21]];
STab2[2]=Tab[sg[22]];STab2[3]=Tab[sg[23]];}
//当F=5时,数码管刷新显示三路定时开启时间
if(F==6){FTab2[0]=Tab[sg[24]];FTab2[1]=Tab[sg[25]];
FTab2[2]=Tab[sg[26]];FTab2[3]=Tab[sg[27]];}
//当F=6时,数码管刷新显示三路定时关闭时间
}
◆3.2.6按键处理子程序
voidKey_Process(void)
//根据不同状态量STATE的值,在不同的状态按不同的键实现不同的功能,能够按键输值
时刻别忘时间显示的范围
{switch(STATE)
{case0:
if(Keyno==11){kx[0]=5;kx[1]=10;kx[2]=11;kx[3]=15;h=0;}
if(Keyno==12){kx[0]=12;kx[1]=1;kx[2]=13;kx[3]=14;h=1;}//心情状态
if(Keyno==10){STATE=2;F=0;}break;
case2:
if(Keyno<10){sg[n]=Keyno;n++;if(sg[0]>2||(sg[0]==2&&sg[1]>4))sg[0]=sg[1]=0;
if(sg[2]>5)sg[2]=sg[3]=0;if(n>3)n=4;}//用可以改变按键计数器初值
if(Keyno==11){sg[1]=sg[1]+1;if(sg[0]==2&&sg[1]==4)sg[0]=sg[1]=0;}//加1键if(Keyno==12){sg[1]=sg[1]-1;if(sg[0]!
=0&&sg[1]==-1){sg[0]=sg[0]-1;sg[1]=9;}
if(sg[0]==0&&sg[1]==-1){sg[0]=2;sg[1]=3;}}//减1键,时间设定范围
if(Keyno==10){STATE=3;}break;//
case3:
if(Keyno==11){sg[3]=sg[3]+1;if(sg[3]>9){sg[2]=sg[2]+1;sg[3]=0;}if(sg[2]==6)sg[2]=sg[3]0;}//加1键
if(Keyno==12){sg[3]=sg[3]-1;if(sg[2]!
=0&&sg[3]==-1){sg[2]=sg[2]-1;sg[3]=9;}
if(sg[2]==0&&sg[3]==-1){sg[2]=5;sg[3]=9;}}//减1键
if(Keyno==10){STATE=4;F=1;}break;
case4:
if(Keyno<10){sg[n]=Keyno;n++;if((sg[4]==2&&sg[5]>4))sg[4]=sg[5]=0;
if(sg[6]>5)sg[6]=sg[7]=0;if(n>7)n=8;}
if(Keyno==11){sg[5]=sg[5]+1;if(sg[5]==6)sg[4]=sg[5]=0;}if(Keyno==12){sg[5]=sg[5]-1;if(sg[4]!
=0&&sg[5]==-1){sg[4]=sg[4]-1;sg[5]=9;}
if(sg[4]==0&&sg[5]==-1){sg[4]=2;sg[5]=3;}}
if(Keyno==10){STATE=5;}flog=0;break;
case5:
if(Keyno==11){sg[7]=sg[7]+1;if(sg[7]>9){sg[6]=sg[6]+1;sg[7]=0;}if(sg[6]==6)sg[6]=sg[7]=0;}
if(Keyno==12){sg[7]=sg[7]-1;if(sg[6]!
=0&&sg[7]==-1){sg[6]=sg[6]-1;sg[7]=9;}
if(sg[6]==0&&sg[7]==-1){sg[6]=5;sg[7]=9;}}
if(Keyno==10){flog=1;STATE=6;F=2;}break;//
case6:
if(Keyno==10){STATE=7;}
if(Keyno<10){sg[n]=Keyno;n++;if((sg[8]==2&&sg[8]>4))sg[8]=sg[9]=0;
if(sg[10]>5)sg[10]=sg[11]=0;if(n>11)n=12;}
if(Keyno==11){sg[9]=sg[9]+1;if(sg[5]==6)sg[8]=sg[9]=0;}if(Keyno==12){sg[9]=sg[9]-1;if(sg[8]!
=0&&sg[9]==-1){sg[8]=sg[8]-1;sg[9]=9;}
if(sg[8]==0&&sg[8]==-1){sg[8]=2;sg[9]=3;}}flog=0;break;
case7:
if(Keyno==11){sg[11]=sg[11]+1;if(sg[11]>9){sg[10]=sg[10]+1;sg[11]=0;}if(sg[10]==6)sg[10]=sg[11]=0;}
if(Keyno==12){sg[11]=sg[11]-1;if(sg[10]!
=0&&sg[11]==-1){sg[10]=sg[10]-1;sg[11]=9;}
if(sg[10]==0&&sg[11]==-1){sg[10]=5;sg[11]=9;}}
if(Keyno==10){flog=1;STATE=8;F=3;}break;
case8:
if(Keyno<10){sg[n]=Keyno;n++;if(sg[12]>2||(sg[12]==2&&sg[13]>4))sg[12]=sg[13]=0;
if(sg[14]>5)sg[14]=sg[15]=0;if(n>15)n=16;}//用可以改变按键计数器初if(Keyno==11){sg[13]=sg[13]+1;if(sg[12]==2&&sg[13]==4)sg[12]=sg[13]=0;}