1. 程式人生 > >51微控制器--定時器測量脈寬

51微控制器--定時器測量脈寬

學51也算有一段時間了 以前學的相當的粗糙 很多原理性的東西 都不知道 今天上課的時候聽老師說  這個LOW的微控制器可以測量脈寬   去手冊上看了一下 加上課本上說的  臥槽 真的可以 哈哈  

直接上手冊上的來說吧  

就是這個東西  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<reg52.h>
# 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);
	}
}


此程式碼得到下圖 


但是無意間讓我發現了一個很無奈的問題  我覺得上面的數碼管寫的太小學生了 於是想讓程式少幾行 把數碼管的函式變更了一下  但是測得脈寬長度居然不一樣了 多了8個us即使兩個函式執行時間不一樣  可是我實在數碼管顯示函式之前就把脈寬測量完成了 啊  為啥會多這個8us呢   有哪位大佬看到希望指點一下 啊 下面附上程式碼和圖

# include<reg52.h>
# 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();
	}
}