有人工裁判,就會有爭執
1568
2025-04-02
#include "STC15W4K.H" // 包含STC15W4K寄存器定義文件 void main() { //占空比 = (1-CCAPnH/256)*100% //CCAPnH = (1 - 占空比)*256 // (1-0.875)*256 = 32 = 20H //對應頻率為 = SYSclk/12/256 = 22118400/12/256 =7.2K CCAPM0=0x42; // 設置PCA模塊為PWM輸出方式。 CR=1; // PCA計數器開始運行 CCAP0H=0x20; // 脈寬控制 87.5% while(1); // 讓程序停在這里。 }
1
2
3
4
5
6
7
8
9
10
11
12
13
注意:使用PWM功能,單片機IO口會自動切換到強推挽輸出模式,所以我們不需要對IO口進行配置,但是要注意強推挽意味輸出電流大,不能短路了!!!
上面例子為配置寄存器為系統脈沖的分頻,下面演示利用定時器T0溢出作為輸入脈沖,進行PWM輸出
#include "STC15W4K.H" // 包含 "STC15W4K.H"寄存器定義頭文件 void initPCA() { // 初始化定時器T0為16位自動重裝方式,其溢出脈沖作PCA計數器的時鐘源 TMOD=0x00; // 設置T0為16位自動重裝方式 TH0=0xff; // 定時時間19.53uS TL0=0xDC; TR0=1; // 啟動定時器0 // 初始化PCA模塊1為PWM輸出方式 CMOD=0x84; // #10000100B ,選擇T0為PCA計數器時鐘源 CCAPM1=0x42; // 設置PCA模塊1為8位PWM輸出方式。脈沖在P1.0引腳輸出,PWM無需中斷支持。 CCAP1H=0x20; // 設置脈沖寬度 EA=1; // 開整個單片機所有中斷共享的總中斷控制位 CR=1; // 啟動PCA計數器(CH,CL)計數 } void main (void) { initPCA(); while(1); // 這里可以編寫其它程序 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
使用T0計算定時器初值的方法總結:
所需PWM頻率 = (1/定時時間)/256
定時時間 = 1/(256*所需PWM頻率)
eg 所需200hz
1/(256*200) = 19.63125us
16位定時器12T的計算公式為
初值 = 65536 - SYSclk/12*T = 0xFFDC
下面是配置寄存器的漸變PWM輸出
#include "STC15W4K.H" // 包含STC15W4K寄存器定義文件 #define pulse_width_MAX 0xfa // PWM脈寬最小值,占空比2.3% #define pulse_width_MIN 0x05 // PWM脈寬最大值,占空比98% #define STEP 0x02; // PWM脈寬變化步長 unsigned char pulse_width; // PWM脈寬變量,即存入CCAP0H中的值 void delay(void) { unsigned char i,j,k; for(i=10;i>0;i--) // 注意后面沒分號 for(j=50;j>0;j--) // 注意后面沒分號 for(k=255;k>0;k--); // 注意后面有分號 } void port_mode() // 端口模式 { P0M1=0x00; P0M0=0x00;P1M1=0x00; P1M0=0x00;P2M1=0x00; P2M0=0x00;P3M1=0x00; P3M0=0x00; P4M1=0x00; P4M0=0x00;P5M1=0x00; P5M0=0x00;P6M1=0x00; P6M0=0x00;P7M1=0x00; P7M0=0x00; } void initPWM() { CMOD=0x80; // #10000000B 空閑模式下停止PCA計數器工作 // 選擇PCA時鐘源為Fosc/12,禁止PCA計數器溢出時中斷 CCON = 0; // 清零PCA計數器溢出中斷請求標志位CF // CR = 0, 不允許 PCA 計數器計數,清零PCA 各模塊中斷請求標志位CCFn CL = 0; // 清零PCA 計數器 CH = 0; CCAPM0=0x42; // 設置PCA模塊0為PWM輸出方式。 CR=1; // PCA計數器開始運行 } void PWM_OUT() { // 占空比從最小到最大 pulse_width=pulse_width_MIN; while(1) { if (pulse_width>pulse_width_MAX) break; CCAP0H= pulse_width; pulse_width+=STEP; delay(); } // 占空比從最大到最小 pulse_width=pulse_width_MAX; while(1) { if (pulse_width 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 下面是調T0實現可變PWM輸出的例子 #include "STC15W4K.H" // 包含 "STC15W4K.H"寄存器定義頭文件 #define T0_1 246 // 定時器TO重裝值(10個脈沖溢出) #define T0_2 236 // 定時器TO重裝值(20個脈沖溢出) #define PWM_PluseWidth 255 // PWM脈沖寬度,數字越大,脈寬越窄,占空比越小 void delay20ms(void) { unsigned char i,j,k; for(i=2;i>0;i--) // 注意后面沒分號 for(j=198;j>0;j--) // 注意后面沒分號 for(k=150;k>0;k--); // 注意后面有分號 } void port_mode() // 端口模式 { P0M1=0x00; P0M0=0x00;P1M1=0x00; P1M0=0x00;P2M1=0x00; P2M0=0x00;P3M1=0x00; P3M0=0x00; P4M1=0x00; P4M0=0x00;P5M1=0x00; P5M0=0x00;P6M1=0x00; P6M0=0x00;P7M1=0x00; P7M0=0x00; } void initPCA() { // 初始化定時器T0為8位自動重裝方式,其溢出脈沖作PCA計數器的時鐘源 TMOD=0x02; // 設置T0為8位自動重裝方式 TH0=T0_1; // 來256-246=10個脈沖就中斷 TL0=T0_1; // 來256-246=10個脈沖就中斷 TR0=1; // 啟動定時器0 // 初始化PCA模塊1為8位PWM輸出方式 CMOD=0x84; // #10000100B 空閑模式下停止PCA計數器工作 // PCA時鐘源選擇T0溢出信號,禁止PCA計數器溢出時中斷 CCON=0; // 清零PCA計數器溢出中斷請求標志位CF // CR = 0, 不允許 PCA 計數器計數,清零PCA 各模塊中斷請求標志位CCFn CL=0; // 清零PCA 計數器 CH=0; CCAPM1=0x42; // 設置PCA模塊1為8位PWM輸出方式。脈沖在P1.0引腳輸出,PWM無需中斷支持。 PCA_PWM1=0; // 清0 PWM 模式下的第9位 CCAP1H=PWM_PluseWidth; // 設置脈沖寬度 EA=1; // 開整個單片機所有中斷共享的總中斷控制位 CR=1; // 啟動PCA計數器(CH,CL)計數 } void main (void) { port_mode(); // 所有IO口設為準雙向弱上拉方式。 initPCA(); while(1) // 等待中斷 { // P1.0 輸出高頻PWM極窄脈沖 TH0=T0_1; // 來256-246=10個脈沖就中斷 TL0=T0_1; // 來256-246=10個脈沖就中斷 CCAP1H=PWM_PluseWidth; // 設置脈沖寬度 delay20ms(); // P1.0 輸出低頻PWM極窄脈沖 TH0=T0_2; // 來256-236=20個脈沖就中斷 TL0=T0_2; // 來256-236=20個脈沖就中斷 delay20ms(); // P1.0 輸出高頻PWM窄脈沖 TH0=T0_1; // 來256-246=10個脈沖就中斷 TL0=T0_1; // 來256-246=10個脈沖就中斷 CCAP1H=PWM_PluseWidth>>2; // 設置脈沖寬度 delay20ms(); // P1.0 輸出低頻PWM窄脈沖 TH0=T0_2; // 來256-236=20個脈沖就中斷 TL0=T0_2; // 來256-236=20個脈沖就中斷 delay20ms(); //P1.0 輸出高頻PWM寬脈沖 TH0=T0_1; // 來256-246=10個脈沖就中斷 TL0=T0_1; // 來256-246=10個脈沖就中斷 CCAP1H=PWM_PluseWidth>>4; delay20ms(); // P1.0 輸出低頻PWM寬脈沖 TH0=T0_2; // 來256-236=20個脈沖就中斷 TL0=T0_2; // 來256-236=20個脈沖就中斷 delay20ms(); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 單片機 嵌入式
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。