900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 51单片机定时器及其应用(2)(测量脉冲宽度)

51单片机定时器及其应用(2)(测量脉冲宽度)

时间:2020-11-02 22:35:44

相关推荐

51单片机定时器及其应用(2)(测量脉冲宽度)

51单片机定时器及其应用(2)(测量脉冲宽度)

上一篇文章讲了如何使用51单片机的定时器功能制作一个简易的数字钟,上次有一个GATE位没有涉及到,因此这次来介绍一下定时器的这个GATE位的应用,也就是测量脉冲宽度。先来介绍一下我们有什么“工具”,看一下定时器的TMOD寄存器:

这个GATE位,为了方便,这里以定时器1为例。手册说只有当定时器的外部引脚INT1ˉ\bar{INT1}INT1ˉ为高电平并且内部软件控制位TR1为1时才能打开定时器1,这正好能用于解决脉冲宽度测量这个难题。

将GATE置1,TR1置1,此时外部送来一个脉冲,在高电平器件就会开始计数,计数值在TH1和TL1寄存器里,当低电平到来时,关闭定时器,将最后的计数值减去初值,再乘以每秒计数间隔(51单片机每秒间隔为一个机器周期,1us左右),就可以得到脉冲宽度了。如果脉冲宽度过大,则每次计数值满了会产生溢出中断,此时只定义一个变量Count,每次溢出加1,并在中断服务程序中清0,就可以得到最终脉冲宽度为count×定时时间+TH1*256+TL1,单位为us。下面给出代码

#include <reg52.h>sbit Wei_Select=P2^6;sbit Duan_Select=P2^5;sbit INT=P3^2;char Display_Code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};char Wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};long count=0;long Pulse_Width=0;unsigned int flag=0;unsigned int Count_High=0;unsigned int Count_Low=0;unsigned int num=0;unsigned int ge=0,shi=0,bai=0,qian=0,wan=0;void delay_ms(unsigned int Xms){unsigned int i=0,j=0;for(i=Xms;i>0;i--)for(j=110;j>0;j--);}void InitTimer0(void){TMOD = 0x09;TH0 = 0x14;TL0 = 0x13;EA = 1;ET0 = 1;EX0=0;}void Timer0()interrupt 1{TH0 = 0x14;TL0 = 0x13;count++;}void display(unsigned int position,unsigned int number){Duan_Select=0;Wei_Select=1;P0=Wei[position-1];Wei_Select=0;Duan_Select=1;P0=Display_Code[number];delay_ms(2);}void Read_Count(){Count_Low=TL0;Count_High=TH0;num=Count_High*256+Count_Low;}void main(){InitTimer0();while(1){count=0;flag=0;while(INT==1);TH0 = 0;TL0 = 0;TR0=1;while(INT==0);while(INT==1);TR0=0;Read_Count();Pulse_Width=(count*65535+num)/1000;ge=Pulse_Width%10;shi=Pulse_Width/10%10;bai=Pulse_Width/100%10;qian=Pulse_Width/1000%10;wan=Pulse_Width/10000%10;while(flag!=200){flag++;display(8,ge);display(7,shi);display(6,bai);display(5,qian);display(4,wan);}}}

测量范围为10ms到未知,只要你愿意等,能测量很宽的脉冲宽度,显示单位为ms。测量范围大的话,误差差不多为4ms左右。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。