c51定时器中断.ppt

上传人:小飞机 文档编号:5417014 上传时间:2023-07-05 格式:PPT 页数:24 大小:229KB
返回 下载 相关 举报
c51定时器中断.ppt_第1页
第1页 / 共24页
c51定时器中断.ppt_第2页
第2页 / 共24页
c51定时器中断.ppt_第3页
第3页 / 共24页
c51定时器中断.ppt_第4页
第4页 / 共24页
c51定时器中断.ppt_第5页
第5页 / 共24页
点击查看更多>>
资源描述

《c51定时器中断.ppt》由会员分享,可在线阅读,更多相关《c51定时器中断.ppt(24页珍藏版)》请在三一办公上搜索。

1、3.2单片机定时器/计数器应用,3.2.1利用Timer0中断产生1秒延时,让数1个码管显示秒计数本案例主要目的是熟练掌握单片机内部Timer0或Timer1的编程控制方法,会利用Timer0或Timer1中断精确定时。同时掌握数码管动态显示原理,学会6位数字显示的程序设计。本案例使用的电路为图3-1-3。,一、程序设计,#includecode unsigned char seven_seg10=0 xc0,0 xf9,0 xa4,0 xb0,0 x99,0 x92,0 x82,0 xf8,0 x80,0 x90;unsigned char cp,i;/声明全局变量void timer0_i

2、sr(void)interrupt 1/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输出显示数据,void timer0_initialize(void)/timer0中断初始化函数EA=0;/设置中断允许寄存器IE中的 EA位,/关闭中断总开关TMOD=0 x01;/设置计时器模式控制寄存器,/Time0工作在定时方式1TR0=0;/

3、设置计时器控制寄存器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;/开始计数,void main(void)timer0_initialize()/timer0初始化,为中断做好准备whi

4、le(1);/等待中断,二、程序说明,1.中断服务函数名中,interruput为关键字,1为timer0中断号。在reg51.h头文件中已经定义,表3.2.1为单片机常用中断的中断号。在使用中断服务函数时,直接在名后加interruput和中断号即可。,表3.2.1 REG51.H中单片机常用中断号定义,2.timer0可以用作计数,也可以用来定时,由由TMOD寄存器中 为决定,作为计数器使用时,接受单片机外部引脚P3.4输入的脉冲加计数;作为定时器使用时,接受单片机内部的机器周期脉冲。如果单片机的振荡频率为,振荡周期为,则机器周期为。本案例中 MHz,则 微秒,timer0工作在模式1为1

5、6为加计数器,当计数器初始值为0 xee11时,则从开始计数到产生中断需要的时间为0 xffff 0 xee11个微秒,刚好为5000微秒,也即5毫秒。,本案例TIMER0的初装也可以利用下面语句完成:,#defined TEMOR0_COUNT 0 xee11TL0=TEMOR0_COUNT/TEMOR0_COUNT左移8位,并将低字节装入TEMOR0_COUNT利用定时器/计数器定时时,需要现设置工作模式,并计算它的初装值,计算初装值不好计算,常利用计算机中的计算器工具辅助。timer0工作在模式1可以最大65535微秒中断1次,如工作模式2,最大256微秒中断1次。3.当程序中只涉及一个

6、中断时,可以不对中断的优先级进行设置,因此在本案例中语句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口反相驱动

7、,因此,如果千位数码管显示,P2.7输出低电平,P2的其它端口输出高电平,并且此时P0输出千位数据。,在利用Proteuse软件仿真时,数码管SEVEN_SEG使用7SEG-MPX4-CA,非门NOT选用74 HC series类型中Gates&Inverters分类下的74HC04。电阻R29是限流电阻。,二、程序设计,#include#defined unsigned char uchar#defined unsigned int uintcode uchar seven_seg10=0 xc0,0 xf9,0 xa4,0 xb0,0 x99,0 x92,0 x82,0 xf8,0 x80

