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