Introduction and application of PWM-----LED breathing light (2)

This chapter introduces the effect of LED to produce breathing lights. At the end of the article, there is a link to the complete project file, which can be downloaded if necessary.

Introduction to PWM

Pulse Width Modulation (PWM), the abbreviation of "Pulse Width Modulation" in English, referred to as Pulse Width Modulation, is a very effective technology that uses the
digital output of a microprocessor to control an analog circuit. To put it simply, it is
the control of the pulse width.
STM32 timers except TIM6 and 7. Other timers can be used to generate PWM output. The advanced timers
TIM1 and TIM8 can simultaneously generate up to seven PWM outputs. The general-purpose timer can also generate up to 4
PWM outputs at the same time, so that STM32 can generate up to 30 PWM outputs at the same time!

To make the general-purpose timer TIMx of STM32 generate PWM output, we will also use 3 registers to control PWM . These three registers are: capture / compare mode register TIMx_CCMR1/2), capture / compare enable register ( TIMx_CCER ), capture / compare register ( TIMx_CCR1~4 ). Next, we briefly introduce these three registers.

The first is the capture / compare mode register ( TIMx_CCMR1/2 ), there are a total of 2 registers , TIMx _CCMR1
and TIMx_CCMR2 . TIMx_CCMR1 controls CH1 and 2 , while TIMx_CCMR2 controls CH3 and 4 . the register
The descriptions of each person are shown in the figure
Some bits of this register have different functions in different modes, so in the figure , we divide the register into 2 layers, the upper layer corresponds to output and the lower layer corresponds to input. For a detailed description of this register, please refer to Section 14.4.7 on page 288 of the "STM32 Reference Manual" . What we need to explain here is the mode setting bit OCxM , this part consists of 3 bits. A total of 7 modes can be configured , we are using PWM mode, so these 3 bits must be set to 110/111 . The difference between these two PWM modes is that the polarity of the output level is reversed.
Next, we introduce the capture / compare enable register ( TIMx_CCER ), which controls the
Road switch. The description of each bit of the register is shown in the figure:
This register is relatively simple, we only use the CC2E bit here, this bit is the input / capture 2 output enable bit, if you want to
PWM is output from the IO port, this bit must be set to 1 , so we need to set this bit to 1 . This register is described in more detail
Introduced, please refer to the section 14.4.9 on page 292 of the " STM32 Reference Manual" .
Finally, let 's introduce the capture / compare register ( TIMx_CCR1~4 ), which has a total of 4 , corresponding to 4
Output channel CH1~4 . Because these 4 registers are similar, we only take TIMx_CCR1 as an example to introduce, each of the registers
The bit description is shown in the figure:

 

In the output mode, the value of this register is compared with the value of CNT , and corresponding actions are taken according to the comparison result. take advantage of this,
By modifying the value of this register, we can control the output pulse width of PWM . In this chapter, we use TIM3
Channel 2 , so we need to modify TIM3_CCR2 to achieve pulse width control of DS0 brightness.
We want to use the CH2 output PWM of TIM3 to control the brightness of DS0 , but TIM3_CH2 is connected to PA7 by default
The above, and our DS0 is connected to PB5 , if it is an ordinary MCU , it may only be possible to fly PA7 to PB5 with flying wires
It has been implemented, but we use STM32 , which is more advanced, and can use the remapping function to put TIM3_CH2
Mapped to PB5 .
The remapping control of STM32 is controlled by the multiplexing remapping and debugging IO configuration register ( AFIO_MAPR ), which
The description of each register is shown in the figure:

 What we use here is the remapping of TIM3. As can be seen from the above figure, TIM3_REMAP is controlled by the two bits [11:10] . The TIM3_REMAP[1:0] remapping control table is shown in the table: 

