Based on STM32CubeMX and keil, universal timer interrupt is used to realize fixed PWM & adjustable PWM wave output to realize LED flashing and breathing light respectively.

Preface

In the previous blog, I wrote about the basic timer to achieve LED flashing. It mainly uses a prescaler and counting, plus a level flip. The principle and specific operation are relatively simple.
This blog chooses a universal timer to perform a slightly more difficult effect demonstration, using the function of outputting PWM waves.
This blog writes about outputting fixed PWM and variable PWM to further achieve LED0 flashing and LED0 breathing light effects.
功能实现效果:
PF9 outputs a PWM wave to control LED0 to flash, with a 1s cycle and a state change of 0.5s.
PF9 outputs PWM wave to control LED0 to realize the breathing light, with a clock cycle of 20ms.


1. PWM wave description

PWM wave, Pulse Width Modulation (Pulse Width Modulation), is a technology that adjusts the pulse width in electrical signals. It transmits information or achieves precise control of the output by controlling the duty cycle of the high-level time and low-level time of the signal.
In the PWM wave, the period is fixed, and the period refers to the length of time of a complete high and low level. The pulse width is the duration of high level or low level, which can be adjusted as needed. The pulse width is proportional to the amplitude of the signal, that is, the wider the pulse width, the greater the signal amplitude, and the narrower the pulse width, the smaller the signal amplitude.

The advantages of PWM wave include:
1. Simple and reliable: PWM modulation circuit is relatively simple, low cost and high reliability.
2. High efficiency and energy saving: Since the output average value of the PWM wave can be controlled by adjusting the duty cycle, high-efficiency energy conversion can be achieved and power loss can be reduced.
3. Precise control: By adjusting the pulse width, the output voltage, current or power can be precisely controlled.
4. Strong adaptability: PWM technology is suitable for different types of loads, and the frequency and duty cycle can be adjusted to meet various needs.

简单点概括一下That is, it outputs a square wave of high and low levels, and the duty cycle is adjustable.


2. Universal timer

2.1 Why use TIM14

The first is the functional requirement. This blog is about the blinking and breathing light effects of LED0, so in fact, the output of the PWM wave must be given to the PF9 pin.
We can see from the schematic diagram below that PF9 is not only connected to LED0, but can also be used as the output of TIM14_CH1.
Insert image description here
Insert image description here
If TIM14 is enabled directly in STM32CubeMX, it may not be PF9, because TIM14 has two pins that can be configured in STM32F407. If PA7 is configured, the output PWM wave cannot actually be given to LED0. For convenience here, we use TIM14_CH1 of PF9 of LED0 for configuration.
Insert image description here

2.2 TIM14 function introduction

TIM14 is a kind of general timer. It has the following functions. In this blog, we use the PWM generation function.
1. Timing function: TIM14 can be used as a simple timer for measuring time intervals or durations. The elapsed time is recorded by incrementing the counter value, and the timing accuracy is determined based on the prescaler coefficient and clock source.
2. Timing interrupt: TIM14 can be configured to generate an interrupt request when a specific count value is reached. By setting the counter's auto-reload value and enabling interrupts, interrupt events can be triggered to perform specific tasks or operations.
3.PWM generation: TIM14 can be used to generate simple pulse width modulation (PWM) signals. By setting the automatic reload value of the counter and the value of the comparison register, the frequency and duty cycle of the pulse can be controlled.
4. Single pulse mode: TIM14 also supports single pulse mode, which generates a single pulse signal under specific trigger conditions. The trigger source, trigger polarity and pulse width can be configured for various application scenarios.
5. Capture/compare mode: TIM14 can detect external events or signal edges in input capture mode, and record the current value of the counter. At the same time, it can also be compared with the value in the comparison register in comparison mode to trigger the corresponding event or output behavior.

2.3 Explanation of some configuration parameters

Regarding the prescaler coefficient and other things, please refer to the basic timer interrupt based on STM32F407 to achieve LED flashing based on STM32CubeMX and keil , so I will not go into details here.
Here we only describe some of the new functions of PWM compared to the previous blog, namely PWM Generation Channel 1configuration

Insert image description here

