最近在弄STM8S,依照網(wǎng)上的實(shí)驗(yàn)教程調(diào)試PWM程序,總是沒有輸出,有沒有人用過這個(gè)全程,好像是風(fēng)馳的教程
STM8的C語(yǔ)言編程(14)-- PWM
在單片機(jī)應(yīng)用系統(tǒng)中,也常常會(huì)用到PWM信號(hào)輸出,例如電機(jī)轉(zhuǎn)速的控制,F(xiàn)在很多高檔的單片機(jī)也都集成了PWM功能模塊,方便用戶的應(yīng)用。 對(duì)于PWM信號(hào),主要涉及到兩個(gè)概念,一個(gè)就是PWM信號(hào)的周期或頻率,另一個(gè)就是PWM信號(hào)的占空比。例如一個(gè)頻率為1KHZ,占空比為30%,有效信號(hào)為1的PWM信號(hào),在用示波器測(cè)量時(shí),就是高電平的時(shí)間為300uS,低電平的時(shí)間為700uS的周期波形。 在單片機(jī)中實(shí)現(xiàn)PWM信號(hào)的功能模塊,實(shí)際上就是帶比較器的計(jì)數(shù)器模塊。首先該計(jì)數(shù)器循環(huán)計(jì)數(shù),例如從0到N,那么這個(gè)N就決定了PWM的周期,PWM周期=(N+1)*計(jì)數(shù)器時(shí)鐘的周期。在計(jì)數(shù)器模塊中一定還有一個(gè)比較器,比較器有2個(gè)輸入,一個(gè)就是計(jì)數(shù)器的當(dāng)前值,另一個(gè)是可以設(shè)置的數(shù),這個(gè)數(shù)來(lái)自一個(gè)比較寄存器。當(dāng)計(jì)數(shù)器的值小于比較寄存器的值時(shí),輸出為1(可以設(shè)置為0),當(dāng)計(jì)數(shù)器的值大于或等于比較寄存器的值時(shí),輸出為0(也可設(shè)置為1,與前面對(duì)應(yīng))。 了解了這個(gè)基本原理后,我們就可以使用STM8單片機(jī)中的PWM模塊了。下面的實(shí)驗(yàn)程序首先將定時(shí)器2的通道2設(shè)置成PWM輸出方式,然后通過設(shè)置自動(dòng)裝載寄存器TIM2_CCR2,決定PWM信號(hào)的周期。在程序的主循環(huán)中,循環(huán)修改占空比,先是從0逐漸遞增到128,然后再?gòu)?28遞減到0。 當(dāng)把下面的程序在ST的三合一板上運(yùn)行時(shí),可以看到發(fā)光二極管LD1逐漸變亮,然后又逐漸變暗,就這樣循環(huán)往復(fù)。如果用示波器看,可以看到驅(qū)動(dòng)LD1的信號(hào)波形的占空比從0變到50%,然后又從50%變到0。 同樣還是利用ST的開發(fā)工具,生成一個(gè)C語(yǔ)言程序的框架,然后修改其中的main.c,修改后的代碼如下。
// 程序描述:用PWM輸出驅(qū)動(dòng)LED
#include"STM8S207C_S.h"
voidCLK_Init(void); voidTIM_Init(void);
// 函數(shù)功能:延時(shí)函數(shù) // 輸入?yún)?shù):ms -- 要延時(shí)的毫秒數(shù),這里假設(shè)CPU的主頻為2MHZ // 輸出參數(shù):無(wú) // 返 回 值:無(wú) // 備 注:無(wú) voidDelayMS(unsigned int ms) { unsigned char i; while(ms != 0) { for(i=0;i<250;i++) { } for(i=0;i<75;i++) { } ms--; } }
// 函數(shù)功能:初始化時(shí)鐘 // 輸入?yún)?shù):無(wú) // 輸出參數(shù):無(wú) // 返 回 值:無(wú) // 備 注:無(wú) voidCLK_Init() { CLK_CKDIVR = 0x11; // 10:fHSI = fHSI RC output/ 4 // = 16MHZ / 4 =4MHZ // 001: fCPU=fMASTER/2. = 2MHZ }
// 函數(shù)功能:初始化定時(shí)器2的通道2,用于控制LED的亮度 // 輸入?yún)?shù):無(wú) // 輸出參數(shù):無(wú) // 返 回 值:無(wú) // 備 注:無(wú) voidTIM_Init() { TIM2_CCMR2 = TIM2_CCMR2 | 0x70;// Output modePWM2. //通道2被設(shè)置成比較輸出方式 // OC2M = 111,為PWM模式2, // 向上計(jì)數(shù)時(shí),若計(jì)數(shù)器小于比較值,為無(wú)效電平 // 即當(dāng)計(jì)數(shù)器在0到比較值時(shí),輸出為1,否則為0 TIM2_CCER1 = TIM2_CCER1 | 0x30;// CC polarity low,enable PWMoutput */ // CC2P = 1,低電平為有效電平 // CC2E = 1,開啟輸出引腳
//初始化自動(dòng)裝載寄存器,決定PWM方波的頻率,F(xiàn)pwm=4000000/256=15625HZ TIM2_ARRH = 0; TIM2_ARRL = 0xFF;
//初始化比較寄存器,決定PWM方波的占空比 TIM2_CCR2H = 0; TIM2_CCR2L = 0;
// 初始化時(shí)鐘分頻器為1,即計(jì)數(shù)器的時(shí)鐘頻率為Fmaster=4MHZ TIM2_PSCR = 0; // 啟動(dòng)計(jì)數(shù) TIM2_CR1 = TIM2_CR1 | 0x01; }
main() { unsigned char i;
CLK_Init(); // 初始化時(shí)鐘 TIM_Init(); // 初始化定時(shí)器
while(1) // 進(jìn)入無(wú)限循環(huán) { // 下面的循環(huán)將占空比逐漸從0遞增到50% for(i=0;i<128;i++) { TIM2_CCR2H = 0; TIM2_CCR2L = i; DelayMS(5); }
// 下面的循環(huán)將占空比逐漸從50%遞減到0 for(i=128;i>0;i--) { TIM2_CCR2H = 0; TIM2_CCR2L = i; DelayMS(5); } } } //========================================
//上面這個(gè)實(shí)例老是調(diào)不通,不知道為什么??
//========================================
由于上面的例子總是調(diào)試不好,就換了個(gè)例子,但也是調(diào)不通,不知道是不是我哪里弄錯(cuò)了在輸出模式下,該寄存器的值與 CNT 的值比較,根據(jù)比較結(jié)果產(chǎn)生相應(yīng)動(dòng)作。利用這點(diǎn),我們通過修改這個(gè)寄存器的值,就可以控制 PWM 的輸出脈寬了。 #include "iostm8s207rb.h" void CLK_Init(void); void TIM2_PWM2_Init(void); void delay_ms(int value); main() { unsigned char i; CLK_Init(); // 初始化時(shí)鐘 TIM2_PWM2_Init(); // 初始化定時(shí)器的PWM功能 while(1) // 進(jìn)入無(wú)限循環(huán) { // 下面的循環(huán)將占空比逐漸從0遞增到50% for(i=0;i<100;i++) { TIM2_CCR2H = 0; TIM2_CCR2L = i; delay_ms(10); } // 下面的循環(huán)將占空比逐漸從50%遞減到0 for(i=100;i>0;i--) { TIM2_CCR2H = 0; TIM2_CCR2L = i; delay_ms(10); } } } // 函數(shù)功能:初始化定時(shí)器2的通道2,用于控制LED的亮度 void TIM2_PWM2_Init() { TIM2_CCMR2 = TIM2_CCMR2 | 0x70;// Output mode PWM2. // 通道2被設(shè)置成比較輸出方式 // OC2M = 111,為PWM模式2, // 向上計(jì)數(shù)時(shí),若計(jì)數(shù)器小于比較值,為無(wú)效電平 // 即當(dāng)計(jì)數(shù)器在0到比較值時(shí),輸出為1,否則為0 TIM2_CCER1 = TIM2_CCER1 | 0x10;// CC polarity low,enable PWM output // CC2P = 0,高電平為有效電平 // CC2E = 1,開啟輸出引腳 //初始化自動(dòng)裝載寄存器,決定PWM方波的頻率,F(xiàn)pwm=4000000/200=20KHZ TIM2_ARRH = 0; TIM2_ARRL = 0xC8; //200 //初始化比較寄存器,決定PWM方波的占空比 TIM2_CCR2H = 0; TIM2_CCR2L = 0; // 初始化時(shí)鐘分頻器為4,即計(jì)數(shù)器的時(shí)鐘頻率為Fmaster=16MHZ,CK_CNT = 4M TIM2_PSCR = 2; // 啟動(dòng)計(jì)數(shù) TIM2_CR1 = TIM2_CR1 | 0x01; } void CLK_Init() { CLK_CKDIVR =0x00; //16M主頻 } /* ******************************************** 簡(jiǎn)單延時(shí)程序 ******************************************** */ void delay_ms(int value) { int i,j; if(value < 1) value = 1; for(i=0;i!=value;++i) for(j=0;j!=5000;++j); } //===================================
//上面這個(gè)例子也是沒有調(diào)好
//====================================
|