Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

STM32F103 MCU timer is divided into three kinds, advanced timer, general timer, basic timer.

The advanced control timer (TIM1 and TIM8) consists of a 16-bit auto-loading counter driven by a programmable predivider. It is suitable for a variety of purposes, including measuring the pulse width of the input signal (input capture), or generating the output waveform (output comparison, PWM, complementary PWM with embedded dead time, etc.). Using timer predividers and RCC clock control predividers, it is possible to adjust the pulse width and waveform period from a few microseconds to a few milliseconds. Advanced control timers (TIM1 and TIM8) and universal timers (TIMx) are completely independent and do not share any resources. They can operate synchronously.

The functions of TIM1 and TIM8 timers include:

  • 16 bit up, down, up/down automatic loading counters
  • 16 bit programmable (can be modified in real time) predivider, the counter clock frequency divider coefficient is between 1 and 65535 any value
  • Up to 4 separate channels:
    • The input capture
    • The output is
    • PWM generation (Edge or middle alignment mode)
    • Single pulse mode output
  • Dead – time programmable complementary output
  • Use external signals to control timer and timer interconnect synchronization circuit
  • Allows repeating counters in timer registers to be updated after a specified number of counter cycles
  • The brake input signal can set the timer output signal to a reset state or a known state
  • Interrupt /DMA occurs when:
    • Update: Counter overflow up/down, counter initialization (via software or internal/external trigger)
    • Trigger event (counter starts, stops, initializes, or internally/externally triggers count)
    • The input capture
    • The output is
    • Brake signal input
  • Supports incremental (orthogonal) encoders and Hall sensor circuits for positioning
  • Trigger input as external clock or current management on a periodic basis

The main part of the programmable advanced control timer is a 16-bit counter and its associated auto-load register. This counter can count up, down, or up and down both ways. The counter clock is divided by a predivider. Counters, autoload registers, and predivider registers can be read and written by the software, even when the counter is still running.

The advanced timer initialization method is as follows:

void TIMER1_Init(u16 arr, u16 psc)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

    TIM_DeInit(TIM1);

    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_TimeBaseStructure.TIM_RepetitionCounter = 0x00;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

    TIM_ClearFlag(TIM1, TIM_FLAG_Update);
    TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);	// Allow update interrupts

    NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;		//TIM1 update is interrupted
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    TIM_Cmd(TIM1, ENABLE);
}
void TIM1_UP_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM1, TIM_IT_Update) ! = RESET) { TIM_ClearITPendingBit(TIM1, TIM_IT_Update); LED0 = ! LED0; }}Copy the code

Timer 1 is used here, and two parameters are passed during initialization, where ARR is used to set the timer period and PSC is used to set the clock’s frequency division coefficient. The default clock frequency of the timer is 72MHz. After setting these two parameters, the timer period is calculated as (arr+1) x (PSC +1)/72MHz. Set the timer counting mode to upward. Next, you need to set the value of the repeat timer. TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x00; This is a counter specific to advanced timers, set to 0 by default, which means the timer will always count in a loop and never stop. If set to a certain number, the timer will stop running after a certain number of times. If the timer needs to enable interrupt function, also need to set the NVIC register, which is used to set the interrupt priority of the timer.

int main(void)
{    
    delay_init();       // Delay function initialization
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    LED_Init();
    KEY_Init();  
    TIMER1_Init(9.71);		 //50Khz 10us Tout=(9+1)*(71+1)/72M=10us
      
    while(1) {}}Copy the code

The timer is initialized in the main program, and the timer period value is set to 9, the frequency division value is 71, and the calculated timer period is 10us. In the interrupt function, let the LED lamp reverse, through oscilloscope observation can see that LED level will change every 10us.