do STM32 The timer will be used in the experiment of intelligent car PWM output , To change the speed of DC motor . Share this article to learn how to PWM Realize the control of motor speed .

PWM Basic principle of controlling motor speed

    PWM(Pulse Width Modulation), It's pulse width modulation .

    PWM There is a more important concept in English , Duty cycle : It is the proportion of effective level in the whole pulse period .

     In order to achieve IO Persistent variation of voltage at the mouth , Adjustable PWM Duty cycle of . This also enables the power of the peripheral to change continuously , Finally control the speed of DC motor . How to adjust PWM The output of waveform is the key point .

   
In the picture above ARR It's a preload value for the timer ,CCRx The top and bottom of the change is produced PWM The key to wave . Let's assume that ARR greater than CCRx Part of the output is high level ( Namely t1-t2,t3-t4,t5-t6),ARR less than CCRx Part of the output is low level ( Namely 0-t1,t2-t3,t4-t5), Then change CCRx The value of can change the output PWM Duty cycle of . therefore , Want to control PWM The output waveform of , The important thing is how to set it up ARR And CCRx The values of these two registers have changed .

STM32 timer interrupt

     To make it easier to understand, what's next about PWM Application content , Insert a knowledge of timer interrupt first .

     Generating timer interrupt is one of the uses of timer , And the timer is used to carry on PWM Output versus input capture , Timer interrupts are easier to understand , master . Brief introduction of principle

     The principle of using general timer to interrupt , Development board Systick Timer interrupt delay is very similar (Stm32 introduction ——Systick timer ), Namely : use psc( Prescaler coefficient ) After setting the timer clock ,arr( Preload value ) Decrement in each clock cycle 1, When arr Reduced to 0 When the interrupt is triggered, it enters the interrupt handler to process the interrupt . The following code is an example :
