STM32CubeMX timer PWM output
Knowledge Encyclopedia – Introduction to PWM
PWM is a method of digitally encoding the level of an analog signal. Through the use of high resolution counters, the duty cycle of the square wave is modulated to encode the level of a specific analog signal. The PWM signal is still digital because at any given moment, full-scale DC power is either completely on (ON) or not at all (OFF). A voltage or current source is applied to an analog load in a repetitive pulse sequence of ON or OFF. When it is on, it is when the DC power supply is added to the load, and when it is off, it is when the power supply is disconnected. Any analog value can be encoded using PWM as long as the bandwidth is sufficient.
Pulse Width Modulation (PWM, Pulse Width Modulation) is a very effective technology that uses the digital output of a microprocessor to control analog circuits, and is widely used in many fields from measurement, communication to power control and conversion.
One advantage of PWM is that the signal from the processor to the controlled system is in digital form, and then digital-to-analog conversion is performed. Can minimize the impact of noise (can be the same as a computer). Noise can only affect a digital signal if it is strong enough to change a logic 1 to a logic 0 or a logic 0 to a logic 1.
Introduction to STM32 timer PWM output
The timer pulse width modulation mode can generate a signal with a frequency determined by the TIMx_ARR register and a duty cycle determined by the TIMx_CCRx register. Writing '110' (PWM mode 1) or '111' (PWM mode 2) to the OCxM bit in the TIMx_CCMRx register can independently set each OCx output channel to generate a PWM. The OCxPE bit of the TIMx_CCMRx register must be set to enable the corresponding preload register, and finally the ARPE bit of the TIMx_CR1 register must be set (in up-counting or centrosymmetric mode) to enable the auto-reload preload register.
The preload registers are transferred to the shadow registers only when an update event occurs, so all registers must be initialized by setting the UG bit in the TIMx_EGR register before the counter starts counting. The polarity of OCx can be set by software with CCxP bit in TIMx_CCER register, it can be set as active high or active low. The CCxE bit in the TIMx_CCER register controls the OCx output enable.
- Introduction to PWM mode
In the up-counting mode of the counter (that is, the DIR bit of TIMx_CR1 is 0), when TIMx_CNT<TIMx_CCRx, the PWM signal reference OCxREF is high, otherwise it is low. If the comparison value in TIMx_CCRx is greater than the auto-reload value (TIMx_ARR), OCxREF remains '1'. If the compare value is 0, OCxREF remains '0'. The figure below is an example of an edge-aligned PWM waveform when TIMx_ARR=8 (ARR reload register, indicating the counting period of the timer).
This example implements IO output mode – PWM waveform output. Take LED driving as an example, use advanced timer function (PWM mode) to realize breathing light effect.
1. Hardware interface
There are 3 LED lights on this hardware platform: LED2, LED3, LED4 LED2 is connected to PA1, LED2 is connected to PB8, LED4 is connected to PB9
. CH2 corresponds to external pins PB8 and PB9.
2 Software Design
Open the STM32CubeMX tool, configure timer 4, configure PB8 as channel 3 of timer 4 (multiplexing push-pull output), and configure PB9 as channel 4 of timer 4 (multiplexing push-pull output).
Timer 4 basic configuration and PWM mode configuration Configure
the timer channel mode as PWM mode, set the frequency division factor as 72, reload value as 500, and set the active level as low level.
3. Parameter description
model | illustrate |
---|---|
Input capture direct mode | Input Capture Direct Mode |
Input capture indirectmode | input capture indirect mode |
Input capture triggered by TRC | Input capture trigger mode |
Output compare no output | Output Compare (Freeze Mode 000) |
Output compare CH3 | Output Compare (001) |
PWM Generation No output | PWM produces no output |
PWM Generation CH3 | PWM output to CH3 |
CH3 Combined channels | joint channel |
xor activation | Timer Input XOR Mode |
4. Code generation
TIM4 basic function configuration
/* TIM4 init function */
void MX_TIM4_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {
0};
TIM_MasterConfigTypeDef sMasterConfig = {
0};
TIM_OC_InitTypeDef sConfigOC = {
0};
htim4.Instance = TIM4;//定时器4
htim4.Init.Prescaler = 72-1;//分频系数72分频
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;//向上计数方式
htim4.Init.Period = 300;//重装装载值
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;//无时钟分频
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;//自动重装载预装载使能
if (HAL_TIM_Base_Init(&htim4) != HAL_OK)//初始化定时器
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;//PWM模式1,CNT<CCR为有效电平
sConfigOC.Pulse = 0;//占空比
sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;//有效电平时间
sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;//快速比较使能
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)//PWM模式初始化
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
{
Error_Handler();
}
HAL_TIM_MspPostInit(&htim4);//硬件层初始户化
}
PWM mode configuration:
PB8, PB9 pin configuration and PWM mode enable
HAL_TIM_PWM_Start(timHandle,TIM_CHANNEL_3);//初始化通道3
HAL_TIM_PWM_Start(timHandle,TIM_CHANNEL_4);//初始化通道4
Pin mode configuration and PWM initialization
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {
0};
if(timHandle->Instance==TIM4)
{
/* USER CODE BEGIN TIM4_MspPostInit 0 */
/* USER CODE END TIM4_MspPostInit 0 */
__HAL_RCC_GPIOB_CLK_ENABLE();
/**TIM4 GPIO Configuration
PB8 ------> TIM4_CH3
PB9 ------> TIM4_CH4
*/
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN TIM4_MspPostInit 1 */
HAL_TIM_PWM_Start(timHandle,TIM_CHANNEL_3);//启动通道3
HAL_TIM_PWM_Start(timHandle,TIM_CHANNEL_4);//启动通道4
/* USER CODE END TIM4_MspPostInit 1 */
}
}
4. Example of the main function of the breathing light
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/*实现呼吸灯*/
if(flag==0)i++;
else i--;
if(i>=300)flag=1;
if(i==0)flag=0;
HAL_Delay(3);
htim4.Instance->CCR3=i;//调节占空比
htim4.Instance->CCR4=i;
}
5. Introduction to common functions of HAL library timer
The source code of the basic function functions of the timer in the HAL library is in stm32f1xx_hal_tim.c, and the advanced function functions are in stm32f1xx_hal_tim_ex.c. This section mainly introduces several commonly used functions. (The functions listed below may need to be called or modified by the user).
/*硬件层初始化:时钟、中断,DMA*/
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim);
/*中断方式开启定时器*/
HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);
/*DMA方式开启定时器*/
HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length);
/*开启定时器PWM模式*/
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
/*获取状态*/
HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(TIM_HandleTypeDef *htim);
/*中断方式开启定时器输入捕获功能*/
HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
6. Software simulation effect display
Through KEIL software simulation, check the pin level change, KEIL software related settings:
CPU DLL: SARMCM3.DLL
Dialog DLL: DARMSTM.DLL Parameter: -pSTM32F103C8
Enter simulation mode:
Check the pin level change waveform:
Waveform effect: