脈寬調製(PWM,Pulse Width Modulation)是利用微處理器的數字輸出來對模擬電路進行控制的一種非常有效的技術,廣泛應用在從測量、通信到功率控制與變換的許多領域中。
常見的用法是輸出一路PWM波,可以通過調節PWM的頻率和佔空比來控制電路。還有另一種方法是輸出一組互補的PWM波,這兩個波形頻率相同,相位相反,兩組波形之間有死區控制時間。
STM8單片機自帶PWM互補波形輸出功能,通過資料可以看出 STM8共有3個死區時間可調的互補輸出。
本次實驗用的STMs8003單片機有2個互補輸出。
PC6口和PC3口是定時器1通道1互補輸出。PC7口和PC4口是定時器1通道2互補輸出。
要配置輸出互補PWM波,只需要在輸出PWM的基礎上,開啓互補輸出功能就行。
只需要在CCER寄存器中開啓CCxNE寄存器,就能開啓互補輸出功能。
如果需要設置死區時間,還需要配置DTR寄存器。
下來看一下程序中如何配置
void PWM_GPIO_Init( void )
{
PC_DDR |= ( 1 << 6 ); //PC6 推輓輸出
PC_CR1 |= ( 1 << 6 );
PC_DDR |= ( 1 << 3 ); //PC3 推輓輸出
PC_CR1 |= ( 1 << 3 );
PC_DDR |= ( 1 << 7 ); //PC7 推輓輸出
PC_CR1 |= ( 1 << 7 );
PC_DDR |= ( 1 << 4 ); //PC4 推輓輸出
PC_CR1 |= ( 1 << 4 );
}
設置 IO口,將IO口設置爲推輓輸出。
下來初始化定時器
#define FRE 320
//定時器1初始化
void TIM1_Init( void )
{
PWM_GPIO_Init();
TIM1_CR1 = (1<<7); //自動預裝載允許
//設置TIM1 CH1 與 TIM1 CH1N通道
TIM1_CCMR1 = (6<<4)|(1<<3)|(1<<2); //TIM1 CH1 PWM1 輸出比較1預裝載使能 輸出比較1 快速使能
//TIM1_CCER1 |= 0x01; //CC1爲輸出 高電平有效
TIM1_CCER1 |= (1<<0)|(1<<2); //CC1爲輸出 OC1高電平有效 開啓OC1N OC1N高電平有效
//設置TIM1 CH2 與 TIM1 CH2N通道
TIM1_CCMR2 =(6<<4)|(1<<3)|(1<<2); //TIM1 CH2 輸出模式 PWM1 輸出比較2預裝載使能 輸出比較2 快速使能
//TIM1_CCER1 |= (1<<4); //CC2爲輸出 關閉互補輸出
TIM1_CCER1 |= (1<<4)|(1<<6); //CC2爲輸出 互補輸出使能
TIM1_PSCRH = 0x00; //預分頻 0
TIM1_PSCRL = 0x00; //16M
TIM1_ARRH = FRE >> 8; //設定自動重裝載值高8位
TIM1_ARRL = FRE; //設置自動重裝載值低8位
//TIM1_BKR |= (1<<7)|(1<<4); //剎車寄存器 使能OC1輸出 定時器不工作時輸出無效電平 開啓剎車輸入 剎車輸入低電平有效
TIM1_BKR |= (1<<7); //主輸出使能 關閉剎車輸入
TIM1_DTR = 0x18; //死區時間 24*125ns=3000ns
TIM1_EGR = (1<<0); //產生更新事件
TIM1_CR1 |= 0x01; //使能計數器
}
定時器初始化完成後,用一個單獨的函數來調節PWM的佔空比。
//TIM1 CH1 PC6
void TIM1_CH1_OUT( unsigned int DC )
{
TIM1_CCR1H = DC >> 8; //捕獲比較寄存器高8位
TIM1_CCR1L = DC; //捕獲比較寄存器低8位 佔空比值
}
//TIM1 CH2 PC7
void TIM1_CH2_OUT( unsigned int DC )
{
TIM1_CCR2H = DC >> 8;
TIM1_CCR2L = DC;
}
下來在主函數中調用佔空比修改函數,就能設置佔空比了。
void main( void )
{
SysClkInit();
__asm( "sim" ); //禁止中斷
TIM1_Init();
__asm( "rim" ); //開啓中斷
delay_ms( 500 );
TIM1_CH1_OUT(FRE/3); //設置佔空比爲33%
TIM1_CH2_OUT(FRE/3);
while( 1 )
{
}
}
主函數就比較簡單了,初始化完定時器,然後設置輸出佔空比就可以了。
下來還有一個最重要的步驟,需要配置STM8的選項字。因爲互補輸出不是IO口的默認功能,要使用互補輸出還需要將引腳功能手動設置爲互補輸出。
設置選項字比較簡單的方法就是通過STVP軟件設置,詳細設置方法參見 如何設置STM8單片機選項字 這篇博客。
打開STVP軟件,然後添加要燒寫的HEX文件。
然後切換到 OPTION BYTE界面
AR7 ---- AR0就是設置IO口默認功能選項。
點一下AFR7後面選項那個倒三角符號
然後在出現的下拉框中選擇 Port C3 Alternate Function = TIM1_CH1N,Port C4 Alternate Function = TIM1_CH2N選項。
這個選項的意思就是將PC3設置爲定時器1通道1互補輸出功能,將PC4設置爲定時器1通道2互補輸出功能。而默認選項的是將PC3設置爲定時器1通道3,將PC4設置爲定時器1通道4。
如果不設置選項字,剛纔的程序燒寫後,單片機的PC3和PC4引腳是沒有任何波形輸出的。
按照同樣的方法設置AFR0選項,將PC6和PC7設置爲定時器功能。
設置完成後如下圖所示
只需要設置AFR7和AFR0兩個選項就行,其他的爲默認值。如果互補輸出時用到了剎車功能,這裏就還要設置一個AFR4選項。本次實驗中沒有用到剎車功能,所以就不需要設置AFR4。設置完成後燒寫程序就行。
輸出波形如下所示
可以看到兩個波形是互補輸出的,但是兩個波形佔空比相差比較大,這是因爲爲了方便觀察,將死區時間設置的比較大,代碼中的死區時間爲3us。
在代碼中將死區時間設置爲250ns
再看下輸出波形
死區時間設置比較小的時候,輸出的波形,看起來基本對稱了。
這時PWM的互補輸出功能就成功實現了。