Stm32 Study Notes 2 (TIM module timer)

Source: Internet
Author: User

Timer overflow of Tim module & comparison of output

First of all, we must be sure of the strength of the ST Company, but also admitted that stm32 is indeed a very good Cortex-M3 core microcontroller, but his manual is really people feel incomprehensible, in particular, the TIM module is not organized. It is depressing to see that the cloud is still running for almost two days. At the same time, the description of the supporting Firmware Library is difficult to match with the registers in the manual, and it is very difficult to study! It is true that the function is powerful, but at least it should provide a clear description ~~
In the past two days, we have studied the most basic part of the stm32 timer and implemented the two most basic functions of the timer. The remaining functions need to be further studied.
First, note that the latest fwlib Firmware Library version is v2.0.x. In the v1.0.x Firmware Library, the tim1 module is independent and the called functions are different from other timers; in the V2.0 series, tim1.h is canceled, and all Tim modules call Tim. h. Many of the Code circulating on the network is based on the V1 version Firmware Library. You need to modify it when porting it to the V2 version Firmware Library. All programs in this article are based on the Firmware Library V2.0.

The following is an example code of a timer overflow:

C Language: The tim1 module generates an upstream Overflow Event.
// Step 1: Start tim1
Rcc_apb2periphclockcmd (rcc_apb2periph_tim1, enable );

// Step2. interrupt Objective C setting: Enable interrupt and set priority
Nvic_initstructure.nvic_irqchannel = timereup_irqchannel; // update the event
Nvic_initstructure.nvic_irqchannelpreemptionpriority = 0; // the preemption priority is 0.
Nvic_initstructure.nvic_irqchannelsubpriority = 1; // response Priority 1
Nvic_initstructure.nvic_irqchannelcmd = Enable; // interrupt allowed
Nvic_init (& nvic_initstructure); // write settings

// Step 3.tim1 Module Settings
Void tim_configuration (void)
{
Tim_timebaseinittypedef tim_baseinitstructure;
Tim_ocinittypedef tim_ocinitstructure;


// Use the internal clock of tim1
// Tim_internalclockconfig (tim1 );

// Tim1 Basic settings
// Set the frequency division coefficient 71 for the pre-divider, that is, apb2 = 72 m, tim1_clk = 72/72 = 1 MHz
// Tim_period (timerearr) = 1000. An update event is generated after the counter is counted up to 1000, and the count value is zero.
// Upward counting Mode
// Tim_repetitioncounter (timerercr) = 0. Every overflow generates an update event.
Tim_baseinitstructure.tim_period = 1000;
Tim_baseinitstructure.tim_prescaler = 71;
Tim_baseinitstructure.tim_clockdivision = 0;
Tim_baseinitstructure.tim_countermode = tim_countermode_up;
Tim_baseinitstructure.tim_repetitioncounter = 0;
Tim_timebaseinit (tim1, & tim_baseinitstructure );

// Clear the interruption to avoid immediate interruption once the interruption is enabled
Tim_clearflag (tim1, tim_flag_update );
// Enable tim1 to interrupt the source
Tim_itconfig (tim1, tim_it_update, enable );

// Tim1 master switch: Enabled
Tim_cmd (tim1, enable );
}

// Step 4. Interrupt Service Subroutine:
Void tim1_up_irqhandler (void)
{
Gpioc-> ODR ^ = (1 <4); // flashing
Tim_clearitpendingbit (tim1, tim_flag_update); // clear the interrupt
}

The following is the output comparison function to implement the pulse at the specified frequency output by the timereport:

C Language: The tim1 module achieves output comparison, automatically flip and trigger interruption
// Step1. start tim1, and pay attention to the corresponding function pin to start the clock.
Rcc_apb2periphclockcmd (rcc_apb2periph_tim1, enable );
Rcc_apb2periphclockcmd (rcc_apb2periph_gpioa, enable );

// Set the pa.8 port to the oc1 output port of tim1
Gpio_initstructure.gpio_pin = gpio_pin_8;
Gpio_initstructure.gpio_mode = gpio_mode_af_pp;
Gpio_initstructure.gpio_speed = gpio_speed_50mhz;
Gpio_init (gpioa, & gpio_initstructure );

