单片机电子钟设计课件_第1页
单片机电子钟设计课件_第2页
单片机电子钟设计课件_第3页
单片机电子钟设计课件_第4页
单片机电子钟设计课件_第5页
已阅读5页,还剩105页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

项目三电子钟的设计能力目标1、能够使用单片机的定时/计数器实现定时、计数等应用。2、能够完成电子钟硬件电路与控制程序的设计、制作与调试。知识目标1、了解单片机定时器/计数器的内部结构。2、掌握单片机定时器的各种工作方式及特点、应用场合。3、掌握定时器中断服务程序的编写。项目三电子钟的设计1任务一、认识单片机的定时器/计数器一、定时器/计数器及其应用在单片机应用系统中,定时或计数是必不可少的。例如:测量一个脉冲信号的频率、周期,或者统计一段时间里电机转动了多少圈等。常用的定时方法有:1、软件定时软件定时是依靠执行一段程序来实现的,这段程序本身没有具体的意义,通过选择恰当的指令及循环次数实现所需的定时,由于执行每条指令都需一定的时间,执行这段程序所需总的时间就是定时时间。软件定时的特点是无需硬件电路,但定时期间CPU被占用,增加了CPU的开销,因此定时时间不宜过长,而且定时期间如果发生中断,定时时间就会出现误差。任务一、认识单片机的定时器/计数器一、定时器/计数器及其应用23、可编程定时器定时这种定时方法是通过对系统时钟脉冲的计数来实现的。通过程序来设置计数初值,改变计数初值也就改变了定时时间,使用起来非常灵活。由于定时器可以与CPU并行工作,因此不影响CPU的效率,且定时时间精确。2、硬件定时

硬件定时通常由小规模集成电路555外加电阻、电容构成,电路简单,不占CPU资源,但定时时间的调节不够灵活方便。单片机电子钟设计课件3(一)定时器/计数器概述在51系列单片机中有两个16位的加法计数器,分别叫做T0和T1。在计数脉冲的作用下,其计数值不断加1,在此过程中,计数器可能产生溢出,产生溢出后,可以向CPU发出中断请求。如果计数脉冲来自系统时钟,称之为“定时器”,每个机器周期计数器加1;如果计数脉冲来自外部电路,称之为“计数器”一旦计数器产生溢出,TF0变为1,向CPU发出中断请求(一)定时器/计数器概述如果计数脉冲来自系统时钟,称之为“定4二、定时器/计数器的控制寄存器

1、定时器控制寄存器TCONTF0/TF1:定时器/计数器T1和T0的溢出中断标志。为1,表示定时器/计数器的计数值已由全1变为全0,正向CPU发中断请求。TR0/TR1:定时器/计数器T0和T1的启停控制位:为0时,定时器/计数器停止工作;为1时,启动定时器/计数器工作。

二、定时器/计数器的控制寄存器

1、定时器控制寄存器TCON52、定时方式寄存器TMOD

选择定时/计数器的工作方式,M1M0=00,方式001,方式110,方式211,方式3定时方式/计数方式的选择控制位。为0,选定时方式,计数脉冲来自系统时钟的12分频;为1,选计数方式,计数脉冲来自外部电路当GATE=0时,只要TR0=1,与门的输出就为1,计数开始。如果GATE为1,只有TR0=1,并且/INT0=1时,才允许计数。2、定时方式寄存器TMOD选择定时/计数器的工作方式,M16C/T=0,选择定时方式C/T=1,选择计数方式GATE=0时,由TR0控制计数器启停GATE=1时,由TR0和INT0一同控制启停TR0=1时,启动定时器定时器溢出时,TF0置1C/T=0,选择定时方式C/T=1,选择计数方式GATE=07三、T0、T1的工作方式1、方式0方式0的计数器由13位构成,其中高8位在TH中,低5位在TL中。当计数器产生溢出时,TF位被置1,向CPU发出中断请求。在方式0下,计数器产生溢出时,不能进行初始计数值的自动重装(有关自动重装的问题参见方式2),所以方式0不能用于精确定时。方式0的所有功能都可以用方式1代替,方式0的存在,是因为兼容早期的MCS-48单片机的原因,所以一般不使用方式0。三、T0、T1的工作方式1、方式082、方式1方式1与方式0工作形态基本相同,只是方式1的计数器由16位构成,其中高8位在TH中,低8位在TL中,当计数器产生溢出时,TF位被置1,向CPU发出中断请求。在方式1下,计数器产生溢出时,也不能进行初始计数值的自动重装所以方式1也不能用于精确定时。2、方式193、方式2方式2是可以自动重装的工作方式:初始化时一般将8位计数初值同时放入TH、TL中,其中,TH存放的是初值的备份,TL用来计数,当8位计数器TL产生溢出时,除了可以向CPU发中断请求外,单片机的硬件部分还立即把TH中的备份送入TL中。由于重新赋值是硬件自动进行的,所以避免了重新赋值的时间不一,所以方式2可以用于精确定时。3、方式2104、方式3

T1经常用于串行口的波特率发生器,为了让系统中保持两个计数器,可以让T0工作在方式3,这时,T0被分成两个8位计数器,分别位于TH0和TL0中,其中TL0使用T0的中断、启动控制资源,而TH0则借用T1的中断、启动控制资源,而且TH0只能工作在定时方式下,不能工作在计数方式下。4、方式311(四)时间常数的计算如果单片机需要进行周期性的工作,就应该让定时器/计数器T0或T1工作在定时方式,并且给T0或T1赋以一个初始计数值,在T0或T1被启动后,每个机器周期使计数器中的计数值加1,计数器产生溢出后,将再次给计数器赋值(该值被称为时间常数)。显然计数器溢出时间(又称定时时间)与时间常数直接相关:时间常数越大,定时时间就越短;时间常数越小,定时时间就越长。同时系统时钟的频率也直接影响定时时间的长短,时钟的频率越高,定时时间越短;时钟的频率越低,定时时间越长。(四)时间常数的计算12设系统时钟的频率为fosc,计数器的初始值为N,定时器工作于方式1,则定时时间:

