———————————————————————————————————————————— PWM(脈衝寬度調製) 對模擬信號電平進行數字編碼的方法 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ...
————————————————————————————————————————————
PWM(脈衝寬度調製)
- 對模擬信號電平進行數字編碼的方法
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
設計要求:
- 由於AT89系列單片機沒有PWM控制器,所以通過定時器產生PWM
- 通過按鈕控制P2.0輸出高低電平的時間,占空比可調範圍:0~100%,每次按下按鈕以10%步進,通過示波器看到對應波形。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
電路功能:
第一個放大器的作用是反相,將P2.0口輸出的電壓反相,得到一個絕對值相等的負電壓。R1和R2阻止相同,不放大。
第二個放大器的作用是放大電壓,並再次反相。放大倍數是R4:R5=1000:100=10倍。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
實驗現象:
- 首次按下按鈕時,n=0,占空比0%,P2.0低電平10ms,高電平0ms,電機不轉。
- 第二次按下按鈕,n=1,占空比10%,P2.0低電平9ms,高電平1ms,電機轉1ms停9ms。
- 第三次按下按鈕,n=2,占空比20%,P2.0低電平8ms,高電平2ms,電機轉2ms停8ms。
- ...
- 十次迴圈過後n=0,重新開始
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
元件清單:
- BUTTON
- AT89C51
- MOTOR
- RES,p.s.嚴格對應圖中阻止
- OPAMP
- COUNTER TIMER,p.s.COUNTER TIMER(頻率計)設置OperatingMode項為frequency
- Digital Oscilloscope
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
實現代碼:
1 #include <reg52.h> 2 typedef unsigned char uchar; 3 typedef unsigned int uint; 4 sbit PWM = P2 ^ 0; 5 uchar n = 0; 6 void Delay(uchar m) 7 { 8 uchar a, b, c; 9 while(m--) 10 for (c = 19; c > 0; --c) 11 for (b = 20; b > 0; --b) 12 for (a = 130; a > 0; --a); 13 } 14 void PWMout(uchar n) 15 { 16 PWM = 0; //先置PWM信號為低電平,此時可以看到在波形圖上出現波峰 17 Delay(10 - n); //延時10-n(ms) 18 PWM = 1; //置PWM信號為高電平,此時波形圖出現波谷 19 Delay(n); //延時n(ms) 20 } 21 int main() 22 { 23 EA = 1; //通過按鈕中斷來修改n的值 24 EX0 = 1; 25 IT0 = 1; 26 while(1) 27 { 28 PWMout(n); //脈衝輸出子程式 29 } 30 } 31 void Int0()interrupt 0 32 { 33 if (n == 10) //n在0-10中迴圈 34 n = 0; 35 else ++n; 36 }