Mode:Here you can choose PWM mode 1 and PWM mode 2. The difference between the two is:
in the former, under incremental counting, as long as CNT<CCR, that is, the value of the counter is less than the value of the set comparison register, the channel is valid. The opposite is true.
In the former, under downward counting, as long as CNT<CCR, that is, the counter value is less than the set comparison register value, the channel is invalid. The opposite is true.
The latter is just the opposite of the former. For example, in the case of incremental counting, CNT<CCR, the channel is invalid. The opposite is true.

Pulse:PWM pulse width, which sets the value of CCR. The value here should be less than the entire counting period.
Output compare preload:Output comparison preload. Similar to auto-reload preload. When this value is enable, we modify the value of CCR (here is the value of pluse). The modified value needs to wait until the next UEV event to take effect, otherwise it will take effect immediately.
Fast Mode:Whether to use the output comparison fast mode is to set the OC1FE bit in the register TIMx_CCMR1 to speed up the impact of the trigger input event on the CC output. Generally, it can be set to Disable.
CH Polarity:Channel polarity. It is the valid state. If it is set to High, when the channel is valid, the output will be high level.


2.4 PWM implementation process & interruption

The overall process of PWM implementation is roughly as follows:
1. 初始化定时器:First, you need to select a suitable timer and initialize its basic configuration. This includes selecting the timer's mode, setting the clock source and prescaler, and configuring the counter's number of bits.
2. 设置PWM周期:Set the period of the PWM wave as needed. This is accomplished by setting the timer's auto-reload value (autoload register). The auto-reload value determines how long the counter counts before reloading and starting counting again, thereby determining the period of the PWM wave.
3. 设置PWM占空比:Set the comparison value of the timer (compare register) according to the desired duty cycle of the PWM waveform. The value of the comparison register determines how long the counter counts before the state of the PWM wave (high level or low level) changes. By appropriately adjusting the comparison value, the desired duty cycle can be achieved.
4. 使能定时器和PWM输出:Enable the timer and enable PWM output. This usually includes enabling the timer counter, turning on the PWM output channel, and configuring the corresponding pins and output ports.
5. 等待定时器中断或轮询:Depending on the specific implementation, you can choose to wait for the timer interrupt request, or poll the timer status to determine whether the comparison value is reached, so as to perform appropriate processing or update the status of the PWM waveform.

When doing this experiment, I used STM32CubeMX to configure a bunch of them. After burning them, I found that it didn't work. I looked at the code carefully and found that it was not enabled.
Next, write down how to enable PWM after the configuration is completed.

2.4.1 Non-interrupt PWM output (LED flashing)

The output of PWM needs to be enabled, and a function needs to be used HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel). The first parameter of this function is an event processing class object of TIM, which is an object of our TIM14 here, and the following is the channel. Because there is only one channel in TIM14, it should be CH1 here.

Before using HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel)this function, you need to use it HAL_TIM_Base_Start(TIM_HandleTypeDef *htim). This function is the precondition of the former, that is, there is Base_Start first, and then PWM_Start. This is also easier to understand, that is, enable some basic functions first, and then enable more advanced functions.
LED flashing is actually a case of fixed duty cycle, so only a fixed duty cycle PWM wave needs to be output without interruption.

2.4.2 Interrupt PWM output (LED breathing light)

Interrupting the PWM output actually triggers an interrupt at the end of each PWM cycle. So just like above, you also need to enable basic functions first, and then enable advanced functions. Because it is an interrupt mode, in addition to initializing the interrupt and configuring the interrupt vector priority, you only need to call the corresponding interrupt-related startup function. Interrupt-related functions usually have an IT(Interrupt after them)

HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);
HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);

The advantage of using interrupts is that I can modify the CCR value in the callback function every time the interrupt is triggered, thereby changing the duty cycle and achieving the breathing light effect.


3. STM32CubeMX configuration

3.1 GPIO configuration

Insert image description here

3.2 Clock configuration

