Skip to main content
haye
Associate III
December 17, 2018
Question

UART receiving problem (using interrupts)

  • December 17, 2018
  • 4 replies
  • 1848 views

Hello everyone,

I am facing a issue I can't explain.

I am migrating a code from F1 to F2.

I am using UART4. If I only use this peripheral I can send and receive data and everything work well.

Then I am using a the TIM6 to have a 2ms counter.

In the IRQ of the timer I only do this (minimal code to find the bug).

void TIMER_LCD_IRQHandler(void)

{

if (TIM_GetITStatus(TIMER_LCD, TIM_IT_Update) != RESET)

{  

  

TIM_Cmd(TIMER_LCD, DISABLE);

TIM_ClearITPendingBit(TIMER_LCD, TIM_IT_Update);

TIM_Cmd(TIMER_LCD, ENABLE);

}

}

Now with this activation I am loosing data in UART reception. If I comment the TIM_Cmd line everything work well.

This code is working well on the STM32F1. But on the STM32F2 from time to time I loose some data from my UART reception (throught interrupt).

I don't understand the issue because there is no interraction between those 2 peripheral.

I guess I'm missing something about the interrupts.

Does someone have an idea of what the issue could be ?

Thank you for your help !

    This topic has been closed for replies.

    4 replies

    Tesla DeLorean
    Guru
    December 17, 2018

    >>Does someone have an idea of what the issue could be ?

    You're interrupting too frequently? >= 250 KHz perhaps?

    Don't see TIM initialization, hard to guess. 2ms (500 Hz) should be fine, but is that what you've configured?

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    haye
    hayeAuthor
    Associate III
    December 17, 2018

    Thank you for your answer Clive.

    Here is the timer configuration for 2ms (I check at the oscilloscope and the period is 2ms):

    #define TIMER_LCD TIM6

    #define TIMER_LCD_IRQn TIM6_DAC_IRQn

    #define TIMER_LCD_IRQHandler TIM6_DAC_IRQHandler

    #define TIMER_LCD_PRIORITY 2

    #define TIMER_LCD_NB_MS 2

    #define TIMER_LCD_PULSE_PER_MS 4375

    #define TIMER_LCD_PRESCALER 13

    #define TIMER_LCD_ENABLE_IT TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE)

    void TIMER_LCD_init(void)

    {

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6 , ENABLE);

    NVIC_InitTypeDef NVIC_InitStructure;

      

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

    NVIC_InitStructure.NVIC_IRQChannel = TIMER_LCD_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIMER_LCD_PRIORITY;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

    /* Time base configuration */

    TIM_TimeBaseStructure.TIM_Period = TIMER_LCD_PULSE_PER_MS * TIMER_LCD_NB_MS;

    TIM_TimeBaseStructure.TIM_Prescaler = TIMER_LCD_PRESCALER;    

    TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;

    TIM_TimeBaseInit(TIMER_LCD, &TIM_TimeBaseStructure);

    /* TIM enable counter */

    TIM_Cmd(TIMER_LCD, ENABLE);

    /* TIM IT enable */

    TIMER_LCD_ENABLE_IT;

    }

    After Forever
    Senior III
    December 17, 2018

    Is there any other interrupt enabled for the timer's IRQ handler besides the TIM_IT_Update? Maybe something else is firing, and you don't clear its pending bit, and it keeps firing.

    Also make the UART interrupt priority higher (lower number), with pre-emption.

    haye
    hayeAuthor
    Associate III
    December 17, 2018

    Thank you for your answer.

    There is no other interrupts enabled.

    Concerning the priority I could change it to get the UART interrupt triggering first. But on the F1 with those priority there is no problem.

    haye
    hayeAuthor
    Associate III
    December 17, 2018

    Thank you for your answer Clive.

    Here is the timer configuration for 2ms (I check at the oscilloscope and the period is 2ms):

    #define TIMER_LCD TIM6

    #define TIMER_LCD_IRQn TIM6_DAC_IRQn

    #define TIMER_LCD_IRQHandler TIM6_DAC_IRQHandler

    #define TIMER_LCD_PRIORITY 2

    #define TIMER_LCD_NB_MS 2

    #define TIMER_LCD_PULSE_PER_MS 4375

    #define TIMER_LCD_PRESCALER 13

    #define TIMER_LCD_ENABLE_IT TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE)

    void TIMER_LCD_init(void)

    {

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6 , ENABLE);

    NVIC_InitTypeDef NVIC_InitStructure;

      

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

    NVIC_InitStructure.NVIC_IRQChannel = TIMER_LCD_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIMER_LCD_PRIORITY;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

    /* Time base configuration */

    TIM_TimeBaseStructure.TIM_Period = TIMER_LCD_PULSE_PER_MS * TIMER_LCD_NB_MS;

    TIM_TimeBaseStructure.TIM_Prescaler = TIMER_LCD_PRESCALER;    

    TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;

    TIM_TimeBaseInit(TIMER_LCD, &TIM_TimeBaseStructure);

    /* TIM enable counter */

    TIM_Cmd(TIMER_LCD, ENABLE);

    /* TIM IT enable */

    TIMER_LCD_ENABLE_IT;

    }

    Tesla DeLorean
    Guru
    December 17, 2018

    Are you using C++ or .cpp files?

    Might want to clear the local/auto variables, and check the math on the dividers, don't know the clock speeds here.

    Don't do work in the interrupt that blocks.

    Set the USART preemption level higher (lower number), and make sure the NVIC group setting is splitting priority/preemption usefully.

    extern "C" void TIMER_LCD_IRQHandler(void)
    {
     if (TIM_GetITStatus(TIMER_LCD, TIM_IT_Update) != RESET)
     { 
     TIM_ClearITPendingBit(TIMER_LCD, TIM_IT_Update);
     // Do work that takes a few microseconds here
     }
    }

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    haye
    hayeAuthor
    Associate III
    December 18, 2018

    I am using C files. The APB2 Clock is 60MHz.

    In the interrupt block I do only what I post (Disable clear Enable)

    The thing I don't understand is the exact same code work on a F1 and don't on the F2

    S.Ma
    Principal
    December 23, 2018

    F1 and F2 have generation difference, for example the way to program the alternate functions in GPIO is very much different. The USART RX interrupt should have the priority over the other sources. Use 2 GPIO to check how long last each interrupt and look at their timings. Maybe something is bogus... an oscilloscope for debugging is advised.