Table of contents:
1 Overview
2: Common interrupt functions
3: PWM output
1 Overview
In development, timers are widely used, which can be simply summarized into three aspects:
1.1: Application of interrupt function. Timer interrupt is commonly used to realize timing, timekeeping, delay and timeout judgment. The various methods of using kernel timer are summarized in the previous blog post;
1.2: Comparison output, the common application is PWM output, using pulse width modulation to achieve the control of LEDs, motors, etc.;
1.3: Input capture, which can capture the input square wave signal, count the waveform period and duty cycle. The most common use is gating, which converts the external analog quantity into a digital quantity (the count value of the timer);
2: Common interrupt functions
The detailed reference manual for the timer initialization is as follows. The main point is to determine the timer overflow period. The overflow frequency of the timer can be calculated using the formula: Tout = (arr+1)*(psc+1)/Tclk.
The following code is implemented: the LED is flipped in the interrupt function, the flip frequency is 1HZ, that is, the LED flashing frequency is 1HZ;
timer_driver.c
#include "timer_driver.h"
#include "led_driver.h"
void TIM3_Init(unsigned int arr,unsigned int psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_OCInitTypeDef TIM_OCInitStruct;
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Map CH2 of TIM3 to PB5
//Timer TIM3 initialization
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler =psc;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //Enable the specified TIM3 interrupt and allow update interrupt
//Interrupt priority NVIC setting
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3 interrupt
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //Preempt priority level 0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //From priority level 3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ channel is enabled
NVIC_Init(&NVIC_InitStructure); //Initialize NVIC registers
TIM_Cmd(TIM3, ENABLE); //Enable TIMx
}
unsigned char flag = 0;
void TIM3_IRQHandler(void)
{
flag = !flag;
if(flag == 0)
{
LED1_ON;
LED2_ON;
LED3_ON;
}
else
{
LED1_OFF;
LED2_OFF;
LED3_OFF;
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
main.c
#include "stm32f10x.h"
#include "timer_driver.h"
#include "led_driver.h"
#include "systick_driver.h"
#include "key_board.h"
unsigned int led_pwm_ctr_cnt = 0;
unsigned int led_pwm = 0;
/*Peripheral clock initialization*/
void RCC_PeriphClock_Config(void)
{
/*GPIO port clock initialization*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
}
int main()
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //Set interrupt priority group
SysTick_Init(INT_10MS,SysTick_CLKSource_HCLK_Div8); //Core tick timer configuration for LED task round robin
RCC_PeriphClock_Config();
Led_Init(); //LED light initialization
TIM3_Init(9999,7199); //Timer 3 initialization, overflow frequency is 1hz
while(1)
{
;
}
}
3: PWM output
There are two things to determine for pwm output: the period of the PWM output waveform and the duty cycle of the PWM output waveform. Specifically, the effective level of the PWM waveform and the PWM output mode need to be set.
The following code implements 1khz pwm waveform output, and the duty cycle of the pwm wave can be changed through security inspection;
timer_driver.c
#include "timer_driver.h"
#include "led_driver.h"
void TIM3_Init(unsigned int arr,unsigned int psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStruct;
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Map CH2 of TIM3 to PB5
//Timer TIM3 initialization
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler =psc;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
//PWM CH2 output initialization
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM2; /*The high level LED of the development board is on because the upward counting mode is set, and the effective level of OC1 is set to high level. According to the manual, it is set to PWM mode 2*/
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; /*Set OC2 output enable*/
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low; /*Set OC2 valid level to low level*/
TIM_OC2Init(TIM3, &TIM_OCInitStruct);
// //PWM CH1 output initialization
// TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM2; /*The high level LED of the development board is on because the upward counting mode is set, and the OC1 effective level is set to high level. According to the manual, it is set to PWM mode 2*/
// TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; /*Set OC1 output enable*/
// TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low; /*Set OC1 valid level to low level*/
// TIM_OC1Init(TIM3, &TIM_OCInitStruct);
TIM_Cmd(TIM3, ENABLE); //Enable TIMx
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); /*Enable the preload function of output compare 2*/
//TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); /*Enable the preload function of output compare 2*/
TIM_SetCompare2(TIM3, 500);
//TIM_SetCompare1(TIM3, 500);
}
main.c
#include "stm32f10x.h"
#include "timer_driver.h"
#include "led_driver.h"
#include "systick_driver.h"
#include "key_board.h"
unsigned int led_pwm_ctr_cnt = 0;
unsigned int led_pwm = 500;
/*Peripheral clock initialization*/
void RCC_PeriphClock_Config(void)
{
/*GPIO port clock initialization*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
}
int main()
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //Set interrupt priority group
SysTick_Init(INT_10MS,SysTick_CLKSource_HCLK_Div8); //Core tick timer configuration for LED task round robin
RCC_PeriphClock_Config();
Led_Init(); //LED light initialization
Key_Init();
TIM3_Init(999,71); //Timer 3 initialization, pwm cycle is 1KHZ
while(1)
{
if(led_pwm_ctr_cnt >= 1) //500ms polling
{
led_pwm_ctr_cnt = 0;
if(K1 == 0) //k1 button is pressed
{
if(led_pwm < 1000)
led_pwm++;
TIM_SetCompare2(TIM3, led_pwm);
TIM_SetCompare1(TIM3, led_pwm);
}
else
if(K2 == 0)
{
if(led_pwm > 0)
led_pwm--;
TIM_SetCompare2(TIM3, led_pwm);
TIM_SetCompare1(TIM3, led_pwm);
}
}
}
}
The following is the pwm output waveform captured by the logic analyzer:
Previous article:89C51 and ad0832 output sine wave, triangle wave, rectangular wave, sawtooth wave
Next article:51 MCU timer interrupt program
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- 16. Low-power intelligent TWS in-ear detection chip VK233DS, Shenzhen Yongjia Microelectronics is the first choice
- [Atria AT32WB415 Series Bluetooth BLE 5.0 MCU] PWM breathing light
- 30V8A stepper motor driver, step angle 1.8 degrees, required accuracy 0.1 degrees, should I choose chip or H bridge
- Can the 66AK2L06 SoC enable miniaturization of test and measurement equipment?
- Circuit diagram of leakage alarm automatic control socket
- How to detect mosquitoes using ultrasonic sensor circuit
- 2021 National College Student Electronics Competition Released
- Share the application manuals, library functions, routines and selection tables of the full range of MM32 MCU products of Lingdong Microelectronics
- 【Construction Monitoring and Security System】Work Submission Post
- Live FAQ|Typical applications in the era of the Internet of Things