STM32 rookie growth Record---common timer application

Source: Internet
Author: User
Tags reset

First, STM32 Universal timer principle

The STM32 series of CPUs, with up to 8 timers, where TIM1 and TIM8 are advanced timers capable of producing three pairs of PWM complementary outputs, are often used for three-phase motor drives whose clocks are generated by the APB2 output. The other 6 are normal timers, and the clocks are generated by the APB1 output.

The following figure is a screenshot of the timer clock section of the STM32 reference manual on the clock distribution chart:

As can be seen from the figure, the timer clock is not directly from the APB1 or APB2, but from the input of APB1 or APB2 a multiplier, the blue part of the figure.

The following is a universal Timer 2 clock to illustrate the role of this multiplier: when the APB1 prescaler coefficient is 1 o'clock, the multiplier does not work, the clock frequency of the timer equals the frequency of APB1, when the APB1 prescaler coefficient is other values (that is, the prescaler coefficient is 2, 4, 8 or 16), the multiplier function, The clock frequency of the timer equals the frequency of APB1 twice times.

Maybe some classmates still do not understand, OK, let's give an example to illustrate. Assuming Ahb=36mhz, because the maximum allowable frequency of APB1 is 36MHz, so the prescaler coefficient of APB1 can take any value;

When the prescaler factor = 1 o'clock, the apb1=36mhz,tim2~7 clock frequency =36mhz (multiplier does not work);

When the prescaler factor = 2 o'clock, Apb1=18mhz, the tim2~7 clock frequency =36mhz under the action of the multiplier.

Some people will ask, since the need tim2~7 clock frequency =36mhz, why not directly take the APB1 prescaler coefficient = 1. The answer is: APB1 not only to provide the clock for the tim2~7, but also to provide clocks for other peripherals, set this multiplier can be used to ensure that other peripherals using a lower clock frequency.

Stm32 Peripheral User manual, as shown in figure:

Another example: When Ahb=72mhz, the APB1 prescaler coefficient must be greater than 2, because the maximum frequency of APB1 can only be 36MHz. If the APB1 prescaler factor = 2, the tim2~7 can still get a 72MHz clock frequency because of the multiplier. The ability to use a higher clock frequency has undoubtedly increased the resolution of the timer, which is why the multiplier was designed.

Second, STM32 General timer programming

Timer programming is the interrupt programming. Because the use of timers must be used to interrupt.

Step one: Rcc_configuration ();//Set the system clock, including the clock RCC configuration, octave to 72MHZ.

Step two: The configuration of the Gpio, using the function as Gpio_cfg (), the function is implemented as follows:

void Gpio_cfg ()

{

       gpio_inittypedef gpio_initstructure;

      Rcc_apb2periphclockcmd (Rcc_apb2periph_usart1 | Rcc_apb2periph_gpioa | Rcc_apb2periph_gpiob | RCC_APB2PERIPH_GPIOC | Rcc_apb2periph_gpiod, ENABLE);

       

       Gpio_initstructure.gpio_pin = gpio_pin_6;                 Select Pin 6

       gpio_initstructure.gpio_speed = Gpio_speed_50mhz;//Output frequency max. 50MHz

      gpio_initstructure.gpio_mode = GPIO _MODE_OUT_PP; With pull-up resistor output

       gpio_init (gpioc,&gpio_initstructure);

}


In fact, the explanation of the timer, do not need to configure the Gpio pin, but we in the timer experiment,

Use the LED light every second to do the experiment, so you need to configure the pin corresponding to the GPIO.

Step three: Nested Interrupt controller configuration, we still use the function nvic_config (); Only the process of initialization is slightly different. Here we also list the function implementation:

From the above function implementation, actually only changes the structure member Nvic_irqchannel value, now needs the channel is the TIM2 channel, therefore the initialization value is Tim2_irqchannel. As can be seen from here, this function can actually be seen as a model that can be used directly in other programs.

void Nvic_cfg ()