By default, TIM3_REMAP[1:0] is 00 , there is no remapping, so TIM3_CH1~TIM3_CH4 points
Not connected to PA6 , PA7 , PB0 and PB1 , and we want TIM3_CH2 to be mapped to PB5 , we need to set
TIM3_REMAP[1:0]=10 , that is, partial remapping. It should be noted here that TIM3_CH1 is also mapped to PB4 at this time.
So far, we have introduced several related registers to be used in this chapter. In this chapter, we will implement remapping TIM3_CH2
On PB5 , TIM3_CH2 outputs PWM to control the brightness of DS0 . Below we introduce the configuration of the library function
function steps.
The first thing to mention is that the PWM- related functions are set in the library function files stm32f10x_tim.h and stm32f10x_tim.c
in the file.
1 ) Turn on the TIM3 clock and the multiplexing function clock, and configure PB5 as the multiplexing output.
To use TIM3 , we must first turn on the clock of TIM3 , which I believe everyone should understand after reading so many codes.
Here we also need to configure PB5 as a multiplexed output, because the TIM3_CH2 channel will be remapped to PB5 . At this time, PB5
Belongs to the multiplexing function output. The method of enabling the TIM3 clock by the library function is:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // Enable timer 3 clock
The method of setting the AFIO clock by the library function is:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // Multiplex clock enable
These two lines of code are easy to organize, so I won't repeat them here. Just set PB5 as multiplex function output:
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // multiplex push-pull output
2 ) Set TIM3_CH2 to remap to PB5 .
Because TIM3_CH2 is connected to PA7 by default , we need to set TIM3_REMAP as partial remapping (pass
Through AFIO_MAPR configuration), let TIM3_CH2 remap to PB5 . Set the remapping function in the library function
The numbers are:
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState)
STM32 remapping can only be remapped to specific ports. The first entry parameter can be understood as setting the type of remapping. For example, the entry parameter of TIM3 partial remapping is
GPIO_PartialRemap_TIM3 , as the name suggests. Therefore, the implementation method of the library function for partial remapping of TIM3 is:
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
3 ) Initialize TIM3, set ARR and PSC of TIM3 .
After turning on the clock of TIM3 , we need to set the values ​​of the two registers ARR and PSC to control the output PWM
cycle. When the PWM cycle is too slow (below 50Hz ), we will obviously feel the flicker. Therefore, the PWM week
The period here should not be set too small. This is implemented in the library function through the TIM_TimeBaseInit function, and the format of the call is:
TIM_TimeBaseStructure.TIM_Period = arr; // Set auto reload value
TIM_TimeBaseStructure.TIM_Prescaler =psc; // Set the prescaler value
TIM_TimeBaseStructure.TIM_ClockDivision = 0; // Set clock division : TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // Up counting mode
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // Initialize TIMx according to the specified parameters
4 ) Set the PWM mode of TIM3_CH2 and enable the CH2 output of TIM3 .
Next, we need to set TIM3_CH2 to PWM mode (the default is frozen), because our DS0 is low power
It is flat and bright, and we hope that when the value of CCR2 is small, DS0 will be dark, and when the value of CCR2 is large, DS0 will be bright, so I
We need to control the mode of TIM3_CH2 by configuring the relevant bits of TIM3_CCMR1 . In the library function, the PWM channel is set
The setting is set through the function TIM_OC1Init()~TIM_OC4Init() . The setting functions of different channels are different. Here I
We are using channel 2 , so the function used is TIM_OC2Init() .
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
This initialization format should be familiar to everyone, so let's take a look at the structure TIM_OCInitTypeDef
Definition:
typedef struct
{
uint16_t TIM_OCMode;
uint16_t TIM_OutputState;
uint16_t TIM_OutputNState; */
uint16_t TIM_Pulse;
uint16_t TIM_OCPolarity;
uint16_t TIM_OCNPolarity;
uint16_t TIM_OCIdleState;
uint16_t TIM_OCNIdleState;
} TIM_OCInitTypeDef;
Here we explain several member variables related to our requirements:
The parameter TIM_OCMode setting mode is PWM or output comparison, here we are PWM mode.
The parameter TIM_OutputState is used to set the comparative output enable, that is, enable the PWM output to the port.
The parameter TIM_OCPolarity is used to set whether the polarity is high or low.
The other parameters TIM_OutputNState , TIM_OCNPolarity , TIM_OCIdleState and TIM_OCNIdleState are
Only used by advanced timers TIM1 and TIM8 .
To achieve the scenario we mentioned above, the method is:
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; // Select PWM mode 2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // Compare output enable
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // Output polarity is high
TIM_OC2Init(TIM3, &TIM_OCInitStructure); // Initialize TIM3 OC2
5 ) Enable TIM3 .
After completing the above settings, we need to enable TIM3 . The method of enabling TIM3 has been explained before:
TIM_Cmd(TIM3, ENABLE); // Enable TIM3
6 ) Modify TIM3_CCR2 to control the duty cycle.
Finally, after the above settings, the PWM has actually started to output, but its duty cycle and frequency are fixed
, and we can control the output duty cycle of CH2 by modifying TIM3_CCR2 . Then control the brightness of DS0 .
In the library function, the function to modify the duty cycle of TIM3_CCR2 is:
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2)
Of course, for other channels, there is a function name respectively, and the function format is TIM_SetComparex(x=1,2,3,4) .
Through the above 6 steps, we can control CH2 of TIM3 to output PWM wave.

Part of the code program:

PWM initialization

void TIM3_PWM_Init(u16 arr,u16 psc)
{ 
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器 3 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|
RCC_APB2Periph_AFIO, ENABLE); //使能 GPIO 和 AFIO 复用功能时钟
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //重映射 TIM3_CH2->PB5 
//设置该引脚为复用输出功能,输出 TIM3 CH2 的 PWM 脉冲波形 GPIOB.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化 GPIO
//初始化 TIM3
TIM_TimeBaseStructure.TIM_Period = arr; //设置在自动重装载周期值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM 向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //初始化 TIMx
//初始化 TIM3 Channel2 PWM 模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择 PWM 模式 2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性高
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //初始化外设 TIM3 OC2
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能预装载寄存器
TIM_Cmd(TIM3, ENABLE); //使能 TIM3
}

Complete project file: (28 messages) Based on the STM32 punctual atomic PWM output experiment-breathing light-MCU document resources-CSDN library

Guess you like

Origin blog.csdn.net/m0_63171897/article/details/127289633