STM32 輸出方波的方法有兩種比較類似的,一個是PWM模式,一個是輸出比較模式。下面來看看這兩種模式的不同處在哪。
先看看官方對兩種模式的介紹
PWM模式:
輸出比較模式
通過兩種模式的介紹,好像不能直觀的看出來具體差別在哪,再看看兩種模式設置時寄存器裏面的介紹。
通過CCMR寄存器中的OCM位可以看出來這兩種模式的一點區別。
輸出比較模式下: CCR = CNT 時,翻轉輸出電平。
PWM模式下: CNT < CCR時輸出一種電平,CNT > CCR時輸出相反的電平。
通過圖片來直觀的看看這兩種模式的區別。
PWM模式下: ARR 決定輸出頻率 ,CCR決定輸出佔空比。
輸出比較模式下: ARR 決定輸出頻率 CCRx 決定每個通道的初始相位。
兩種模式下最主要的差別就是CCR值代表的含義不一樣。PWM模式下CCR可以控制佔空比。輸出比較模式下CCR可以控制初始相位。
下面通過一個程序來對比一下這兩種模式
#include "pwm.h"
void TIM3_PWM_Init( u16 arr, u16 psc )
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE ); //使能定時器3時鐘
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //使能GPIO和AFIO複用功能模塊時鐘
//設置TIM3 CH3
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOB, &GPIO_InitStructure );
//初始化TIM3
TIM_TimeBaseInitStructure.TIM_Period = arr;
TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit( TIM3, &TIM_TimeBaseInitStructure );
//初始化TIM3_CH3 PWM 模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC3Init( TIM3, &TIM_OCInitStructure );
//使能TIM3在CCR2上的預裝載寄存器
TIM_OC3PreloadConfig( TIM3, TIM_OCPreload_Enable );
//使能TIM3
TIM_Cmd( TIM3, ENABLE );
}
void TIM3_CMP_Init( u16 arr, u16 psc )
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE ); //使能定時器3時鐘
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE ); //使能GPIOC時鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//初始化TIM3
TIM_TimeBaseInitStructure.TIM_Period = arr;
TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit( TIM3, &TIM_TimeBaseInitStructure );
//初始化TIM3_CH4 比較 模式 輸出比較翻轉觸發模式(當計數值與比較/捕獲寄存器值相同時,翻轉輸出引腳的電平)
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC4Init( TIM3, &TIM_OCInitStructure );
TIM_OC4PreloadConfig( TIM3, TIM_OCPreload_Enable );
//使能TIM3
TIM_Cmd( TIM3, ENABLE );
}
將定時器3通道3設置爲PWM輸出模式,定時器3通道4設置爲輸出比較模式。
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "pwm.h"
// LED0 PA8 LED1 PD2
int main(void)
{
u16 led_pwm_val=0;
u8 dir=1;
delay_init(); //延時函數初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
LED_Init();
LED0 = 1;
LED1 = 1;
delay_ms(500);
LED0 = 0;
LED1 = 0;
//比較輸出模式下: ARR 決定輸出頻率 CCRx 決定每個通道的初始相位
//PWM模式: ARR 決定輸出頻率 CCRx 決定輸出 的高電平時長
TIM3_PWM_Init(1000-1,72-1);
//比較翻轉模式,一個週期只翻轉一次,所以頻率爲 1/2
TIM3_CMP_Init(1000-1,71-1);
TIM_SetCompare3(TIM3,100); //PWM 模式
TIM_SetCompare4(TIM3,100); //比較輸出模式
while(1)
{
delay_ms(200);
LED0 = !LED0;
}
}
主函數中分別初始化兩種模式,然後設置CCR值爲相同值,看看輸出波形的區別。
藍色波形爲 PWM模式輸出的波形,粉色爲輸出比較模式輸出的波形。可以看到同樣的設置參數,PWM輸出方波頻率爲1KHz,輸出比較輸出的方波爲500Hz,說明輸出比較模式的頻率爲PWM模式頻率的1/2。
PWM輸出波形的高電平爲100us,週期爲1000us,佔空比爲10%,和主函數中設置的一樣。
輸出比較模式輸出的波形起始相位滯後於PWM波形100us,滯後相位差爲PWM波形的10%,滯後相位差爲本身輸出波形的20%。
輸出比較模式的佔空比爲50%,是固定的不能修改佔空比。
通過上面實驗可以看到,這兩種模式的主要差別是。
PWM模式: ARR設置頻率,CCR設置佔空比,頻率和佔空比可以任意設置,起始相位不能設置。
輸出比較模式:ARR設置頻率,CCR設置相位,頻率和起始相位可以任意設置,佔空比不能設置。輸出頻率爲理論計算值一半。