// Step3. enable tim1 output comparison to match and interrupt
Nvic_initstructure.nvic_irqchannel = timerecc_irqchannel;
Nvic_initstructure.nvic_irqchannelpreemptionpriority = 1;
Nvic_initstructure.nvic_irqchannelsubpriority = 1;
Nvic_initstructure.nvic_irqchannelcmd = Enable;
Nvic_init (& nvic_initstructure );

// Step 4. Tim Module Settings
Void tim_configuration (void)
{
Tim_timebaseinittypedef tim_baseinitstructure;
Tim_ocinittypedef tim_ocinitstructure;


// Tim1 basic counter settings
Tim_baseinitstructure.tim_period = 0 xFFFF; // The value must be 65535
Tim_baseinitstructure.tim_prescaler = 71; // pre-Division 71, that is, 72 Division, 1 m
Tim_baseinitstructure.tim_clockdivision = 0;
Tim_baseinitstructure.tim_countermode = tim_countermode_up;
Tim_baseinitstructure.tim_repetitioncounter = 0;
Tim_timebaseinit (tim1, & tim_baseinitstructure );

// Timereoc1 Module Settings
Tim_ocstructinit (& tim_ocinitstructure );
Tim_ocinitstructure.tim_ocmode = tim_ocmode_toggle; // pin output mode: flip
Tim_ocinitstructure.tim_pulse = 2000; // flip cycle: 2000 pulses
Tim_ocinitstructure.tim_outputstate = tim_outputstate_enable; // enable the timettings Channel
Tim_ocinitstructure.tim_ocpolarity = tim_ocpolarity_high; // The output is a positive logic.
Tim_oc1init (tim1, & tim_ocinitstructure); // write Configuration

// Clear the interruption
Tim_clearflag (tim1, tim_flag_pc3 );

// Set the tim1 interrupt source to enable the capture and comparison interruptions of the corresponding channel
Tim_itconfig (tim1, tim_it_pc3, enable );

// Tim1 Enabled
Tim_cmd (tim1, enable );
// Channel output enabling
Tim_ctrlpwmoutputs (tim1, enable );
}

Step 5. Interrupt Service subroutine
Void tim1_cc_irqhandler (void)
{
2017-11-capture;
If (tim_getitstatus (tim1, tim_it_pc3) = set)
{
Tim_clearitpendingbit (tim1, tim_it_pc3 );
Capture = tim_getcapture1 (tim1 );
Tim_setcompare1 (tim1, capture plus 2000 );
// Here is an explanation:
// Increase the value of timereccr1 by 2000, so that the next tim event requires 2000 pulses,
// Another method is to reset the Pulse counter.
// Tim_setcounter (tim2, 0x0000 );
}
}

For Tim operations, note that because of the low power consumption of the stm32 processor, each module must enable the clock independently. Therefore, do not forget to enable the clock for the modules and pins used, for this reason, I have wasted a lot of time ~~!


The TIM module generates PWM

This is the PWM output mode of stm32. The tim1 module of stm32 is an enhanced timer module, which is born for motor control and can generate three sets of 6-way PWM, at the same time, two PWM channels in each group are complementary and can have a dead zone, which can be used to drive the H-bridge.
The following code uses Channels 1 and 2 of the tim1 module to generate a total of 4 PWM code examples. For similar code, refer to the corresponding example in the Firmware Library of St.
C Language: The tim1 module generates PWM with dead zone

// Step1. enable the TIM and corresponding port clock.
// Start gpio
Rcc_apb2periphclockcmd (rcc_apb2periph_gpioa | rcc_apb2periph_gpiob | \
Rcc_apb2periph_gpioc | rcc_apb2periph_gpiod ,\
Enable );
// Start afio
Rcc_apb2periphclockcmd (rcc_apb2periph_afio, enable );
// Start tim1
Rcc_apb2periphclockcmd (rcc_apb2periph_tim1, enable );

