cancel
Showing results for 
Search instead for 
Did you mean: 

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.

RAnan.3
Associate III

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.

8 REPLIES 8
TDK
Guru

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

If you feel a post has answered your question, please click "Accept as Solution".

> 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.3
Associate III

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);

}

}

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???

gbm
Lead III

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().

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
RAnan.3
Associate III

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()

> 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

// 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? ​