0

I have some problem when I use a stm32 discovery board send data to another one and it can get correct data and print in callback function, but cannot print correctly in other function.

void UART7_IRQHandler()
{
    HAL_UART_IRQHandler(&huart7);
    HAL_UART_Receive_IT(&huart7, (uint8_t *)UART7RxBuffer, 16);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart)  
{   
    if(huart->Instance == UART7) {
        X = (UART7RxBuffer[1]-48) + (UART7RxBuffer[3]-48)*0.1 + (UART7RxBuffer[4]-48)*0.01 + (UART7RxBuffer[5]-48)*0.001;           
    }
}

But I receive wrong data like this

void controller(){
    printf("%.3f\t\n", X);
}

It should be 0.012, and it correct in HAL_UART_RxCpltCallback(), I receive -38.02, -0.009, 0.512, 0.012, -1.948 and so on in controller. How should I do to prevent this situation?

林鼎倫
  • 1
  • 2
  • You mean, `X` is always `0.012` inside `HAL_UART_RxCpltCallback`, and it's not being written from anywhere else, but a random value is printed inside some other function? Please post a [mcve]. – vgru Nov 15 '17 at 14:50
  • You don't seem to have any means to protect the shared data, so you'll most likely have massive race conditions. You need to implement semaphores or similar. In addition, having floating point calculations inside an ISR is not a great idea. It doesn't look like you _need_ floating point either, since you wish to parse out an exact 4 digit value from ASCII, you can do this better and faster with unsigned 16. Do you at least have a FPU on the microcontroller? Also, what's at index 0 of that string and why do you skip it? – Lundin Nov 15 '17 at 14:51
  • @Lundin: my guess is the sign character (i.e. `" 0.012"` or something like that), since the decimal dot at idx `[2]` is also skipped. But yes, this will work by pure luck. If a single byte is ever skipped or inserted into the stream, it will read incorrect values forever. – vgru Nov 15 '17 at 14:54
  • So I should use mutex or semaphores to send data? – 林鼎倫 Nov 16 '17 at 11:28

1 Answers1

0

Without knowing if your MCU actually supports floating point etc, I would probably do something like this in order to diagnose/debug what is happening:

void UART7_IRQHandler()
{
    HAL_UART_IRQHandler(&huart7);
    HAL_UART_Receive_IT(&huart7, (uint8_t *)UART7RxBuffer, 16);
}

char d1;
char d2;
char d3;
char d4;
float X1;
float X2;
float X3;
float X4;
float X;

void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart)  
{   
    if(huart->Instance == UART7) {
        d1 = UART7RxBuffer[1]-48;  /* add breakpoint here, and single step from here while inspecting variables */
        d2 = UART7RxBuffer[3]-48;
        d2 = UART7RxBuffer[4]-48;
        d3 = UART7RxBuffer[5]-48;
        X1 = d1;
        X2 = d2 * 0.1;
        X3 = d3 * 0.01;
        X4 = d4 * 0.001;
        X = X1 + X2 + X3 + X4;
    }
}
Stian Skjelstad
  • 2,277
  • 1
  • 9
  • 19