2023-02-27 11:49 PM
Hi!
I am trying to write a program where I am waiting for receiving 6 bytes of data through UART. It works just fine the first time, than I restart the receive_IT function and nothing happens anymore. I have other codes where I use it just the same, the only difference is the MCU. For this project I am using an STM32F030F4P6.
main.c
volatile uint8_t rx_buffer[6] = {0};
int8_t step = 1;
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM3_Init();
MX_USART1_UART_Init();
MX_TIM14_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, rx_buffer, 6);
HAL_GPIO_WritePin(Sleep_X_GPIO_Port, Sleep_X_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(Sleep_Y_GPIO_Port, Sleep_Y_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(Sleep_Z_GPIO_Port, Sleep_Z_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(Step_X_GPIO_Port, Step_X_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(Step_Y_GPIO_Port, Step_Y_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(Step_Z_GPIO_Port, Step_Z_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(Dir_GPIO_Port, Dir_Pin, GPIO_PIN_RESET);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
stm32f0xx_it.c
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
/*
* x, e = 221
* x, h = 224
*
* y, e = 222
* y, h = 225
*
* z, e = 223
* z, h = 226
*
* p, k = 219
* p, b = 210
*/
for(i=0; i<2; i++){
sum_rx += rx_buffer[i];
}
for(i=2;i<6;i++){
sum_step += ((rx_buffer[i] - 48) * power(10, 5-i));
}
/*sum_step += (rx_buffer[5] - 48);
sum_step += ((rx_buffer[4] - 48) * 10);
sum_step += ((rx_buffer[3] - 48) * 100);
sum_step += ((rx_buffer[2] - 48) * 1000);*/
switch(sum_rx){
case 221:
HAL_GPIO_WritePin(Dir_GPIO_Port, Dir_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(Sleep_X_GPIO_Port, Sleep_X_Pin, GPIO_PIN_SET);
for(i=0; i<sum_step; i++){
HAL_GPIO_WritePin(Step_X_GPIO_Port, Step_X_Pin, GPIO_PIN_SET);
Delay(2);
HAL_GPIO_WritePin(Step_X_GPIO_Port, Step_X_Pin, GPIO_PIN_RESET);
}
HAL_GPIO_WritePin(Sleep_X_GPIO_Port, Sleep_X_Pin, GPIO_PIN_RESET);
break;
case 224:
HAL_GPIO_WritePin(Dir_GPIO_Port, Dir_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(Sleep_X_GPIO_Port, Sleep_X_Pin, GPIO_PIN_SET);
for(i=0; i<sum_step; i++){
HAL_GPIO_WritePin(Step_X_GPIO_Port, Step_X_Pin, GPIO_PIN_SET);
Delay(2);
HAL_GPIO_WritePin(Step_X_GPIO_Port, Step_X_Pin, GPIO_PIN_RESET);
}
HAL_GPIO_WritePin(Sleep_X_GPIO_Port, Sleep_X_Pin, GPIO_PIN_RESET);
break;
case 222:
HAL_GPIO_WritePin(Dir_GPIO_Port, Dir_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(Sleep_Y_GPIO_Port, Sleep_Y_Pin, GPIO_PIN_SET);
for(i=0; i<sum_step; i++){
HAL_GPIO_WritePin(Step_Y_GPIO_Port, Step_Y_Pin, GPIO_PIN_SET);
Delay(2);
HAL_GPIO_WritePin(Step_Y_GPIO_Port, Step_Y_Pin, GPIO_PIN_RESET);
}
HAL_GPIO_WritePin(Sleep_Y_GPIO_Port, Sleep_Y_Pin, GPIO_PIN_RESET);
break;
case 225:
HAL_GPIO_WritePin(Dir_GPIO_Port, Dir_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(Sleep_Y_GPIO_Port, Sleep_Y_Pin, GPIO_PIN_SET);
for(i=0; i<sum_step; i++){
HAL_GPIO_WritePin(Step_Y_GPIO_Port, Step_Y_Pin, GPIO_PIN_SET);
Delay(2);
HAL_GPIO_WritePin(Step_Y_GPIO_Port, Step_Y_Pin, GPIO_PIN_RESET);
}
HAL_GPIO_WritePin(Sleep_Y_GPIO_Port, Sleep_Y_Pin, GPIO_PIN_RESET);
break;
case 223:
HAL_GPIO_WritePin(Dir_GPIO_Port, Dir_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(Sleep_Z_GPIO_Port, Sleep_Z_Pin, GPIO_PIN_SET);
for(i=0; i<sum_step; i++){
HAL_GPIO_WritePin(Step_Z_GPIO_Port, Step_Z_Pin, GPIO_PIN_SET);
Delay(2);
HAL_GPIO_WritePin(Step_Z_GPIO_Port, Step_Z_Pin, GPIO_PIN_RESET);
}
HAL_GPIO_WritePin(Sleep_Z_GPIO_Port, Sleep_Z_Pin, GPIO_PIN_RESET);
break;
case 226:
HAL_GPIO_WritePin(Dir_GPIO_Port, Dir_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(Sleep_Z_GPIO_Port, Sleep_Z_Pin, GPIO_PIN_SET);
for(i=0; i<sum_step; i++){
HAL_GPIO_WritePin(Step_Z_GPIO_Port, Step_Z_Pin, GPIO_PIN_SET);
Delay(2);
HAL_GPIO_WritePin(Step_Z_GPIO_Port, Step_Z_Pin, GPIO_PIN_RESET);
}
HAL_GPIO_WritePin(Sleep_Z_GPIO_Port, Sleep_Z_Pin, GPIO_PIN_RESET);
break;
case 219:
htim3.Instance -> CCR1 = ki;
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
Delay(150);
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
break;
case 210:
htim3.Instance -> CCR1 = be;
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
Delay(150);
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
break;
default:
break;
}
for(i=0; i<7; i++){
rx_buffer[i] = 0;
}
HAL_UART_Receive_IT(huart, rx_buffer, 6);
step = 1;
sum_rx = 0;
sum_step = 0;
}
void Delay(uint8_t ms){
HAL_TIM_Base_Start(&htim14);
while(htim14.Instance -> CNT < ms){
}
htim14.Instance -> CNT = 0;
HAL_TIM_Base_Stop(&htim14);
}
int power(int x, int y){
int i;
int eredm = x;
if(y != 0){
for(i=1; i<y; i++){
eredm *= x;
}
}
else
eredm = 1;
return eredm;
}
I also tried not to call the HAL_UART_Receive_IT() inside the callback function, nothing else happened. I also checked the UART registers and everything seems the same as when I call the function the first time.
Thank you in advance!
********
Edit:
Thank you for the answers but today I was able to find the solution, yet I still don’t know why.
So Inoticed that the EIE bit in CR3 register don’t set to 1 after the second call of the HAL_UART_Receive_IT() function, but if I set it to 1 by hand before the function it works just fine.
Solved! Go to Solution.
2023-03-03 06:43 AM
Thank you for the answers but today I was able to find the solution, yet I still don’t understand.
So Inoticed that the EIE bit in CR3 register don’t set to 1 after the second call of the HAL_UART_Receive_IT() function, but if I set it to 1 by hand before the function it works just fine.
2023-02-27 11:57 PM
Your Delay uses an interrupt for advancing the time and if the priorities are not correct, that won't work in an interrupt handler. Set a break point in the handler and step through the code to find where it stops.
Generally, using delays and doing "excecssive" stuff in interrupt handlers is not recommended, but may work for your use case.
hth
KnarfB
2023-02-28 01:27 AM
I am not fully understand how my is delay using an interrupt. It only starts a timer, counts, and after a time stops again. Also if I don't use my delay function, the same thing happens.
The handler seems to run smoothly, no error or exceptional thing happens.
2023-02-28 02:34 AM
You're right, my fault, I was still thinking of HAL_Delay().
Check the registers, maybe the UART got an overrun error while you were processing the data.
hth
KnarfB
2023-02-28 07:57 AM
You should not do any comparing, for loops in the interrupt. Because you do, you're blocking other interrupts from firing like system tick, etc. Set a flag instead and get out quickly. Check the flag in main while loop, then call a function to do your for loop and switch/case statements. But you're main problem is that you don't check the HAL status when you call HAL_UART_Receive_IT.
Check this post i replied to to see how I set a flag if HAL_UART_Receive_IT returns HAL_BUSY and try to enable it again in main while loop.
2023-03-02 12:46 AM
Yes, rookie thing I don't check the HAL_Status, but unfortunatelly it doesn't help me. Anyway Hal statusr returns OK. I also rewrote the program, now I only have one quick check in the callback and than I have the switch-case in the while loop. But even if I call the HAL_UART_Receive_IT() after I am done with everything It still don't works.
2023-03-02 03:46 AM
I am trying to look at registers with little success. I was able to find that the following exception happens:
The only solution right now if call the MX_USART1_UART_INIT() again before calling the UART_Receive_IT(), because it sets the EOBF register to 0 again.
void zeroing(void){
for(i=0; i<6; i++){
rx_buffer[i] = 0;
}
sum_rx = 0;
sum_step = 0;
MX_USART1_UART_Init();
HAL_UART_Receive_IT(&huart1, &rx_buffer, 6);
}
2023-03-02 07:47 AM
What device are you receiving from and how often is it sending data?
2023-03-03 05:03 AM
Hi @BBara.1
When you consider that you are not able to receive anymore (so after the second call of HAL_UART_Receive_IT), what is the content of the ISR Status register of your Uart instance ? Especially, could you have a look at ORE bit ?
If overrun error is detected, reception chain is blocked until ORE is cleared.
2023-03-03 06:37 AM
I already edited the post at the end. I was finally able to find the solution. the EIE bit was the impostor :D