Based on stm32f103c8t6, HAL library timer control light on and off &&PWM to realize breathing light

1. Basic knowledge of timers

Timer classification

1. Basic timer The basic timer is a simple timer that is usually used to generate precise time delays. It has a single 16-bit counter that can achieve different counting speeds by setting the prescaler coefficient. Basic timers are usually used for simple scheduled tasks. 2. Universal timer A universal timer is a more complex and powerful timer, usually used for more complex timing and counting tasks. STM32 series microcontrollers are usually equipped with multiple general-purpose timers, such as TIM1, TIM2, etc. The general timer has multiple 16-bit or 32-bit counters, which can achieve different counting speeds and timing accuracy by setting the prescaler coefficient and counting period. Timer applications STM32 timers are widely used in various fields, including industrial control, communications, embedded systems, etc. The following are some common timer application scenarios:

1. Scheduled interrupt: You can use a timer to generate periodic interrupt signals for triggering and processing scheduled tasks. 2. Timing measurement: You can use a timer to measure and calculate time, such as measuring pulse width, measuring signal frequency, etc. 3. PWM output: A timer can be used to generate precise pulse width modulation signals for controlling motor speed, LED brightness, etc. 4. Input capture: You can use a timer to capture external signals and measure the timestamp of external events.

Timer configuration In order to configure and control the STM32 timer, we can use the corresponding library function or directly operate the register. The following are some commonly used configuration parameters:

1. Prescaler coefficient: used to set the counting speed of the timer, which can be adjusted as needed. 2. Counting period: used to set the counting period of the timer and determine the time interval for the timer to overflow. 3. Working mode: The timer can work in different modes, such as timer mode, counter mode, PWM mode, etc. 4. Interrupt enable: You can choose whether to enable the interrupt function of the timer to trigger interrupt tasks.

2. Application of timer 1

1. Use Tim2~Tim5 of STM32F103 to connect a certain channel pin of the timer (multiplexed with the GPIOx pin, see the figure below), connect an LED, and use the timer counting mode to control the LED to light up periodically at a frequency of 2s. -Destroy code:

#include "led.h"
?
void LED_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, & amp;GPIO_InitStruct);
}
?
void LED_Toggle(void)
{
    GPIOB->ODR ^= GPIO_Pin_0;
}
?
?
led.h
?
#ifndef __LED_H
#define __LED_H
?
#include "stm32f10x.h"
?
void LED_Config(void);
void LED_Toggle(void);
?
#endif
?
tim_timebase.c
?
#include "tim_timebase.h"
#include "led.h"
?
int a = 0;
?
static void NVIC_Config(void)
{
    NVIC_InitTypeDef NVIC_InitStruct;
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    
    NVIC_InitStruct.NVIC_IRQChannel=TIM3_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
    NVIC_Init( & amp;NVIC_InitStruct);
}
?
void TIM3_Config(void)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    
    NVIC_Config();
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    
    TIM_TimeBaseInitStruct.TIM_Period=71;
    TIM_TimeBaseInitStruct.TIM_Prescaler=1000;//1ms
    TIM_TimeBaseInit(TIM3, & amp;TIM_TimeBaseInitStruct);
    
    TIM_ClearFlag(TIM3, TIM_FLAG_Update);
    
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
    
    TIM_Cmd(TIM3, ENABLE);
}
?
void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3, TIM_IT_Update)) a + + ;
    if(a == 1000)
    {
        LED_Toggle();
        a = 0;
    }
    TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}
tim_timebase.h

#ifndef __TIM_TIMEBASE_H
#define __TIM_TIMEBASE_H
?
#include "stm32f10x.h"
?
void TIM3_Config(void);
?
#endif

main.c

#include "stm32f10x.h"
#include "led.h"
#include "tim_timebase.h"
?
int main(void)
{
    LED_Config();
    TIM3_Config();
    
    while(1)
    {
        
    }
}

3. Application of PWM

2. Connect it, use the timer PWM mode, let the LED gradually light up and off in the way of a breathing light, with a cycle of 1~2 seconds, and adjust it to a satisfactory effect. Use Keil virtual oscilloscope to observe the PWM output waveform.

Code PWM.c

#include "stm32f10x.h" // Device header
?
void PWM_Init(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);
//GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, & amp;GPIO_InitStructure);
    
    TIM_InternalClockConfig(TIM2);
    
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; //ARR
    TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1; //PSC
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2, & amp;TIM_TimeBaseInitStructure);
    
    TIM_OCInitTypeDef TIM_OCInitStructure;
    TIM_OCStructInit( & amp;TIM_OCInitStructure);
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 0; //CCR
    TIM_OC1Init(TIM2, & amp;TIM_OCInitStructure);
    
    TIM_Cmd(TIM2, ENABLE);
}
?
void PWM_SetCompare1(uint16_t Compare)
{
    TIM_SetCompare1(TIM2, Compare);
}
main.c
?
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
?
uint8_t i;
?
int main(void)
{
    OLED_Init();
    PWM_Init();
    
    while (1)
    {
        for (i = 0; i <= 100; i + + )
        {
            PWM_SetCompare1(i);
            Delay_ms(5);
        }
        for (i = 0; i <= 100; i + + )
        {
            PWM_SetCompare1(100 - i);
            Delay_ms(5);
        }
    }
}

Use Keil virtual oscilloscope to observe the PWM output waveform

It is marked as bit display and represented by a green line. The obtained waveform result is as shown in the figure below:

4. Summary

Through this experiment, the LED was realized to turn on and off periodically at a frequency of 2 seconds. The PWM mode of the timer was used. By configuring the parameters of the timer and related registers, the LED gradually turned on and off in the way of a breathing light. Through Keil virtual With an oscilloscope, we can observe the PWM output waveform to verify the correctness of the PWM; we made full preparations before the experiment, carefully read the relevant STM32 timer and PWM mode documents, and understood the configuration method of its registers and the interrupt processing function. Wrote and became familiar with the use of Keil virtual oscilloscope to observe waveform output. This experiment helps us gain a deeper understanding of the timer principle and PWM of STM32. Through actual operations and observation of waveforms, we will better grasp and understand the working principles of timers and PWM. When testing the breathing light effect, it was found that when the PWM cycle is very large, the breathing light effect is not obvious. From the PWM wave principle, only the proportion of high level is modified. Then if the cycle is very large, even if the duty cycle No matter how you modify it, the human eye will still see the process of turning on and off. When the PWM frequency increases, the human eye will not be able to identify the low-level gap, so it can be seen as the process from on to off.