T=(216-N)×12/fosc(1)如果定时器工作于方式2或方式3,定时时间为:

T=(28-N)×12/fosc(2)

当初始值N=0时,如果fosc=12MHZ,最大定时时间为:方式1为:Tmax=216×12/fosc=65536us=65.536ms方式2、方式3为:Tmax=28×12/fosc=256us根据定时时间T,及公式(1)、(2)分别可以求出初值N为:方式1:N=216-T×fosc/12(3)方式2、方式3:N=28-T×fosc/12(4)如果fosc=12MHZ,以上公式可简化为方式1:N=216-T

方式2、方式3:N=28-T设系统时钟的频率为fosc,计数器的初始值为N,13

例如:系统的时钟频率是12MHz,在方式1下,如果希望定时器/计数器T0的定时时间T为10ms,则初值N=216-T=65536-10000=55536如何将55536给两个8位寄存器TH0、TL0赋值呢?可将十进制数55536转换成四位十六进制数,将高2位送TH0,低2位送TL0。更简单的方法是:对于16位计数器来讲,216等效为0,对于8位计数器,28等效为0,这样公式(3)、(4)可简化为N=-T,直接用下面两条语句就可以完成计数器初值的设置:TH0=-10000/256;//取-N的高8位TL0=-10000%256;//取-N的低8位

例如:设系统的时钟频率是12MHz,定时器工作于方式2,定时时间200us。根据前面分析,N=-T=-200,可直接用以下语句实现:TH0=-200;TL0=-200;例如:系统的时钟频率是12MHz,在方式1下,如14任务二、定时器应用[案例1]设时钟频率fosc=12MHz,用定时器T0在P1.0脚产生频率为20Hz的方波。

设计思想:在使用定时器/计数器时,首先应根据要求对工作方式进行初始化,然后计算出初始值。初始化的步骤通常是:

(1)向TMOD寄存器写入工作方式控制字。

(2)将计数器的初值写入TH0、TL0/TH1、TL1。

(3)启动定时器/计数器:将TR0/TR1置1。(4)如果采用中断方式,还应将ET0/ET1、EA置1。

任务二、定时器应用[案例1]设时钟频率fosc=15本题中,方波的频率为20HZ,对应的周期为50ms,如果将定时时间设置为25ms,每隔25ms将P1.0脚取反即可产生如图3-3所示的方波。因为定时时间为25ms,如果采用方式2或方式3,其定时的最大时间不超过256us,因此选方式1比较恰当,根据前面的分析,计数器初值N=-25000。本例题是定时而非计数,且无需脚参与启停控制,故C/=0,GATE为0,这样TMOD取0x01。本题中,方波的频率为20HZ,对应的周期为50m16voidmain(void){TMOD=0x01; TH0=-25000/256; TL0=-25000%256;TR0=1; ET0=1; EA=1; while(1);}voidtimer0(void)interrupt1{TH0=-25000/256; TL0=-25000%256;P10=~P10;}T0工作于定时方式1定时时间为25ms启动定时器T0允许定时器T0中断单片机开中断定时器T0中断服务程序重新装入时间常数P1.0求反voidmain(void)T0工作于定时方式1定时时间为17[案例2]如图所示,P0口接8只发光二极管,编程使发光管轮流点亮,点亮时间为500ms,要求使用定时器T0来控制,设晶振为12MHz[案例2]如图所示,P0口接8只发光二极管,编程使发18

设计思想

我们可将P0口的初值设置为0xFE,对应于发光管D1亮,每隔500ms将P0的值循环左移一位,这一周期性的定时作业用T0来完成。当时钟频率为12MHZ时,在定时器的4种工作方式中,方式1的最大溢出时间最长,但即使在方式1,最大的溢出时间也只有65.536ms,所以我们不能在每次中断时都执行上述移位操作,可以这样处理:将定时器T0的溢出时间设定为50ms,累计满10次中断正好500ms,才允许程序执行1次移位动作,设计思想19

主函数ucharcount=0;//50ms定时中断次数计数器voidmain(void){led=0xfe;TMOD=0x01;//T0工作于方式1TH0=-50000/256;//定时时间为50msTL0=-50000%256;ET0=1;//允许T0中断TR0=1;//启动T0定时EA=1;//CPU开中断while(1);}主函数20voidtime0(void)interrupt1{TH0=-50000/256;TL0=-50000%256;count++;if(count==10){count=0;led=_crol_(led,1);P0=led;}}定时器T0中断服务程序重新装入时间常数每中断一次,计数器加110次中断为0.5秒满10次变量led左移1位送P0口voidtime0(void)interrupt1定21[案例3]用定时器的计数方式实现外部中断。如图所示,P0口控制8只发光管轮流点亮,发光管点亮时间为500ms,单脉冲电路控制发光管的移动方向,按下单脉冲按钮,发光管左移,再按下发光管右移。[案例3]用定时器的计数方式实现外部中断。如图所示,22设计思想:当定时器/计数器工作于计数方式2时,如果将计数器的初值设置为全1,只要在计数输入端(T0或T1)送入一个计数脉冲,就可使计数器产生溢出中断。如果将外部中断请求作为计数脉冲输入,就可利用计数中断的名义去完成外部中断服务。当应用中外部中断请求较多时,而单片机内部的定时器/计数器还有富余时,可采用这种方法来扩展外部断。因此本例的实质是将定时器的计数输入端T1扩展为外部中断请求输入,来控制发光管的移动方向。

设计思想:23具体方法:

