Skip to main content
Visitor II
April 2, 2022
Question

I use STM32L452RC for my project which prints in putty through USB CDC. Whenever a character is pressed in keyboard, I get an interrupt and USB_Receive_DS function gets called . Based on the character the controller takes necessary action.

  • April 2, 2022
  • 4 replies
  • 1093 views

I use a timer to wait for the next interrupt from the keyboard . The timeout is 30 Secs. The issue here is the HAL_TIM_Period_Elapsedcallback is getting called frequently , but I have set the timeout to be 30 Secs. Can anyone help me fix this issue ASAP. I use HAL_TIM_Basestart_IT to start the timer. And I have enabled the interrupt in NVIC settings too.

    This topic has been closed for replies.

    4 replies

    Super User
    April 2, 2022

    Sounds like your timer settings are wrong. What are they? Show some code.

    RAnan.3Author
    Visitor II
    April 2, 2022

    Hey, I have a main clock frequency of 80MHz and a prescaler which divides is 47000.

    So, 80000000 / 47000 = 1702.12Mhz . So the time period is 0.000587. My counter period is 50000 which finally gives me a timeout of 29.33 seconds (0.000587 * 50000).

    When I try to run the timer separately it works fine. When I try to integrate with USB CDC I faced the previous issue. So I guess the issue comes when I use both timer and USB CDC at the same time. I cant find a solution for that. Below is the snippet.

    // Receive callback function for USB CDC

    static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)

    {

     /* USER CODE BEGIN 6 */

     USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);

     USBD_CDC_ReceivePacket(&hUsbDeviceFS);

     memset(buff_ch,'\0',1);

      uint8_t len = (uint8_t)*Len;

      memcpy(buff_ch,Buf,len);

       usb_transmit();

     return (USBD_OK);

     /* USER CODE END 6 */

    }

    // Function which takes characters

    void usb_transmit()

    {

    if (buff_ch[0] != '\0')

    {

    rx_flag =1;

    HAL_TIM_Base_Start_IT(&htim1);

    tim_value = __HAL_TIM_GET_COUNTER(&htim1);

    if(buff_ch[0] =='a')

    {

    CDC_Transmit_FS(comp,sizeof(comp));

    delayUS(1000);

    CDC_Transmit_FS(comp_status,sizeof(comp_status));

    delayUS(1000);

    CDC_Transmit_FS(comp_relay,sizeof(comp_relay));

    delayUS(1000);

    }

    if(buff_ch[0] =='b')

    {

    CDC_Transmit_FS(solenoid1,sizeof(solenoid1));

    delayUS(1000);

    CDC_Transmit_FS(solenoid1_status,sizeof(solenoid1_status));

    delayUS(1000);

    CDC_Transmit_FS(sol1_relay,sizeof(sol1_relay));

    delayUS(1000);

    }

    if(buff_ch[0] =='c')

    {

    //HAL_TIM_Base_Start_IT(&htim1);

    CDC_Transmit_FS(solenoid2,sizeof(solenoid2));

    delayUS(1000);

    CDC_Transmit_FS(solenoid2_status,sizeof(solenoid2_status));

    delayUS(1000);

    CDC_Transmit_FS(sol2_relay,sizeof(sol2_relay));

    delayUS(1000);

    }

    if(buff_ch[0] =='d')

    {

    CDC_Transmit_FS(fan,sizeof(fan));

    delayUS(1000);

    CDC_Transmit_FS(fan_status,sizeof(fan_status));

    delayUS(1000);

    CDC_Transmit_FS(fan_relay,sizeof(fan_relay));

    delayUS(1000);

    }

    if(buff_ch[0] =='1')

    {

    comp_status = Relay1_ON;

    CDC_Transmit_FS(comp1_on,sizeof(comp1_on));

    delayUS(5000);

    }

    if(buff_ch[0] =='2')

    {

    comp_status = Relay1_OFF;

    CDC_Transmit_FS(comp1_off,sizeof(comp1_off));

    delayUS(5000);

    }

    if(buff_ch[0] =='3')

    {

    solenoid1_status = Relay2_ON;

    CDC_Transmit_FS(sol1_on,sizeof(sol1_on));

    delayUS(5000);

    }

    if(buff_ch[0]=='4')

    {

    solenoid1_status = Relay2_OFF;

    CDC_Transmit_FS(sol1_off,sizeof(sol1_off));

    delayUS(5000);

    }

    if(buff_ch[0] =='5')

    {

    solenoid2_status = Relay3_ON;

    CDC_Transmit_FS(sol2_on,sizeof(sol2_on));

    delayUS(5000);

    }

    if(buff_ch[0] =='6')

    {

    solenoid2_status = Relay3_OFF;

    CDC_Transmit_FS(sol2_off,sizeof(sol2_off));

    delayUS(5000);

    }

    if(buff_ch[0] =='7')

    {

    fan_status = Relay4_ON;

    CDC_Transmit_FS(fan_on,sizeof(fan_on));

    delayUS(5000);

    }

    if(buff_ch[0]=='8')

    {

    fan_status = Relay4_OFF;

    CDC_Transmit_FS(fan_off,sizeof(fan_off));

    delayUS(5000);

    }

    if(buff_ch[0] == 'm' || buff_ch[0] == 'M')

    {

    CDC_Transmit_FS(menu,sizeof(menu));

    delayUS(1000);

    }

    }

    if(buff_ch[0] == '\e')

    {

    rx_flag= 0;

    CDC_Transmit_FS(esc,sizeof(esc));

    clr = __HAL_TIM_CLEAR_IT(&htim1,TIM_IT_UPDATE);

    }

    }

    Super User
    April 2, 2022

    > The issue here is the HAL_TIM_Period_Elapsedcallback is getting called frequently

    How do you observe that, exactly?

    Read out and check/post content of TIM registers.

    JW

    RAnan.3Author
    Visitor II
    April 2, 2022

    STM CubeMX has a feature of break point. So when I put my break point there it comes inside the loop frequently. I use TIM1 for this. Adding below my elapsed callback function.

    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)

    {

    if(htim->Instance==TIM2)

    {

    counter_new++;

    ADC_Measure();

    }

    if(htim->Instance==TIM1)

    {

    rx_flag = 0; // This is where the breakpoint should come for every 29.33 Secs.

    }

    }

    The problem comes when integrating usb CDC and timer. Will switching controller to low power mode or using low power timer help in this case???

    Graduate
    April 2, 2022

    There are many problems with your code. CDC_Receive_FS() is called by USB interrupt. You can't successfully call Transmit from Receive more than once, as Transmit will not finish until you exit the ISR. Don't call any delays from this routine. Use switch instead of a sequence of if().

    RAnan.3Author
    Visitor II
    April 3, 2022

    Thanks. I need to add many conditions more than just checking the character. I felt if statement would be better to do that. What's wrong with my timer and USB here other than CDC_Rceieve_FS()

    Super User
    April 3, 2022

    > STM CubeMX has a feature of break point. So when I put my break point there it comes inside the loop frequently.

    Which loop?

    How frequently?

    Is there any other place in your program where you use timer-related functions, other than the snippet you've shown (and initialization)?

    JW

    RAnan.3Author
    Visitor II
    April 4, 2022

    // Loop inside which it is getting called.

    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)

    {

    if(htim->Instance==TIM2)

    {

    counter_new++;

    ADC_Measure();

    }

    if(htim->Instance==TIM1)

    {

    rx_flag = 0; // This is where the breakpoint should come for every 29.33 Secs.

    }

    }

    ​In the main function I use HAL_TIM_BASE_START_IT(TIM2)

    to start the timer in timer interrupt mode. And then once an over flow event it should come to the above loop and that would be my over flow event. I dont have any other timer snippets in this program.

    When I try to run it without USB it is working fine. When I try to use it with USB that is when this loop is getting called for almost every second. Is this because of working mode of controller? ​