51单片机--定时器测量脉宽

学51也算有一段时间了 以前学的相当的粗糙 很多原理性的东西 都不知道 今天上课的时候听老师说  这个LOW的单片机可以测量脉宽   去手册上看了一下 加上课本上说的  卧槽 真的可以 哈哈  

直接上手册上的来说吧  51单片机--定时器测量脉宽_第1张图片

就是这个东西  TMOD寄存器中的那个GATE位  很明显 手册中说道  当这位置1的时候 只有在INT0(P3.2)引脚为高电平的时候  并且TR0或者TR1置位的时候 定时/计数器才打开  我们就可以利用这个特点来测量一个脉冲的高电平的宽度  就是这个高电平的持续时间  那么怎么测量呢  说一下思路  

首先  我们让门控位GATE=1   并且启动定时/计数器 TR0  但是这时候寄存器TH0  TL0里面的数值并不会增加  因为INT0这个引脚上还没高电平  我们把要测量的脉冲接到P3.2这个引脚上   当高电平来的时候   TH0和TL0里面的数值就开始每过一个机器周期增加一   知道P3.2引脚上的高电平消失   当高电平消失的时候 自然 TH0和TL0也就停止计数了  这时候我们把TH0和TL0里面的数值读出来   根据时钟和机器周期的关系就可以的出来高电平的时间了  这里 简单算一下 吧   好算一点  假设晶振频率是12MHZ那么机器周期就是1US   如果读出来 TH0+TL0=50000    那么这个高电平的持续时间就是50mS  能明白不 !!!

我用仿真做了一下  得出的结果基本正确   这里说一下仿真的问题   就是 仿真里面好像默认的51的晶振频率是12MHZ   即使你搭建外部晶振电路也不能改变改变频率 还要复位貌似也不太好用  哎呀 算了 这个不太影响

直接上代码 上图  看一下 下面的代码  我仿真里面设置的脉冲频率是1KHZ 占空比是50%    由这个代码得到的高电平的时间 理论值是500us   测得位501us 我觉得基本正确

# include
# define uint unsigned int 
# define uchar unsigned char
uchar code table1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; 
uint High,Low;
sbit K=P3^2;
sbit led0=P2^0;  
sbit led1=P2^1;  
sbit led2=P2^2;  
sbit led3=P2^3;
void delay(uint k)   //延时函数    这个延时是为了数码管  
{  
    uint i,j;  
    for(i=k;i>0;i--)  
        for(j=113;j>0;j--) ;  
}
void Init_T0()
{
	TMOD=0x09;
	TH0=0;
	TL0=0;
}
void Display(disnum)  
{  
    led0=1;  
    P0=table1[disnum/1000];  
    delay(3);  
    P0=0xff;  
    led0=0;   
  
    led1=1;  
    P0=table1[disnum%1000/100];  
    delay(3);  
    P0=0xff;  
    led1=0;  
  
    led2=1;  
    P0=table1[disnum%100/10];  
    delay(3);  
    P0=0xff;  
    led2=0;  
  
    led3=1;  
    P0=table1[disnum%10];  
    delay(3);  
    P0=0xff;  
    led3=0;  
  
}
void Message_Width()
{
	while(K);
	TR0=1;
	while(!K);
	while(K);
	TR0=0;
	High=TH0;
	Low=TL0;
}
void main()
{
	while(1)
	{
	   Init_T0();
	   Message_Width();	
	   Display(High*256+TL0);
	}
}


此代码得到下图 

51单片机--定时器测量脉宽_第2张图片

但是无意间让我发现了一个很无奈的问题  我觉得上面的数码管写的太小学生了 于是想让程序少几行 把数码管的函数变更了一下  但是测得脉宽长度居然不一样了 多了8个us即使两个函数执行时间不一样  可是我实在数码管显示函数之前就把脉宽测量完成了 啊  为啥会多这个8us呢   有哪位大佬看到希望指点一下 啊 下面附上代码和图

# include
# define uint unsigned int 
# define uchar unsigned char
uchar code table1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; 
uchar code table2[]={0x01,0x02,0x04,0x08};
uchar table3[4]={0};
uint High,Low,n;
sbit K=P3^2;
void delay(uint k)   //延时函数    这个延时是为了数码管  
{  
    uint i,j;  
    for(i=k;i>0;i--)  
        for(j=113;j>0;j--) ;  
}
void  Data_Process(disnum)
{
	table3[0]= disnum/1000;
	table3[1]= disnum%1000/100;
	table3[2]= disnum%100/10;
	table3[3]= disnum%1000;
}
void Display()  
{  
	uchar i;
	for(i=0;i<4;i++)
	{
		P2=table2[i];
		P0=table1[table3[i]];
		delay(3);
		P0=0xff;
		P2=0; 
	} 
}
void Init_T0()
{
	TMOD=0x09;
	TH0=0;
	TL0=0;
}
void Message_Width()
{
	while(K);
	TR0=1;
	while(!K);
	while(K);
	TR0=0;
	High=TH0;
	Low=TL0;
}
void main()
{
	while(1)
	{
		Init_T0();
		Message_Width();
		Data_Process(High*256+TL0);
		Display();
	}
}


51单片机--定时器测量脉宽_第3张图片


你可能感兴趣的:(51单片机)