General purpose timer (interrupt function and PWM output)

Publisher:静心悠然Latest update time:2018-05-13 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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


  1. #include "timer_driver.h"  

  2. #include "led_driver.h"  

  3.   

  4. void TIM3_Init(unsigned int arr,unsigned int psc)  

  5. {  

  6.   TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  

  7.     NVIC_InitTypeDef NVIC_InitStructure;  

  8.     TIM_OCInitTypeDef TIM_OCInitStruct;  

  9.       

  10.     GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Map CH2 of TIM3 to PB5  

  11.       

  12.     //Timer TIM3 initialization  

  13.     TIM_TimeBaseStructure.TIM_Period = arr;   

  14.     TIM_TimeBaseStructure.TIM_Prescaler =psc;  

  15.     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  

  16.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   

  17.     TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);  

  18.       

  19.     TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //Enable the specified TIM3 interrupt and allow update interrupt  

  20.   

  21.     //Interrupt priority NVIC setting  

  22.     NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3 interrupt  

  23.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //Preempt priority level 0  

  24.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //From priority level 3  

  25.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ channel is enabled  

  26.     NVIC_Init(&NVIC_InitStructure); //Initialize NVIC registers  

  27.   

  28.     TIM_Cmd(TIM3, ENABLE); //Enable TIMx          

  29. }  

  30.   

  31. unsigned char flag = 0;  

  32. void TIM3_IRQHandler(void)   

  33. {  

  34.         flag = !flag;  

  35.         if(flag == 0)  

  36.         {  

  37.             LED1_ON;  

  38.             LED2_ON;  

  39.             LED3_ON;  

  40.         }  

  41.         else  

  42.         {  

  43.             LED1_OFF;  

  44.             LED2_OFF;  

  45.             LED3_OFF;  

  46.         }  

  47.         TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  

  48. }  


main.c


  1. #include "stm32f10x.h"  

  2. #include "timer_driver.h"  

  3. #include "led_driver.h"  

  4. #include "systick_driver.h"  

  5. #include "key_board.h"  

  6.   

  7. unsigned int led_pwm_ctr_cnt = 0;  

  8. unsigned int led_pwm = 0;  

  9.   

  10. /*Peripheral clock initialization*/  

  11. void RCC_PeriphClock_Config(void)  

  12. {  

  13.     /*GPIO port clock initialization*/  

  14.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD, ENABLE);  

  15.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);  

  16. }  

  17.   

  18. int main()  

  19. {  

  20.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //Set interrupt priority group  

  21.     SysTick_Init(INT_10MS,SysTick_CLKSource_HCLK_Div8); //Core tick timer configuration for LED task round robin   

  22.     RCC_PeriphClock_Config();  

  23.     Led_Init(); //LED light initialization   

  24.     TIM3_Init(9999,7199); //Timer 3 initialization, overflow frequency is 1hz  

  25.       

  26.     while(1)  

  27.     {  

  28.         ;  

  29.     }  

  30. }  


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


  1. #include "timer_driver.h"  

  2. #include "led_driver.h"  

  3.   

  4. void TIM3_Init(unsigned int arr,unsigned int psc)  

  5. {  

  6.   TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  

  7.     TIM_OCInitTypeDef TIM_OCInitStruct;  

  8.       

  9.     GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Map CH2 of TIM3 to PB5  

  10.       

  11.     //Timer TIM3 initialization  

  12.     TIM_TimeBaseStructure.TIM_Period = arr;   

  13.     TIM_TimeBaseStructure.TIM_Prescaler =psc;  

  14.     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  

  15.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   

  16.     TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);  

  17.       

  18.     //PWM CH2 output initialization  

  19.     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*/  

  20.     TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; /*Set OC2 output enable*/  

  21.     TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low; /*Set OC2 valid level to low level*/  

  22.     TIM_OC2Init(TIM3, &TIM_OCInitStruct);  

  23.       

  24. // //PWM CH1 output initialization  

  25. // 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*/  

  26. // TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; /*Set OC1 output enable*/  

  27. // TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low; /*Set OC1 valid level to low level*/  

  28. // TIM_OC1Init(TIM3, &TIM_OCInitStruct);  

  29.   

  30.     TIM_Cmd(TIM3, ENABLE); //Enable TIMx          

  31.   

  32.     TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); /*Enable the preload function of output compare 2*/   

  33.     //TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); /*Enable the preload function of output compare 2*/   

  34.       

  35.     TIM_SetCompare2(TIM3, 500);  

  36.     //TIM_SetCompare1(TIM3, 500);  

  37. }  

main.c


  1. #include "stm32f10x.h"  

  2. #include "timer_driver.h"  

  3. #include "led_driver.h"  

  4. #include "systick_driver.h"  

  5. #include "key_board.h"  

  6.   

  7. unsigned int led_pwm_ctr_cnt = 0;  

  8. unsigned int led_pwm = 500;  

  9.   

  10. /*Peripheral clock initialization*/  

  11. void RCC_PeriphClock_Config(void)  

  12. {  

  13.     /*GPIO port clock initialization*/  

  14.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);  

  15.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);  

  16. }  

  17.   

  18. int main()  

  19. {  

  20.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //Set interrupt priority group  

  21.     SysTick_Init(INT_10MS,SysTick_CLKSource_HCLK_Div8); //Core tick timer configuration for LED task round robin   

  22.     RCC_PeriphClock_Config();  

  23.     Led_Init(); //LED light initialization   

  24.     Key_Init();  

  25.     TIM3_Init(999,71); //Timer 3 initialization, pwm cycle is 1KHZ  

  26.       

  27.     while(1)  

  28.     {  

  29.         if(led_pwm_ctr_cnt >= 1) //500ms polling  

  30.         {  

  31.             led_pwm_ctr_cnt = 0;  

  32.             if(K1 == 0) //k1 button is pressed  

  33.             {  

  34.                 if(led_pwm < 1000)  

  35.                     led_pwm++;  

  36.                 TIM_SetCompare2(TIM3, led_pwm);  

  37.                 TIM_SetCompare1(TIM3, led_pwm);  

  38.             }  

  39.             else  

  40.             if(K2 == 0)  

  41.             {  

  42.                 if(led_pwm > 0)  

  43.                     led_pwm--;  

  44.                 TIM_SetCompare2(TIM3, led_pwm);  

  45.                 TIM_SetCompare1(TIM3, led_pwm);  

  46.             }  

  47.         }  

  48.     }  

  49. }  


The following is the pwm output waveform captured by the logic analyzer:



Reference address:General purpose timer (interrupt function and PWM output)

Previous article:89C51 and ad0832 output sine wave, triangle wave, rectangular wave, sawtooth wave
Next article:51 MCU timer interrupt program

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号