void TIM3_Int_Init(u16 arr,u16 psc){ RCC->APB1ENR|=1<<1; //TIM3 Clock enable
TIM3->ARR=arr; // Set the counter auto reload value TIM3->PSC=psc; // Prescaler setting TIM3->DIER|=1<<0; // Allow update interrupt
TIM3->CR1|=0x01; // Enable timer 3 MY_NVIC_Init(1,3,TIM3_IRQn,2);// seize 1, Subpriority 3, group 2 }
RCC->APB1ENR|=1<<1

     Explain the above line of code , Due to the timer 3(TIM3) It's hanging on the wall APB1 Peripherals on , So open it APB1, Here is the prescaler value psc It's about setting up TIM3 Of the clock frequency , If the system clock (SYSTICK) The frequency is 72MHz,psc by 7199, be TIM3 The clock frequency of is :
72MHz/(7199+1)Hz = 10KHz // there “+1” It's in the manual .
    10KHz What is it
What do you mean ? That's what happens in a second 10K Cycles , So the length of a cycle is 1/10KHz, If you want to set the timer interrupt interval to 0.5 second , Then you will arr Set to 5000 that will do , because arr Every reduction 1 It takes a cycle , reduce 5000 The first time passed by 5000*(1/10KHz)=0.5 second .
TIM3->DIER|=1<<0
     Explain the line above , Setting allow update interrupt , Namely arr be reduced to 0 The update interrupt can be triggered later , There are other types of interruptions .
MY_NVIC_Init(1,3,TIM3_IRQn,2);// seize 1, Subpriority 3, group 2

     Look at the code above , Interrupt priority includes preemption priority and response priority ( That is, sub priority ) There are two priorities , Preemptive priority : If procedure 1 In use CPU, In this case, if the program 2 Required use CPU, And the program 2 High priority of preemption , be CPU By program 2 seize ; If the preemption priority is the same , Then it's a procedure 2 The response priority of is higher than that of the program 1,CPU And it can't be preempted ; If procedure 1 In use CPU, program 2 And procedures 3 The preemption priority of is equal to or lower than that of the program 1, And the procedure 2 The response priority of is higher than that of program 3 , Then wait CPU After vacating , program 2 Run first , program 3 Last run .TIM3_IRQn Is the number that specifies the interrupt handler to run .“ group 2” Is to set interrupt priority grouping , This is because the register provides four bits to set the priority , group 2 Represents the first two to preempt priority , The last two give priority to the response .

PWM pattern , Effective level

     I've finished with interruptions , Again PWM working principle .

     Let's say that in the picture above ARR greater than CCRx The output is high when the voltage is high ,ARR less than CCRx The output is at low level , But it may not be so in practice , It could be the opposite ——ARR greater than CCRx The output is at low level ,ARR less than CCRx The output is high when the voltage is high , As for what kind of situation , And look at it PWM What is the mode , What polarity is the effective level set .

*
pattern 1:ARR less than CCRx The output is “ Effective ” level ,ARR greater than CCRx The output is “ invalid ” level .

*
pattern 2:ARR less than CCRx The output is “ invalid ” level ,ARR greater than CCRx The output is “ Effective ” level .

     It's about “ Effective ” and “ invalid ”, instead of “ high ” and “ low ”, That is to say, the effective level can be high or low , It's not necessarily high level .PWM pattern , Effective level polarity , It needs the programmer to configure the relevant registers to achieve . This is explained by the following code .
TIM1_PWM_Init(899,0);// No frequency division .PWM frequency =72000/(899+1)=80Khz

     The previous section talked about the setting of timer parameters . Using timers 1 Access to 1 To output all the way PWM wave , there 899 It's set up ARR Value of , As for that 0 It's used to set TIM1 The frequency of , No frequency division on behalf of TIM1 The clock frequency of is the same as the system clock , Here we assume that 72MHz.
void TIM1_PWM_Init(u16 arr,u16 psc){ // This part needs to be modified manually IO Port setting RCC->APB2ENR|=1<<11;
//TIM1 Clock enable GPIOA->CRH&=0XFFFFFFF0; //PA8 Clear previous settings GPIOA->CRH|=0X0000000B;
// Multiplexing function output TIM1->ARR=arr; // Set the counter auto reload value TIM1->PSC=psc; // Prescaler setting TIM1->CCMR1|=7<<4;
//CH1 PWM2 pattern TIM1->CCMR1|=1<<3; //CH1 Preload enable TIM1->CCER|=0<<1; //OC1 Output enable
//TIM1->CCER|=1<<1; TIM1->BDTR|=1<<15; //MOE Main output enable TIM1->CR1=0x0080; //ARPE Enable
TIM1->CR1|=0x01; // Enable timer 1 }
     The following specific analysis of the above code .

     front 4-6 Lines are used to configure GPIO Oral .
TIM1->ARR=arr; // Set the counter auto reload value TIM1->PSC=psc; // Prescaler setting
     These two lines are the frequency and reload value of the timer I mentioned .
TIM1->CCMR1|=7<<4; //CH1 PWM2 pattern TIM1->CCMR1|=1<<3; //CH1 Preload enable TIM1->CCER|=0<<1;
//OC1 Output enable

     These three lines are used to set the PWM Output mode and setting channel , What is the passage ? Simply put, it's output PWM Wavelike GPIO mouth , The code was not set at first PA8 this GPIO Mouth , this PA8 That's the channel 1. If you use a channel, you need to do the input and output direction first , Channel enable settings .
TIM1->CCER|=1<<1;
     This line of code is used to set the “ Effective level ” Polar , According to the manual , When TIM1->CCER[1] This is the location 1 Time , The active level is low , Place 0 The active level is high , By default, the 0.
TIM1->BDTR|=1<<15; //MOE Main output enable
     This line of code only needs to set the advanced timer , Ordinary timer does not need to be set .
TIM1->CR1=0x0080; //ARPE Enable

     This line of code is used to enable ARPE,ARPE What is it , It's when it's set 1 Time , You set it up yourself CCRx It will take effect immediately , If it is set to 0, So you set it up yourself CCRx Value does not take effect immediately ( Maybe before ARPE It's worth it ), It's set before CCRx Your latest settings will not be used until it takes effect CCRx value .

There's no right in the code above CCRx Set it up , that is because CCRx It's often a variable value , You can use one in the main function for loop +if The judgment statement evaluates it ++ or – Operation of , So as to achieve continuous change CCRx Worthy of purpose , for example :
for(i=0;i<300;i++){ TIM1->CCR1=i; if(i==300){ i=0; }}
    PWM The period of the wave is determined by the timer clock frequency and the preload value , The preload value is ARR.

     Preload value PSC Set to 899, that , When the current value of the timer val from 0 increase to 899 Time , It's been a long time 900 Clock cycles , this 900 One clock cycle produces one PWM wave form , in other words 900 One timer clock cycle is equivalent to one PWM cycle , that PWM And the frequency of that is 72MHz/900=80KHz, with a period of 1/80KHz.

Technology
©2019-2020 Toolsou All rights reserved,
Huawei 2021 session Hardware Engineer Logical post (FPGA) Super detailed surface !!!Vue-element-admin upgrade ui edition virtual machine VMware Download and install the most detailed tutorial !C++ Move constructor and copy constructor sound of dripping water java Backstage interview pygame Realize full screen mode and adjustable window size mysql Database setting character set configuration modification my.ini file (windows)30 What's the experience of being a junior programmer at the age of 20 C++ Multithreading programming ( Summary of common functions and parameters )python_ cherry tree