8、,0 x90;code uchar seg_scan4=0 xef,0 xdf,0 xbf,0 x7f;/各个数码管对应的位选数据uchar counter4=0,0,0,0;/个位、十位、百位和千位数uint cp,i;void timer0_isr(void)interrupt 1/timer0中断服务函数uchar j;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(cou

9、nter0=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;void timer0_initialize(void)/timer0中断初始化函数EA=0;TMOD=0 x01;TR0=0;TL0=0 x11;TH0=0 xee;PT0=1;ET0=1;EA=1;TR0=1

10、;void main(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口输出个位显示数据编码;数码管的位选信号只利用了

11、P2的高4位,执行P2=seg_scan0,P2=0 xef,经过非门反相,加在数码管上的位选信号只有个位是高电平,此时只显示个位。3数组counterj也可以用1个变量代替,在显示时需做下面处理,uint x;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_

12、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#defined unsigned char ucharcode uchar

13、seven_seg10=0 xc0,0 xf9,0 xa4,0 xb0,0 x99,0 x92,0 x82,0 xf8,0 x80,0 x90;code uchar seg_scan6=0 xfb,0 xf7,0 xef,0 xdf,0bf,0 x7f;/各个数码管对应的位选数据uchar counter3=0,0,0;/时位、分位和秒位uchar tick,cp,i,j;/tick:秒信号,cp:中断次数累计,void dispaly(void)uchar d;d=d*tick;/d 的值1秒内改变1次,要么0 x00,要么0 xffd=d|0 x7f;/d 的值1秒内改变1次,要么0 x7

14、f,要么0 xffswich(i)case 0:P0=seven_segcounter0%10;break;/显示秒个位case 1:P0=seven_segcounter0/10;break;/显示秒十位case 2:P0=d,void timer0_isr(void)interrupt 1/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)/刚

15、好1秒j=0;counter0+;/个位数,1秒加1if(counter0=60)counter0=0;counter1+;if(counter1=60)counter1=0;counter2+;if(counter2=24)counter2=0;display();,void timer0_initialize(void)/timer0中断初始化函数EA=0;TMOD=0 x01;TR0=0;TL0=0 x11;TH0=0 xee;PT0=1;ET0=1;EA=1;TR0=1;void main(void)timer0_initialize()/timer0初始化,为中断做好准备while(

16、1);,三、程序说明,1.利用counter2、counter1 和counter0变量分别表示时、分和秒位的数值大小,也可以利用结构体定义这些变量,如:typedef structucar hour;ucar min;ucar sec;time;time now;/now是数据类型为time的变量然后就可以用now.hour,now.min和now.sec分别代替counter2、counter1 和counter0.变量,2.执行timer0中断服务函数时调用了dispaly()函数,直接把dispaly()的函数体程序写在中断函数体内也行,但中断服务函数会显得臃肿。timer0每5毫秒中

17、断1次,调用dispaly()函数执行1次,在执行dispaly()过程中,当i=0时,只显示秒个位,当i=1时,只显示秒十位,依次类推。为了让小时的个位小数点常亮,让小时个位显示时,把显示编码数据的高8位设置为0;为了分个位小数点秒闪烁,把分个位小数点位设置一个周期变化的量即可。3.程序与复杂,使用的变量就愈多,在程序分析和设计时,需要注意使用的变量最好使用有一定含义的字符表示。,思考题,1.利用模式2最大好处在于在timer0中断服务函数中不再对TL0和TH0预置,程序变得简单一些,下面是利用timer0实现1秒定时局部程序,试分析并补写完整,让这个程序完成与本案例一样的功能。unsigned int cp,i;void timer0_isr(void)interrupt 1 cp+;if(cp=4000)cp=0;i+;void timer0_ini(void)EA=0;TR0=0;TL0=0 x06;TH0=0 x06;TR0=1;EA=1;ET0=1;,思考题,2.单片机不能直接执行C语言程序,需要利用Keil C软件编译后生成Hex文件,单片机执行程序都需要一定的时间,如果一个程序执行中断服务函数使用的时间超过了中断间隔时间,运行结果会如何?,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号