1、初始化定时器/计数器T1计数工作方式2,即每次溢出中断后能自动装入计数初值。2、计数器TH1、TL1的初值预置为0FFH。3、程序中设置一个位变量,每当计数器T1产生溢出中断时求反,发光管左移还是右移取决于该变量是0还是1。具体方法:1、初始化定时器/计数器T1计数24

voidmain(void){DIR=0;led=0xfe;TMOD=0x61;TH0=-50000/256;TL0=-50000%256;TH1=0xff; TL1=0xff;ET0=1;ET1=1; TR0=1;TR1=1; EA=1;while(1);}T0为定时方式0,T1为计数方式2定时时间为50msT1的初值为0xff允许T0、T1中断启动T0定时启动T1计数CPU开中断voidmain(void)T0为定时方式0,T1为计数25

voidtime0(void)interrupt1{TH0=-50000/256;TL0=-50000%256;count++;if(count==10){count=0; if(DIR==1) led=_crol_(led,1); else led=_cror_(led,1); P0=led;}}重新装入时间常数满10次为0.5秒计数器清0DIR为1左移DIR为0右移每中断一次,计数器加1定时器T0中断服务程序voidtime0(void)interrupt126

voidtime1(void)interrupt3{DIR=~DIR; }每次按下按钮产生T1的溢出中断,将DIR求反定时器T1中断服务程序voidtime1(void)interrupt327[案例4]用定时器来控制数码管的动态显示。设计思想:

前面我们介绍LED动态显示程序时,每一位点亮后都需延时1ms左右,由于使用的是软件延时,大大降低了CPU的效率,而且当CPU因处理某件事务在一段时间内无法调用显示程序时,LED显示器将会出现黑屏或产生闪烁现象。用定时器控制数码管的动态显示的方法:设定时器的定时时间为1ms,每次产生溢出中断,就根据位选变量bsel(主程序中将其初值设置为0xfe)送位选口,点亮一位数码管,并将bsel左移一位,为下一位的显示做好准备,4次定时中断分别完成4位数码管的显示,之后将bsel的值再次初始化为0xfe,准备下一轮显示。