// Step2. configure gpio to output the output from AF.
// Pa.8/9: oc1 output port of tim1
Gpio_initstructure.gpio_pin = gpio_pin_8 | gpio_pin_9;
Gpio_initstructure.gpio_mode = gpio_mode_af_pp;
Gpio_initstructure.gpio_speed = gpio_speed_50mhz;
Gpio_init (gpioa, & gpio_initstructure );

// Pb.13/14 ports are set to the output ports of timeconch1n and timeconch2n.
Gpio_initstructure.gpio_pin = gpio_pin_13 | gpio_pin_14;
Gpio_initstructure.gpio_mode = gpio_mode_af_pp;
Gpio_initstructure.gpio_speed = gpio_speed_50mhz;
Gpio_init (gpiob, & gpio_initstructure );

// Step3. initialize the TIM Module
Void tim_configuration (void)
{
Tim_timebaseinittypedef tim_baseinitstructure;
Tim_ocinittypedef tim_ocinitstructure;
Tim_bdtrinittypedef tim_bdtrinitstructure;

// Set the tim1 basic counter (set the PWM frequency)
// Frequency = timereclk/(ARR + 1)
Tim_baseinitstructure.tim_period = 1000-1;
Tim_baseinitstructure.tim_prescaler = 72-1;
Tim_baseinitstructure.tim_clockdivision = 0;
Tim_baseinitstructure.tim_countermode = tim_countermode_up;
Tim_baseinitstructure.tim_repetitioncounter = 0;
Tim_timebaseinit (tim1, & tim_baseinitstructure );
// Enable the shadow register of ARR (the setting is not changed until an update event is generated)
Tim_arrpreloadconfig (tim1, enable );


// Set the timereoc1 module (set the duty cycle of Channel 1)
Tim_ocinitstructure.tim_ocmode = tim_ocmode_pwm1;
Tim_ocinitstructure.tim_outputstate = tim_outputstate_enable;
Tim_ocinitstructure.tim_outputnstate = tim_outputnstate_enable;
Tim_ocinitstructure.tim_ocpolarity = tim_ocpolarity_high;
Tim_ocinitstructure.tim_ocnpolarity = tim_ocnpolarity_high;
Tim_ocinitstructure.tim_pulse = 120;
Tim_oc1init (tim1, & tim_ocinitstructure );
// Enable the shadow register of The CCR1 register (the settings are not changed until an update event is generated)
Tim_oc1preloadconfig (tim1, tim_ocpreload_enable );

// Set tim2_oc2 module (Set 2-channel duty cycle)
Tim_ocinitstructure.tim_outputstate = tim_outputstate_enable;
Tim_ocinitstructure.tim_outputnstate = tim_outputnstate_enable;
Tim_ocinitstructure.tim_pulse = 680;
Tim_oc2init (tim1, & tim_ocinitstructure );
// Enable the shadow register of the CCR2 register (the setting is not changed until an update event is generated)
Tim_oc2preloadconfig (tim1, tim_ocpreload_enable );

// Dead zone settings
Tim_bdtrinitstructure.tim_ossrstate = tim_ossrstate_enable;
Tim_bdtrinitstructure.tim_ossistate = tim_ossistate_enable;
Tim_bdtrinitstructure.tim_locklevel = tim_locklevel_off;
Tim_bdtrinitstructure.tim_deadtime = 0x90; // adjust the dead zone size here 0-0xff
Tim_bdtrinitstructure.tim_break = tim_break_disable;
Tim_bdtrinitstructure.tim_breakpolarity = tim_breakpolarity_high;
Tim_bdtrinitstructure.tim_automaticoutput = tim_automaticoutput_enable;
Tim_bdtrconfig (tim1, & tim_bdtrinitstructure );

// Tim1 Enabled
Tim_cmd (tim1, enable );
// Tim1_oc channel output PWM (must be added)
Tim_ctrlpwmoutputs (tim1, enable );

}

In fact, the PWM module can also have a lot of tricks to play, for example, in the case of exceptions (such as CPU clock problems), you can urgently close the output to avoid serious accidents such as circuit burning

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.