{

       nvic_inittypedef nvic_initstructure;

        Select Interrupt Grouping 1

        nvic_prioritygroupconfig (nvic_prioritygroup_1);



        Select the TIM2 interrupt channel

        nvic_initstructure.nvic_irqchannel = Tim2_irqchannel;     

        Preemptive interrupt priority is set to 0

        nvic_initstructure.nvic_irqchannelpreemptionpriority = 0;

       The response interrupt priority is set to 0

        nvic_initstructure.nvic_irqchannelsubpriority = 0;

        Enable interrupt

        Nvic_initstructure.nvic_irqchannelcmd = enable;

        Nvic_init (&nvic_initstructure);

}


Step four: The initialization of the timer configuration, using Timer_config ();. OK, the key part comes out.

Let's take a look at the implementation process:

Timer_cfg (); Timer configuration

       //Turn-on Timer 2

 tim_cmd (tim2,enable);

Voidtimer_config (void)
{ 

    rcc_apb1periphclockcmd (rcc_apb1periph_tim2,enable); 

    Tim_deinit (TIM2);

    tim_timebasestructure.tim_period=2000-1;  The value of the automatic reload register

    tim_timebasestructure.tim_prescaler= (36000-1);         Clock Prescaler frequency

    tim_timebasestructure.tim_clockdivision=tim_ckd_div1;  Sampling divider

     tim_timebasestructure.tim_countermode=tim_countermode_up;//Up-counting mode
    Tim_timebaseinit (tim2,& Tim_timebasestructure);

    Tim_clearflag (tim2,tim_flag_update);               Clear overflow Interrupt flag

    tim_itconfig (tim2,tim_it_update,enable);

     Tim_cmd (tim2,enable);                              /Turn on Clock

} 

Let's explain each statement. First we want to use the timer, we must make the timer clock, this is the function rcc_apb1periphclockcmd (), and through it to open the rcc_apb1periph_tim2.

Tim_deinit (TIM2), the function is mainly used to reset the TIM2 timer to enter the initial state.

Then we assign a value to the automatic reload register, and the size of the Tim_period actually indicates that an update or break will occur once the tim_period count is required. Next we need to set the clock Prescaler frequency Tim_prescaler, here is a formula, we say for example: clock frequency =72mhz/(clock Prescaler + 1). Describes the current set of this tim_prescaler, directly determines the clock frequency of the timer. The popular point is that it counts how many times a second can be counted. such as the calculated clock frequency is 2000, that is,

A second accounting 2000 times, and if Tim_period is set to 4000, that is, 4,000 times the count will be interrupted once. Since the clock frequency is counted 2000 times a second, it will be interrupted once for 2 seconds.

The next code, there is a need to pay attention to, tim_timebasestructure.tim_countermode=tim_countermode_up; we generally use the up-counting mode, that is, each count will be added 1, Until the register overflow has been interrupted. Finally, don't forget that you need to enable the timer.

Interrupt Time = (tim_prescaler+1) * (tim_period+1)/flk

Use the above formula to calculate: Interrupt Time (2000-1+1) * (36000-1+1)/72000000=1 sec

Step five: Write the interrupt service program. It is also important to note that one of the first steps to get into the interrupt service is to clear out the interrupt flag bit. Since we are using up overflow mode, we use the

The function should be: Tim_clearitpendingbit (tim2,tim_flag_update);.

The interrupt service program implemented by the STM32 Development Board is as follows:

Every second, when an interrupt occurs, enter this interrupt function to execute the program, let the LED flash, this interrupt program is located in the file stm32f10x_it.c

/******************************************************************************* * Function Name:tim2_irqhandler *

Description:this function handles TIM2 global interrupt request. * Input:none * output:none * return:none ***********************************************

 

   /void Tim2_irqhandler (void) {U8 readvalue; if (Tim_getitstatus (TIM2, tim_it_update)! = RESET)//detect whether an overflow update event occurred {tim_clearitpendingbit (TIM2, Tim_flag

 

              _update);//clear TIM2 interrupt to handle bit//uart2_tx485_puts ("123450");

        /* Debug Timer Test */readvalue = Gpio_readoutputdatabit (gpioc,gpio_pin_6);

         if (ReadValue = = 0)//If the port is currently low, {gpio_setbits (gpioc,gpio_pin_6);//change it to high-level output; } else//If the port is currently high, {gpio_resetbits (GPIOC,GP   Io_pin_6);

        

  Change it to low-level output;}   }        

}

 

General Timer working principle diagram

Compile the completed code download in my resources: http://download.csdn.net/detail/yx_l128125/4508425

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.