因此这种显示方式由定时中断自动完成,无需在主程序中调用。[案例4]用定时器来控制数码管的动态显示。28主程序ucharbsel,n;voidmain(void){n=0;bsel=0xfe;//首先显示数码管的最低位TMOD=0x01;//T0工作于定时方式2TH0=-1000/256;//T0的定时时间为1000usTL0=-1000%256;ET0=1;//允许T0中断TR0=1;//启动定时EA=1;//开中断while(1);}主程序29voidtime0(void)interrupt1{TH0=-1000/256;TL0=-1000%256;P0=0xff;P2=bsel;P0=segtab[dbuf[n]];bsel=_crol_(bsel,1);n++; if(n==4) {n=0; bsel=0xfe; }}重新装入时间常数定时器T0中断服务程序熄灭数码管,防止上一位字符在当前位置显示出来。点亮当前位根据显示缓存查字段码准备显示下一位指向下一位要显示的数据如果四位已显示完,重新从最低位开始voidtime0(void)interrupt130[案例5]如图3-8所示,设计一个电子秒表,每隔一秒加1,用三位数码管显示秒表的当前值(0-255),单脉冲按键用于启动、停止、清0控制,第一次按下该按键时启动秒表,第二次按键将暂停秒表,第三次按键将秒表清0,设置晶振频率为12MHZ。[案例5]如图3-8所示,设计一个电子秒表,每31设计思想:我们可用一个变量记录秒表的当前值,为了提高秒表精度,我们可令定时器T0工作于定时方式2,定时时间为250us,4000次溢出中断正好满1秒,让变量加1,同时将该变量转换为三位BCD码送到显示缓存,供显示程序显示。单脉冲直接和外部中断0的输入端INT0相连,每次按键产生中断请求,程序中设置一个变量,对按键动作进行计数,取值为1-3,分别对应于启动、停止和清0,程序根据该变量的值进行相应的控制。设计思想:32主程序voidmain(void){count=0;sec=0;mode=0;IT0=1; //外部中断负跳变触发EX0=1;//允许外部中断0中断TMOD=0x02;//T0工作于定时方式2TH0=-250;//T0的定时时间为250usTL0=-250;ET0=1;//允许T0中断TR0=0;//停止定时器EA=1;//开中断while(1)disp();}主程序33定时器T0中断服务程序voidtime0(void)interrupt1{count++;//中断次数加1if(count==4000){count=0; sec++; dbuf[2]=sec/100;//将秒数计换成三位BCD码dbuf[1]=(sec%100)/10;dbuf[0]=sec%10;}}定时器T0中断服务程序34voidint0(void)interrupt0{mode++; //每次产生中断,mode加1if(mode==1) //mode为1,启动定时器工作TR0=1;elseif(mode==2)//如果mode等于2,停止定时器工作TR0=0;elseif(mode==3)//如果mode为3,{mode=0;TR0=0;sec=0; //将秒计数器清0 dbuf[0]=0;dbuf[1]=0; dbuf[2]=0; } }外部中断0中断服务程序voidint0(void)interrupt0外部35[案例6]用单片机演奏歌曲《兰花草》

设计思想:单片机可以根据音符产生不同频率的脉冲信号,经驱动后来控制蜂鸣器,让蜂鸣器产生与音符相应的声音,再把它们有机地组合起来,就可以发出一段音乐。[案例6]用单片机演奏歌曲《兰花草》设计思想:单36

1、要产生与某音符相应的脉冲信号,只要算出该音频的频率和周期,然后将该周期除2,即为半周期的时间。将定时器的定时时间设定为这半周期时间,一旦定时器溢出,就将P1.6脚求反,这样就能产生与音符频率对应的脉冲信号。设单片机定时器工作在定时方式1,改变时间常数TH0、TL0就可以产生与各种音符频率相应的脉冲信号。

设要产生的频率为fr,单片机机器周期的频率为fi,则对应定时器时间常数为N。N=65536-fi÷2÷fr1、要产生与某音符相应的脉冲信号,只要算出该音37

2、用单片机演奏音乐时,可以这样来表示乐谱:乐谱由多个简谱码组成,以00结束,每个简谱码用一个字节来表示,字节的高4位为音符码,代表音符的高低,低4位为节拍码,表示音符的节拍,下表3-2为节拍与节拍码的对照。如果1拍为0.4秒,则1/4拍为0.1秒,2/4拍为0.2秒,所以只要根据节拍来设定延时时间。设定时器T1的定时时间为50ms,二次溢出中断正好为1/4拍,将节拍码乘2即为该节拍所需溢出中断的次数。2、用单片机演奏音乐时,可以这样来表示乐谱:38

程序中,定时器T0用于控制音调的高低,定时器T1用于控制节拍的长短,各音符对应的时间常数放在数组tab1中,乐谱以简谱码的形式存储在数组tab3中,高四位为音符码,低四位为节拍码,0x00表示乐谱结束。变量m指向tab3中当前需演奏的简谱码,从中分解出高四位的音符码,并从tab1中取出时间常数控制定时器T0产生与音符频率相应的方波;从简谱码的低四位分解出节拍码,控制定时器T1延时节拍所需的时间。程序中,定时器T0用于控制音调的高低,定39程序流程图程序流程图40voidmain(void){ucharm;//用于指向音符的下标变量ucharc;TMOD=0x11;//定时器设定为方式1ET0=1;//允许T0中断ET1=1;//允许T1中断TH1=-50000/256;//50ms定时,节拍长短控制TL1=-50000%256;TR1=1;EA=1;}voidmain(void)41

while(1){m=0; //指向音符的下标变量while(tab3[m]) //如果乐谱末结束{c=tab3[m]>>4; //取高四位的音符if(c!=0) //音符不为0{th=tab1[c-1]>>8;//根据音符取出时间常数tl=tab1[c-1]&0xff;TH0=th;TL0=tl;//重新设置时间常数 TR0=1;} //启动定时器,开启中断else{TR0=0;} //如果音符为0,不发声,time=(tab3[m]&0x0f)*2;//确定延时时间 while(time!=0);//延时规定节拍m++; //指向下个音符}

TR0=0;//暂停5S后,重新开始time=100;while(time!=0);}

while(1)TR0=0;42voidtimer0(void)interrupt1using1{TH0=th;//装入时间常数TL0=tl;SOUND=~SOUND;//产生方波}voidtimer1(void)interrupt3{TH1=-50000/256;//重新装入50ms的时间常数TL1=-50000%256;time--;//溢出中断次数减1}定时器T0中断服务程序,用于产生产生与音符频率相应的方波定时器T1中断服务程序,延时当前节拍所需的时间voidtimer0(void)interrupt143

[案例7]调节发光二极管的亮度。亮度分为0-7共8级,亮度等级为0时,发光管熄灭;亮度等级为7时,发光管最亮。用KINC、KDEC两个按键调节当前的亮度。

设计思想:如图所示,如果在P0.0引脚产生一个周期为2ms的脉冲,如果每个周期内脉冲的低电平时间少,高电平时间长,发光管的亮度显然暗些,反之发光管要亮些,当P0.0输出全为高,发光管就熄灭了。因此只要调节脉冲低电平的时间就可改变发光管的亮度。[案例7]调节发光二极管的亮度。亮度分为0-7共44程序中变量light表示亮度等级,取值在0-7之间,用KINC、KDEC按键对其加减调整,当light为0时,P0.0始终输出高电平。定时器T0的定时时间为250us,变量count对定时中断进行计数,取值也在0-7之间,当count<light时,是发光管点亮时间,P0.0输出低电平;当count≥light时,P0.0输出高电平,发光管熄灭。发光管熄灭发光管亮度最低发光管亮度最高程序中变量light表示亮度等级,取值在0-745voidmain(void){TMOD=0x02;//T0工作于方式2TH0=-250;TL0=-250;;//定时时间为250usET0=1;//允许T0中断TR0=1;//启动定时EA=1;//CPU开中断while(1){while((P2&0x30)==0x30);//等待按键delay(10);//去抖动延时if(KINC==0)//是KINC键,亮度等级加1light=(ligh+1)&0x7;elseif(KDEC==0)//是KDEC键,亮度等级减1light=(ligh-1)&0x7;while((P2&0x30)!=0x30);//等待按键释放delay(10);//去抖动}voidmain(void)46voidtime0(void)interrupt1{count++;//定时中断计数器加1count=count&0x7;//计数器的值在0~0x07之间if(count<light)//如果计数器的值小于当前亮度等级 LED=0;//点亮LEDelse LED=1;//否则,关闭发光管}定时器T0中断服务程序voidtime0(void)interrupt1定47任务四、电子钟的设计

设计一个电子钟,用四位LED显示器显示当前时、分,时、分之间用闪烁的‘.’分隔,按KSET键设置当前时间,长按KSET键设置闹铃时间,进入设置方式后,用KSET键来选择对时、分进行修改,当前修改的对象闪烁,KINC、KDEC分别对修改对象加/减1,长按KSET键结束设置。如果当前时间与闹铃时间一致,蜂鸣器发出“嘟”、“嘟”的闹铃声,LED显示器闪烁,闹铃时按任意一键,关闭蜂鸣器。任务四、电子钟的设计设计一个电子钟,用四位LE48设计思想

根据设计要求,我们可以将电子钟分为三种工作状态,用变量state表示:

正常走时状态LED显示器显示当前时间,系统上电后自动进入该方式。

闹铃状态如果当前时、分与闹铃时、分相同,进入闹铃状态,此时蜂鸣器发出“嘟”、“嘟”的闹铃声,LED显示器闪烁,闹铃时按任意一键,关闭蜂鸣器,LED显示器停止闪烁,返回正常走时状态。设置状态在走时状态用户按下kSET键则进入设置状态,用户通过KINC、KDEC键对当前时间或闹铃时间进行修改,最后长按KSET键退出设置状态,并返回到正常走时方式。在设置当前时间时应将定时器关闭,否则LED显示器上的显示值将被定时中断服务程序刷新;在设置闹铃时间时,当前时间仍需被定时中断服务程序刷新,只是不在LED显示器上显示出来。设计思想

正常走时状态

闹铃状态设置状态49

定时器T0用来产生时钟和方波,程序中每隔250uS就产生一次定时中断,4000次中断正好满1秒。定时器T0每两次中断(500us)就令计数变量n加1,n满2000正好是1S,当n<500时,每500us就将P1.0求反一次,产生250个频率为1KHZ的方波,控制蜂鸣器鸣叫,当n>500后,令P1.0保持高电平,鸣叫停止,这样在1秒钟内“嘟”持续1/4秒,停顿3/4秒,整个闹铃状态将产生60次“嘟”,除非用户按键关闭蜂鸣器。定时器T0用来产生时钟和方波,50单片机电子钟设计课件51单片机电子钟设计课件52调试方法与步骤1、仔细检查硬件电路,确认硬件连接无误后,开始软件调试。2、在Keil下新建项目,选择硬件仿真,设置好串口号及波特率,输入源程序,编译成功后进入调试状态。3、全速运行程序,此时数码管应显示初始时间“12.25”,如果没有显示,应检查电路中的显示端口与程序中的定义是否一致,显示程序是否有问题。

4、按下(或长按)KSET键,显示器的高2位应该闪烁,如果按键后无反应,应重点检查键盘电路的连接以及键盘程序getkey(),直到按下各键时,能得到对应的键值返回。调试方法与步骤1、仔细检查硬件电路,确认硬件连接无误后,开始535、如果按下(或长按)KSET键后,程序能够进入当前时间或闹铃时间设置方式,应仔细检查KSET、KINC、KDEC键的功能是否与设计要求一致,最后长按KSET键能否退出设置方式。如果有问题,应进入set_time()仔细调试。6、显示程序、键盘处理程序调试好后,全速运行程序,此时数码管显示的时间应每分钟更新一次,如果时间始终不变,可检查程序是否能进入定时器中断服务程序,如果不能,说明定时器及中断的初始化可能有问题,否则可进一步观察当前时间time[3]及update标志是否相应变化。5、如果按下(或长按)KSET键后,程序能够进入当前时间或闹547、如果能够正常走时,需进一步检测到了闹铃时间,数码管是否闪烁,蜂鸣器有无鸣叫,以及鸣叫时按键能否关闭声音。7、如果能够正常走时,需进一步检测到了闹铃时间,数码管是否闪55项目三电子钟的设计能力目标1、能够使用单片机的定时/计数器实现定时、计数等应用。2、能够完成电子钟硬件电路与控制程序的设计、制作与调试。知识目标1、了解单片机定时器/计数器的内部结构。2、掌握单片机定时器的各种工作方式及特点、应用场合。3、掌握定时器中断服务程序的编写。项目三电子钟的设计56任务一、认识单片机的定时器/计数器一、定时器/计数器及其应用在单片机应用系统中,定时或计数是必不可少的。例如:测量一个脉冲信号的频率、周期,或者统计一段时间里电机转动了多少圈等。常用的定时方法有:1、软件定时软件定时是依靠执行一段程序来实现的,这段程序本身没有具体的意义,通过选择恰当的指令及循环次数实现所需的定时,由于执行每条指令都需一定的时间,执行这段程序所需总的时间就是定时时间。软件定时的特点是无需硬件电路,但定时期间CPU被占用,增加了CPU的开销,因此定时时间不宜过长,而且定时期间如果发生中断,定时时间就会出现误差。任务一、认识单片机的定时器/计数器一、定时器/计数器及其应用573、可编程定时器定时这种定时方法是通过对系统时钟脉冲的计数来实现的。通过程序来设置计数初值,改变计数初值也就改变了定时时间,使用起来非常灵活。由于定时器可以与CPU并行工作,因此不影响CPU的效率,且定时时间精确。2、硬件定时

硬件定时通常由小规模集成电路555外加电阻、电容构成,电路简单,不占CPU资源,但定时时间的调节不够灵活方便。单片机电子钟设计课件58(一)定时器/计数器概述在51系列单片机中有两个16位的加法计数器,分别叫做T0和T1。在计数脉冲的作用下,其计数值不断加1,在此过程中,计数器可能产生溢出,产生溢出后,可以向CPU发出中断请求。如果计数脉冲来自系统时钟,称之为“定时器”,每个机器周期计数器加1;如果计数脉冲来自外部电路,称之为“计数器”一旦计数器产生溢出,TF0变为1,向CPU发出中断请求(一)定时器/计数器概述如果计数脉冲来自系统时钟,称之为“定59二、定时器/计数器的控制寄存器

1、定时器控制寄存器TCONTF0/TF1:定时器/计数器T1和T0的溢出中断标志。为1,表示定时器/计数器的计数值已由全1变为全0,正向CPU发中断请求。TR0/TR1:定时器/计数器T0和T1的启停控制位:为0时,定时器/计数器停止工作;为1时,启动定时器/计数器工作。

二、定时器/计数器的控制寄存器

1、定时器控制寄存器TCON602、定时方式寄存器TMOD

选择定时/计数器的工作方式,M1M0=00,方式001,方式110,方式211,方式3定时方式/计数方式的选择控制位。为0,选定时方式,计数脉冲来自系统时钟的12分频;为1,选计数方式,计数脉冲来自外部电路当GATE=0时,只要TR0=1,与门的输出就为1,计数开始。如果GATE为1,只有TR0=1,并且/INT0=1时,才允许计数。2、定时方式寄存器TMOD选择定时/计数器的工作方式,M161C/T=0,选择定时方式C/T=1,选择计数方式GATE=0时,由TR0控制计数器启停GATE=1时,由TR0和INT0一同控制启停TR0=1时,启动定时器定时器溢出时,TF0置1C/T=0,选择定时方式C/T=1,选择计数方式GATE=062三、T0、T1的工作方式1、方式0方式0的计数器由13位构成,其中高8位在TH中,低5位在TL中。当计数器产生溢出时,TF位被置1,向CPU发出中断请求。在方式0下,计数器产生溢出时,不能进行初始计数值的自动重装(有关自动重装的问题参见方式2),所以方式0不能用于精确定时。方式0的所有功能都可以用方式1代替,方式0的存在,是因为兼容早期的MCS-48单片机的原因,所以一般不使用方式0。三、T0、T1的工作方式1、方式0632、方式1方式1与方式0工作形态基本相同,只是方式1的计数器由16位构成,其中高8位在TH中,低8位在TL中,当计数器产生溢出时,TF位被置1,向CPU发出中断请求。在方式1下,计数器产生溢出时,也不能进行初始计数值的自动重装所以方式1也不能用于精确定时。2、方式1643、方式2方式2是可以自动重装的工作方式:初始化时一般将8位计数初值同时放入TH、TL中,其中,TH存放的是初值的备份,TL用来计数,当8位计数器TL产生溢出时,除了可以向CPU发中断请求外,单片机的硬件部分还立即把TH中的备份送入TL中。由于重新赋值是硬件自动进行的,所以避免了重新赋值的时间不一,所以方式2可以用于精确定时。3、方式2654、方式3

T1经常用于串行口的波特率发生器,为了让系统中保持两个计数器,可以让T0工作在方式3,这时,T0被分成两个8位计数器,分别位于TH0和TL0中,其中TL0使用T0的中断、启动控制资源,而TH0则借用T1的中断、启动控制资源,而且TH0只能工作在定时方式下,不能工作在计数方式下。4、方式366(四)时间常数的计算如果单片机需要进行周期性的工作,就应该让定时器/计数器T0或T1工作在定时方式,并且给T0或T1赋以一个初始计数值,在T0或T1被启动后,每个机器周期使计数器中的计数值加1,计数器产生溢出后,将再次给计数器赋值(该值被称为时间常数)。显然计数器溢出时间(又称定时时间)与时间常数直接相关:时间常数越大,定时时间就越短;时间常数越小,定时时间就越长。同时系统时钟的频率也直接影响定时时间的长短,时钟的频率越高,定时时间越短;时钟的频率越低,定时时间越长。(四)时间常数的计算67设系统时钟的频率为fosc,计数器的初始值为N,定时器工作于方式1,则定时时间:

T=(216-N)×12/fosc(1)如果定时器工作于方式2或方式3,定时时间为:

T=(28-N)×12/fosc(2)

当初始值N=0时,如果fosc=12MHZ,最大定时时间为:方式1为:Tmax=216×12/fosc=65536us=65.536ms方式2、方式3为:Tmax=28×12/fosc=256us根据定时时间T,及公式(1)、(2)分别可以求出初值N为:方式1:N=216-T×fosc/12(3)方式2、方式3:N=28-T×fosc/12(4)如果fosc=12MHZ,以上公式可简化为方式1:N=216-T

方式2、方式3:N=28-T设系统时钟的频率为fosc,计数器的初始值为N,68

例如:系统的时钟频率是12MHz,在方式1下,如果希望定时器/计数器T0的定时时间T为10ms,则初值N=216-T=65536-10000=55536如何将55536给两个8位寄存器TH0、TL0赋值呢?可将十进制数55536转换成四位十六进制数,将高2位送TH0,低2位送TL0。更简单的方法是:对于16位计数器来讲,216等效为0,对于8位计数器,28等效为0,这样公式(3)、(4)可简化为N=-T,直接用下面两条语句就可以完成计数器初值的设置:TH0=-10000/256;//取-N的高8位TL0=-10000%256;//取-N的低8位

例如:设系统的时钟频率是12MHz,定时器工作于方式2,定时时间200us。根据前面分析,N=-T=-200,可直接用以下语句实现:TH0=-200;TL0=-200;例如:系统的时钟频率是12MHz,在方式1下,如69任务二、定时器应用[案例1]设时钟频率fosc=12MHz,用定时器T0在P1.0脚产生频率为20Hz的方波。

设计思想:在使用定时器/计数器时,首先应根据要求对工作方式进行初始化,然后计算出初始值。初始化的步骤通常是:

(1)向TMOD寄存器写入工作方式控制字。

(2)将计数器的初值写入TH0、TL0/TH1、TL1。

(3)启动定时器/计数器:将TR0/TR1置1。(4)如果采用中断方式,还应将ET0/ET1、EA置1。

任务二、定时器应用[案例1]设时钟频率fosc=70本题中,方波的频率为20HZ,对应的周期为50ms,如果将定时时间设置为25ms,每隔25ms将P1.0脚取反即可产生如图3-3所示的方波。因为定时时间为25ms,如果采用方式2或方式3,其定时的最大时间不超过256us,因此选方式1比较恰当,根据前面的分析,计数器初值N=-25000。本例题是定时而非计数,且无需脚参与启停控制,故C/=0,GATE为0,这样TMOD取0x01。本题中,方波的频率为20HZ,对应的周期为50m71voidmain(void){TMOD=0x01; TH0=-25000/256; TL0=-25000%256;TR0=1; ET0=1; EA=1; while(1);}voidtimer0(void)interrupt1{TH0=-25000/256; TL0=-25000%256;P10=~P10;}T0工作于定时方式1定时时间为25ms启动定时器T0允许定时器T0中断单片机开中断定时器T0中断服务程序重新装入时间常数P1.0求反voidmain(void)T0工作于定时方式1定时时间为72[案例2]如图所示,P0口接8只发光二极管,编程使发光管轮流点亮,点亮时间为500ms,要求使用定时器T0来控制,设晶振为12MHz[案例2]如图所示,P0口接8只发光二极管,编程使发73

设计思想

我们可将P0口的初值设置为0xFE,对应于发光管D1亮,每隔500ms将P0的值循环左移一位,这一周期性的定时作业用T0来完成。当时钟频率为12MHZ时,在定时器的4种工作方式中,方式1的最大溢出时间最长,但即使在方式1,最大的溢出时间也只有65.536ms,所以我们不能在每次中断时都执行上述移位操作,可以这样处理:将定时器T0的溢出时间设定为50ms,累计满10次中断正好500ms,才允许程序执行1次移位动作,设计思想74

主函数ucharcount=0;//50ms定时中断次数计数器voidmain(void){led=0xfe;TMOD=0x01;//T0工作于方式1TH0=-50000/256;//定时时间为50msTL0=-50000%256;ET0=1;//允许T0中断TR0=1;//启动T0定时EA=1;//CPU开中断while(1);}主函数75voidtime0(void)interrupt1{TH0=-50000/256;TL0=-50000%256;count++;if(count==10){count=0;led=_crol_(led,1);P0=led;}}定时器T0中断服务程序重新装入时间常数每中断一次,计数器加110次中断为0.5秒满10次变量led左移1位送P0口voidtime0(void)interrupt1定76[案例3]用定时器的计数方式实现外部中断。如图所示,P0口控制8只发光管轮流点亮,发光管点亮时间为500ms,单脉冲电路控制发光管的移动方向,按下单脉冲按钮,发光管左移,再按下发光管右移。[案例3]用定时器的计数方式实现外部中断。如图所示,77设计思想:当定时器/计数器工作于计数方式2时,如果将计数器的初值设置为全1,只要在计数输入端(T0或T1)送入一个计数脉冲,就可使计数器产生溢出中断。如果将外部中断请求作为计数脉冲输入,就可利用计数中断的名义去完成外部中断服务。当应用中外部中断请求较多时,而单片机内部的定时器/计数器还有富余时,可采用这种方法来扩展外部断。因此本例的实质是将定时器的计数输入端T1扩展为外部中断请求输入,来控制发光管的移动方向。

设计思想:78具体方法:

1、初始化定时器/计数器T1计数工作方式2,即每次溢出中断后能自动装入计数初值。2、计数器TH1、TL1的初值预置为0FFH。3、程序中设置一个位变量,每当计数器T1产生溢出中断时求反,发光管左移还是右移取决于该变量是0还是1。具体方法:1、初始化定时器/计数器T1计数79

voidmain(void){DIR=0;led=0xfe;TMOD=0x61;TH0=-50000/256;TL0=-50000%256;TH1=0xff; TL1=0xff;ET0=1;ET1=1; TR0=1;TR1=1; EA=1;while(1);}T0为定时方式0,T1为计数方式2定时时间为50msT1的初值为0xff允许T0、T1中断启动T0定时启动T1计数CPU开中断voidmain(void)T0为定时方式0,T1为计数80

voidtime0(void)interrupt1{TH0=-50000/256;TL0=-50000%256;count++;if(count==10){count=0; if(DIR==1) led=_crol_(led,1); else led=_cror_(led,1); P0=led;}}重新装入时间常数满10次为0.5秒计数器清0DIR为1左移DIR为0右移每中断一次,计数器加1定时器T0中断服务程序voidtime0(void)interrupt181

voidtime1(void)interrupt3{DIR=~DIR; }每次按下按钮产生T1的溢出中断,将DIR求反定时器T1中断服务程序voidtime1(void)interrupt382[案例4]用定时器来控制数码管的动态显示。设计思想:

前面我们介绍LED动态显示程序时,每一位点亮后都需延时1ms左右,由于使用的是软件延时,大大降低了CPU的效率,而且当CPU因处理某件事务在一段时间内无法调用显示程序时,LED显示器将会出现黑屏或产生闪烁现象。用定时器控制数码管的动态显示的方法:设定时器的定时时间为1ms,每次产生溢出中断,就根据位选变量bsel(主程序中将其初值设置为0xfe)送位选口,点亮一位数码管,并将bsel左移一位,为下一位的显示做好准备,4次定时中断分别完成4位数码管的显示,之后将bsel的值再次初始化为0xfe,准备下一轮显示。

因此这种显示方式由定时中断自动完成,无需在主程序中调用。[案例4]用定时器来控制数码管的动态显示。83主程序ucharbsel,n;voidmain(void){n=0;bsel=0xfe;//首先显示数码管的最低位TMOD=0x01;//T0工作于定时方式2TH0=-1000/256;//T0的定时时间为1000usTL0=-1000%256;ET0=1;//允许T0中断TR0=1;//启动定时EA=1;//开中断while(1);}主程序84voidtime0(void)interrupt1{TH0=-1000/256;TL0=-1000%256;P0=0xff;P2=bsel;P0=segtab[dbuf[n]];bsel=_crol_(bsel,1);n++; if(n==4) {n=0; bsel=0xfe; }}重新装入时间常数定时器T0中断服务程序熄灭数码管,防止上一位字符在当前位置显示出来。点亮当前位根据显示缓存查字段码准备显示下一位指向下一位要显示的数据如果四位已显示完,重新从最低位开始voidtime0(void)interrupt185[案例5]如图3-8所示,设计一个电子秒表,每隔一秒加1,用三位数码管显示秒表的当前值(0-255),单脉冲按键用于启动、停止、清0控制,第一次按下该按键时启动秒表,第二次按键将暂停秒表,第三次按键将秒表清0,设置晶振频率为12MHZ。[案例5]如图3-8所示,设计一个电子秒表,每86设计思想:我们可用一个变量记录秒表的当前值,为了提高秒表精度,我们可令定时器T0工作于定时方式2,定时时间为250us,4000次溢出中断正好满1秒,让变量加1,同时将该变量转换为三位BCD码送到显示缓存,供显示程序显示。单脉冲直接和外部中断0的输入端INT0相连,每次按键产生中断请求,程序中设置一个变量,对按键动作进行计数,取值为1-3,分别对应于启动、停止和清0,程序根据该变量的值进行相应的控制。设计思想:87主程序voidmain(void){count=0;sec=0;mode=0;IT0=1; //外部中断负跳变触发EX0=1;//允许外部中断0中断TMOD=0x02;//T0工作于定时方式2TH0=-250;//T0的定时时间为250usTL0=-250;ET0=1;//允许T0中断TR0=0;//停止定时器EA=1;//开中断while(1)disp();}主程序88定时器T0中断服务程序voidtime0(void)interrupt1{count++;//中断次数加1if(count==4000){count=0; sec++; dbuf[2]=sec/100;//将秒数计换成三位BCD码dbuf[1]=(sec%100)/10;dbuf[0]=sec%10;}}定时器T0中断服务程序89voidint0(void)interrupt0{mode++; //每次产生中断,mode加1if(mode==1) //mode为1,启动定时器工作TR0=1;elseif(mode==2)//如果mode等于2,停止定时器工作TR0=0;elseif(mode==3)//如果mode为3,{mode=0;TR0=0;sec=0; //将秒计数器清0 dbuf[0]=0;dbuf[1]=0; dbuf[2]=0; } }外部中断0中断服务程序voidint0(void)interrupt0外部90[案例6]用单片机演奏歌曲《兰花草》

设计思想:单片机可以根据音符产生不同频率的脉冲信号,经驱动后来控制蜂鸣器,让蜂鸣器产生与音符相应的声音,再把它们有机地组合起来,就可以发出一段音乐。[案例6]用单片机演奏歌曲《兰花草》设计思想:单91

1、要产生与某音符相应的脉冲信号,只要算出该音频的频率和周期,然后将该周期除2,即为半周期的时间。将定时器的定时时间设定为这半周期时间,一旦定时器溢出,就将P1.6脚求反,这样就能产生与音符频率对应的脉冲信号。设单片机定时器工作在定时方式1,改变时间常数TH0、TL0就可以产生与各种音符频率相应的脉冲信号。

设要产生的频率为fr,单片机机器周期的频率为fi,则对应定时器时间常数为N。N=65536-fi÷2÷fr1、要产生与某音符相应的脉冲信号,只要算出该音92

2、用单片机演奏音乐时,可以这样来表示乐谱:乐谱由多个简谱码组成,以00结束,每个简谱码用一个字节来表示,字节的高4位为音符码,代表音符的高低,低4位为节拍码,表示音符的节拍,下表3-2为节拍与节拍码的对照。如果1拍为0.4秒,则1/4拍为0.1秒,2/4拍为0.2秒,所以只要根据节拍来设定延时时间。设定时器T1的定时时间为50ms,二次溢出中断正好为1/4拍,将节拍码乘2即为该节拍所需溢出中断的次数。2、用单片机演奏音乐时,可以这样来表示乐谱:93

程序中,定时器T0用于控制音调的高低,定时器T1用于控制节拍的长短,各音符对应的时间常数放在数组tab1中,乐谱以简谱码的形式存储在数组tab3中,高四位为音符码,低四位为节拍码,0x00表示乐谱结束。变量m指向tab3中当前需演奏的简谱码,从中分解出高四位的音符码,并从tab1中取出时间常数控制定时器T0产生与音符频率相应的方波;从简谱码的低四位分解出节拍码,控制定时器T1延时节拍所需的时间。程序中,定时器T0用于控制音调的高低,定94程序流程图程序流程图95voidmain(void){ucharm;//用于指向音符的下标变量ucharc;TMOD=0x11;//定时器设定为方式1ET0=1;//允许T0中断ET1=1;//允许T1中断TH1=-50000/256;//50ms定时,节拍长短控制TL1=-50000%256;TR1=1;EA=1;}voidmain(void)96

while(1){m=0; //指向音符的下标变量while(tab3[m]) //如果乐谱末结束{c=tab3[m]>>4; //取高四位的音符if(c!=0) //音符不为0{th=tab1[c-1]>>8;//根据音符取出时间常数tl=tab1[c-1]&0xff;TH0=th;TL0=tl;//重新设置时间常数 TR0=1;} //启动定时器,开启中断else{TR0=0;} //如果音符为0,不发声,time=(tab3[m]&0x0f)*2;//确定延时时间 while(time!=0);//延时规定节拍m++; //指向下个音符}

TR0=0;//暂停5S后,重新开始time=100;while(time!=0);}

while(1)TR0=0;97voidtimer0(void)interrupt1using1{TH0=th;//装入时间常数TL0=tl;SOUND=~SOUND;//产生方波}voidtimer1(void)interrupt3{TH1=-50000/256;//重新装入50ms的时间常数TL1=-50000%256;time--;//溢出中断次数减1}定时器T0中断服务程序,用于产生产生与音符频率相应的方波定时器T1中断服务程序,延时当前节拍所需的时间voidtimer0(void)interrupt198

[案例7]调节发光二极管的亮度。亮度分为0-7共8级,亮度等级为0时,发光管熄灭;亮度等级为7时,发光管最亮。用KINC、KDEC两个按键调节当前的亮度。

设计思想:如图所示,如果在P0.0引脚产生一个周期为2ms的脉冲,如果每个周期内脉冲的低电平时间少,高电平时间长,发光管的亮度显然暗些,反之发光管要亮些,当P0.0输出全为高,发光管就熄灭了。因此只要调节脉冲低电平的时间就可改变发光管的亮度。[案例7]调节发光二极管

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论