Turn on the external crystal oscillator (in fact, you can not turn it on, it depends on the final frequency setting of your clock. Generally, turning on the external crystal oscillator is to adapt to more clock frequencies when setting the clock). In the clock tree in the picture below, my clock comes from
Insert image description hereinternal The high-speed crystal oscillator actually has nothing to do with whether the external crystal oscillator is turned on or not, because I finally got a frequency of 100MHz using the internal high-speed crystal oscillator through a frequency divider and a phase-locked loop.
The HSI RC of the following clock provides 16MHz. After passing through the distributor, it becomes 2MHz. Then it is multiplied by 100 and divided by 2. The chip selects PLLCLK and the frequency is doubled to get the 100MHz we finally set.
Since TIM14 is on the APB1 bus, we also need to pay attention to the clock frequency of the APB1 bus, which is automatically set to 50MHz.
That is to say, the initial clock obtained by TIM14 is 50MHz, and the subsequent timer frequency division is based on 50MHz.
Insert image description here

3.3 Timer related parameter configuration

If 0.5s flickering is implemented, the configuration is as follows.
The frequency division coefficient is set here to obtain a single clock cycle of 1ms, and the ARR is set to 999 to obtain a PWM wave period with a period of 1s.
Pulse is 500 to obtain a duty cycle of 500 ∗ 1 ms 1000 ms = 500 ms 1000 ms = 0.5 \frac{500*1ms}{1000ms}=\frac{500ms}{1000ms}=0.51000ms5001ms=1000ms500ms=0.5 PWM wave.

Insert image description here
If the breathing light effect is implemented, the configuration is as follows.
The frequency division coefficient is set here to obtain a single clock cycle of 0.1ms, and the ARR is set to 199 to obtain a PWM wave period of 20ms.
Pulse is 50 to obtain a duty cycle of 50 ∗ 0.1 ms 20 = 5 ms 20 ms = 0.25 \frac{50*0.1ms}{20}=\frac{5ms}{20ms}=0.252050 0.1 m s=20ms5ms=0.25 PWM wave.
Insert image description here

The reason why we need to set them up separately is because the effect of my own setting is more obvious, and you can also modify it according to your own needs.


3.4 Debug configuration

Insert image description here

3.5 Interrupt configuration

Insert image description here

3.6 Code generation

Insert image description here
Insert image description here


4. Code writing

4.1 LED flashing code writing

If you don't use interrupts, the code is relatively simple. In fact, you only need to enable it in the main function.
Insert image description here

	//不使用中断即输出固定占空比的PWM
	HAL_TIM_Base_Start(&htim14);
	HAL_TIM_PWM_Start(&htim14,TIM_CHANNEL_1);

Parameters in the initialization of LED flashing:
Insert image description here

4.2 Writing LED breathing light code

The breathing light requires an interrupt because the duty cycle of the PWM, that is, the value of the CCR variable, needs to be adjusted.
The first is to enable interrupts

	//使用中断,在回调函数里改变占空比
	//HAL_TIM_Base_Start_IT(&htim14);
	//HAL_TIM_PWM_Start_IT(&htim14,TIM_CHANNEL_1);

The callback function is HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)a function that is triggered when the counter reaches the value set by the pulse.
In order to adjust the pulse width, etc., we also need to set parameters.

uint16_t plusWidth=500;//脉宽
uint16_t dirInc=1;//脉宽变化方向,1为递增,0递减

Callback function code:

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
	//只针对TIM14进行中断处理
  if(htim->Instance!=TIM14)
	{
		return;
	}
	//如果是脉宽递增则增加脉宽
	if(dirInc==1)
	{
		plusWidth++;
		if(plusWidth>=195)
		{
			plusWidth=195;
			dirInc=0;
		}
	}
	//如果是脉宽递减则减少脉宽
	if(dirInc==0)
	{
		plusWidth--;
		if(plusWidth<=5)
		{
			plusWidth=5;
			dirInc=1;
		}
	}
	//__HAL_TIM_SetCompare(定时器对象指针,定时器通道,需要设置的CCR值);
	__HAL_TIM_SetCompare(&htim14,TIM_CHANNEL_1,plusWidth);
}	

Initialization parameter configuration of breathing light
Insert image description here


Summarize

This blog summarizes the PWM function of the timer and its application implementation. It is written in very detail. I have put the corresponding MX project and Keil code at the beginning and you need to pick it up yourself.

Guess you like

Origin blog.csdn.net/Edwinwzy/article/details/131966919