c51定时器中断.ppt_第1页
c51定时器中断.ppt_第2页
c51定时器中断.ppt_第3页
c51定时器中断.ppt_第4页
c51定时器中断.ppt_第5页
免费预览已结束,剩余19页可下载查看

下载本文档

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

文档简介

3.2单片机定时器/计数器应用,3.2.1利用Timer0中断产生1秒延时,让数1个码管显示秒计数本案例主要目的是熟练掌握单片机内部Timer0或Timer1的编程控制方法,会利用Timer0或Timer1中断精确定时。同时掌握数码管动态显示原理,学会6位数字显示的程序设计。本案例使用的电路为图3-1-3。,一、程序设计,#includecodeunsignedcharseven_seg10=0 xc0,0 xf9,0 xa4,0 xb0,0 x99,0 x92,0 x82,0 xf8,0 x80,0 x90;unsignedcharcp,i;/声明全局变量voidtimer0_isr(void)interrupt1/timer0中断服务函数TR0=0;/停止计数TL0=0 x11;/TL0重新预置TH0=0 xee;/TH0重新预置TR0=0;/开始计数cp+;/timer0中断1次,变量cp加1if(cp=200)/中断200次,时间刚好为1秒cp=0;i+;if(i=10)i=0;P0=seven_segi/P0输出显示数据,voidtimer0_initialize(void)/timer0中断初始化函数EA=0;/设置中断允许寄存器IE中的EA位,/关闭中断总开关TMOD=0 x01;/设置计时器模式控制寄存器,/Time0工作在定时方式1TR0=0;/设置计时器控制寄存器TCON寄存器/的TR0位为0,Timer0/停止计数TL0=0 x11;TH0=0 xee;/Timer0的16位计数器初始值为/0 xee11,12MHz晶体振/频率,单片机的机器周期为1微妙,/Timer0每1微秒加1计数,/加满溢出变产生中断,/从计数到中断刚好为5毫秒PT0=1;/设置中断优先次序寄存器IP中的/PT0位,Timer0中断优先ET0=1;/设置中断允许寄存器IE中ET0的/位,开启中断小开关EA=1;/打开中断总开关TR0=1;/开始计数,voidmain(void)timer0_initialize()/timer0初始化,为中断做好准备while(1);/等待中断,二、程序说明,1.中断服务函数名中,interruput为关键字,1为timer0中断号。在reg51.h头文件中已经定义,表3.2.1为单片机常用中断的中断号。在使用中断服务函数时,直接在名后加interruput和中断号即可。,表3.2.1REG51.H中单片机常用中断号定义,2.timer0可以用作计数,也可以用来定时,由由TMOD寄存器中为决定,作为计数器使用时,接受单片机外部引脚P3.4输入的脉冲加计数;作为定时器使用时,接受单片机内部的机器周期脉冲。如果单片机的振荡频率为,振荡周期为,则机器周期为。本案例中MHz,则微秒,timer0工作在模式1为16为加计数器,当计数器初始值为0 xee11时,则从开始计数到产生中断需要的时间为0 xffff0 xee11个微秒,刚好为5000微秒,也即5毫秒。,本案例TIMER0的初装也可以利用下面语句完成:,#definedTEMOR0_COUNT0 xee11TL0=TEMOR0_COUNT/TEMOR0_COUNT左移8位,并将低字节装入TEMOR0_COUNT利用定时器/计数器定时时,需要现设置工作模式,并计算它的初装值,计算初装值不好计算,常利用计算机中的计算器工具辅助。timer0工作在模式1可以最大65535微秒中断1次,如工作模式2,最大256微秒中断1次。3.当程序中只涉及一个中断时,可以不对中断的优先级进行设置,因此在本案例中语句PT0=1可以省略。程序中有多个中断但没有进行优先级设定的情况下,单片机中断优先级默认按终端号递增而依次降低。4.数码管显示语句放在了timer0中断服务函数里面,由于5毫秒中断1次,因此数码管显示的数据会每5毫秒更新1次。1秒内更新200次,更新过程是把原来的数据覆盖,但显示数据1秒内变化1次。,3.2.2利用4个数码管,实现秒信号加计数,一、电路原理图3-2-1所示的电路中,4位七段数码管采用4只单个数码管组成,可以显示00009999,数据输入端并联后接P0口,位选即每个数码管的阳极分别接P2口,中间加非门驱动。因为P2口反相驱动,因此,如果千位数码管显示,P2.7输出低电平,P2的其它端口输出高电平,并且此时P0输出千位数据。,在利用Proteuse软件仿真时,数码管SEVEN_SEG使用7SEG-MPX4-CA,非门NOT选用74HCseries类型中Gatescodeucharseg_scan4=0 xef,0 xdf,0 xbf,0 x7f;/各个数码管对应的位选数据ucharcounter4=0,0,0,0;/个位、十位、百位和千位数uintcp,i;voidtimer0_isr(void)interrupt1/timer0中断服务函数ucharj;TR0=0;/停止计数TL0=0 x11;/TL0重新预置TH0=0 xee;/TH0重新预置TR0=0;/开始计数cp+;/timer0中断1次,变量cp加1if(cp=200)/中断200次,时间刚好为1秒cp=0;counter0+;/个位数,1秒加1,if(counter0=10)counter0=0;counter1+;if(counter1=10)counter1=0;counter2+;if(counter2=10)counter2=0;counter3+;if(counter3=10)counter3=0;P0=seven_segcounterj;/P0输出数据编码P2=seg_scanj;/P2输出位选信号j+;if(j=4)j=0;voidtimer0_initialize(void)/timer0中断初始化函数EA=0;TMOD=0 x01;TR0=0;TL0=0 x11;TH0=0 xee;PT0=1;ET0=1;EA=1;TR0=1;voidmain(void)timer0_initialize()while(1);,三、程序说明,1imer0第1次中断,j=0,显示个位,显示5毫秒后,timer0第2次中断,j=1,显示十位,以后随着中断依次显示百位和千位,最后重新显示个位。每位显示停留的时间为5毫秒。中断4次才能让4为依次扫描显示完,占用的时间为20毫秒,1秒钟内,4位数码管扫描显示50遍,根据人眼视觉暂留特点,你看到的结果是4位数据同时显示,这种显示方法为动态扫描显示。2变量j=0时,counter0是个位十进制数,执行P0=seven_segcounter0,P0口输出个位显示数据编码;数码管的位选信号只利用了P2的高4位,执行P2=seg_scan0,P2=0 xef,经过非门反相,加在数码管上的位选信号只有个位是高电平,此时只显示个位。3数组counterj也可以用1个变量代替,在显示时需做下面处理,uintx;P0=seven_segx/1000;/P0输出千位数据编码P2=seg_scan3;/千位数码管共阳极设置为高电平P0=seven_segx%1000/100;/P0输出百位数据编码P2=seg_scan2;/千位数码管共阳极设置为高电平P0=seven_segx%1000%100/10;/P0输出十位数据编码P2=seg_scan1;/千位数码管共阳极设置为高电平P0=seven_segx%1000%100%10;/P0输出千位数据编码P2=seg_scan0;/千位数码管共阳极设置为高电平,思考题,(1)要让数码管在电路加电开始就显示1230,怎样更改有关数据?(2)为什么不用P2口直接驱动数码管?(3)本案例如果200微秒中断1次,也可以实现1定时,显示结果会怎样?,3.2.3设计一个6位数码管时间显示程序,本案例使用6位数码管显示时间,能显示时/分/秒,显示格式是00.00.00到23.59.59。其中小时和分钟之间的小数点常亮,分钟和秒之间的小数点进行秒闪烁。参考程序:#include#definedunsignedcharucharcodeucharseven_seg10=0 xc0,0 xf9,0 xa4,0 xb0,0 x99,0 x92,0 x82,0 xf8,0 x80,0 x90;codeucharseg_scan6=0 xfb,0 xf7,0 xef,0 xdf,0bf,0 x7f;/各个数码管对应的位选数据ucharcounter3=0,0,0;/时位、分位和秒位uchartick,cp,i,j;/tick:秒信号,cp:中断次数累计,voiddispaly(void)uchard;d=d*tick;/d的值1秒内改变1次,要么0 x00,要么0 xffd=d|0 x7f;/d的值1秒内改变1次,要么0 x7f,要么0 xffswich(i)case0:P0=seven_segcounter0%10;break;/显示秒个位case1:P0=seven_segcounter0/10;break;/显示秒十位case2:P0=d,voidtimer0_isr(void)interrupt1/timer0中断服务函数TR0=0;/停止计数TL0=0 x11;/TL0重新预置TH0=0 xee;/TH0重新预置TR0=0;/开始计数cp+;/timer0中断1次,变量cp加1if(cp=100)/中断100次,时间刚好为0.5秒cp=0;tick=tick;/秒脉冲信号j+;if(j=2)/刚好1秒j=0;counter0+;/个位数,1秒加1if(counter0=60)counter0=0;counter1+;if(counter1=60)counter1=0;counter2+;if(counter2=24)counter2=0;display();,voidtimer0_initialize(void)/timer0中断初始化函数EA=0;TMOD=0 x01;TR0=0;TL0=0 x11;TH0=0 xee;PT0=1;ET0=1;EA=1;TR0=1;voidmain(void)timer0_initialize()/timer0初始化,为中断做好准备while(1);,三、程序说明,1.利用counter2、counter1和counter0变量分别表示时、分和秒位的数值大小,也可以利用结构体定义这些变量,如:typedefstructucarhour;ucarmin;ucarsec;time;timenow;/now是数据类型为time的变量然后就可以用now.hour,now.min和now.sec分别代替counter2、counter1和counter0.变量,2.执行timer0中断服务函数时调用了dispaly()函数,直接把dispaly()的函数体程序写在中断函数体内也行,但中断服务函数会显得臃肿。timer0每5毫秒中断1次,调用dispaly()函数执行1次,在执行dispaly()过程中,当i=0时,只显示秒个位,当i=1时,只显示秒十位,依次类推。为了让小时的个位小数点常亮,让小时个位显示时,把显示编码数据的高8位设置为0;为了分个位小数点秒闪烁,把分个位小数点位设置一个周期变化的量即可。3.程序与复杂,使用的变量就愈多,在程序分析和设计时,需要注意使用的变量最好使用有一定含义的字符表示。,思考题,1.利用模式2最大好处在于在timer0中断服务函数中不再对TL0和TH0预置,程序变得简单一些,下面是利用timer0实现1秒定时局部程序,试分析并补写完

温馨提示

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

评论

0/150

提交评论