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(); } }