一、前期準備
- 硬件:STM32F103C8T6開發板
- 調試工具:DAPLink(本次使用)或USB-TTL
- 開發環境:STM32CubeMX、Keil、Vscode(可選)
- LED:使用PA0(TIM2_CH1)輸出PWM,LED的陰極接GND
二、使用定時器中斷產生PWM
STM32F103C8T6在72MHz的計數時鐘下,可實現最大59.65s的定時。
- ?STM32F103C8T6定時器資源:TIM1、TIM2、TIM3、TIM4
- 時基單元:16位預分頻器 + 16位計數器 + 16位自動重裝載寄存器
計數模式:
1. 向上計數模式(常用):從0開始累加,到自動重裝值觸發中斷。
2. 向下計數模式:從自動重裝值遞減,到0觸發中斷
3. 中央對齊計數模式:從0開始累加,到自動重裝載值觸發中斷,然后遞減,到0再次觸發中斷。常用于電機控制的SVPWM算法中。
TIM輸出比較原理:
- OC(Output Compare):輸出比較,輸出比較可以通過比較CNT與CCR寄存器值的關系,來對輸出電平進行置1、置0或翻轉的操作,用于輸出一定頻率和占空比的PWM波形。每個高級定時器和通用定時器都擁有4個輸出比較通道OC1~4。
- CCR(Capture Compare):捕獲比較寄存器
PWM(Pulse Width Modulation)脈沖寬度調制
- 頻率 = 1 / TS,一般在 幾kHz~幾十kHz。
- 占空比 = TON / TS
- 分辨率 = 占空比變化步距,也就是占空比變化的精細程度。一般1%足夠使用。
注:定時中斷的頻率就是PWM波的頻率,只不過占空比的變化范圍由自動重裝載值ARR決定。
輸出比較模式:常用PWM模式1
?
2.1 PWM參數計算
- PWM頻率: Freq = CK_PSC / (PSC + 1) / (ARR + 1)
- PWM占空比: Duty = CCR / (ARR + 1),CCR值可以設置PWM的占空比,因此ARR常設為100-1
- PWM分辨率: Reso = 1 / (ARR + 1),即PWM的步長
參數說明:
- CK_PSC:時鐘源頻率,72MHz
- PSC:預分頻器寄存器的值
- ARR:自動重裝寄存器的值
- CCR:捕獲比較寄存器的值
案例1:假如驅動SG90舵機:PWM頻率為50Hz,即周期20ms
- PSC = 72-1
- ARR = 20K-1
案例2:輸出頻率為10K的PWM
- 先確定ARR的值:ARR = 100-1
- 再設置PSC的值:PSC = 72-1
2.2 STM32F103C8T6通用定時器輸出通道
- 因為涉及到GPIO的復用功能,所以要使用定時器輸出PWM時,GPIO的工作模式需要設置為復用推挽輸出模式
序號 | 主功能 | 默認復用功能 |
1 | PA0 | TIM2_CH1 |
2 | PA1 | TIM2_CH2 |
3 | PA2 | TIM2_CH3 |
4 | PA3 | TIM2_CH4 |
5 | PA6 | TIM3_CH1 |
6 | PA7 | TIM3_CH2 |
7 | PB0 | TIM3_CH3 |
8 | PB1 | TIM3_CH4 |
9 | PB6 | TIM4_CH1 |
10 | PB7 | TIM4_CH2 |
11 | PB8 | TIM4_CH3 |
12 | PB9 | TIM4_CH4 |
三、STM32CubeMX配置
1.設置RCC:使用外部高速時鐘HSE
?2.SYS配置:配置成 SWD協議下載和調試
3.?定時器配置
使用TIM2,輸出PWM頻率10K
- 設置ARR = 100-1
- 設置PSC = 72-1
TIM2時鐘源配置、通道輸出配置:?GPIO的工作模式會自動被設置為復用推挽輸出模式
工作參數設置:PWM模式1
- ?ARR:決定PWM的分辨率
- CCR:PWM的占空比
4.時鐘樹配置:72MHz
?5.導出代碼:之后步驟參考之前的就可以了
四、程序編寫
// 在TIMX_CH1通道上輸出占空比為CompareValue的PWM
__STATIC_INLINE void LL_TIM_OC_SetCompareCH1(TIM_TypeDef *TIMx, uint32_t CompareValue)
{WRITE_REG(TIMx->CCR1, CompareValue);
}
/* USER CODE BEGIN WHILE */LL_TIM_EnableAllOutputs(TIM2);LL_TIM_EnableCounter(TIM2); // 使能計數LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH1); // 使能輸出比較通道while (1){for (uint16_t i = 0; i <= 100; i++){LL_TIM_OC_SetCompareCH1(TIM2, i); // PA0(TIM2_CH1)輸出占空比為i的PWMLL_mDelay(10);}for (uint16_t i = 0; i <= 100; i++){LL_TIM_OC_SetCompareCH1(TIM2, 100 - i);LL_mDelay(10);}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */