cancel
Showing results for 
Search instead for 
Did you mean: 

Using 2 UART on STM32?

antonius
Senior

Dear Members,

I want to read a result from my GPS,

it's Neo 6M

I initialized 2 UARTs UART 1 for PC and UART 2 for GPS,

I got this result :

INIT CODE GPS NEO - 6M....

                           

From GPS : 0690X0000087jMhQAI.png

Is it receiving properly ?

The code :

 char in[8];

printf("From GPS : ");

  HAL_UART_Receive(&huart2, (uint8_t *)in, 8, 1000);

HAL_UART_Transmit(&huart1, (uint8_t *)in, 8, 1);

printf("\r\n");

Green LED on GPS module is blinking...

Thanks

35 REPLIES 35
antonius
Senior

I try with :

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

 /* Prevent unused argument(s) compilation warning */

 UNUSED(huart);

 /* NOTE : This function should not be modified, when the callback is needed,

           the HAL_UART_RxCpltCallback can be implemented in the user file

  */

   if(huart->Instance==USART2)

   {

      while(1)

    HAL_UART_Transmit(&huart1, (uint8_t *)aRxBuffer, 10,0xFFFF);

      printf("interupt rom USART2 GPS");

  }

}

but there's nothing ??

in main()

while (1)

   {

      printf("INIT CODE GPS NEO - 6M....\r\n");

    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);

      HAL_Delay(260);

   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);

      HAL_Delay(260);

      printf("From GPS : ");

  HAL_UART_Receive_IT(&huart2, (uint8_t *)aRxBuffer, 1000); 

any helps?

thanks

it might take a little while for you to get enough GPS sentences to fill 1000 characters (which is when RxCpltCallback will be called).

BTW, it's not great form to use a infinite loop ('while(1)") in your callbacks (even if you're just playing around).

What you want to do is totally achievable; just last week I wrote code to poll a u-blox M8 on one UART and send data to another simultaneously... getting the hang of concurrent programming can take a little while... 9600 is pretty slow; try receiving just one character at a time, putting that into a queue in your completion routine and reading it out in main... that's (roughly) how I did it.

AvaTar
Lead

> void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

> {

> ...

>      while(1)

>    HAL_UART_Transmit(&huart1, (uint8_t *)aRxBuffer, 10,0xFFFF);

>     printf("interupt rom USART2 GPS");

Transmission is most probably blocking, calling it from interrupt context is disruptive. The same goes for the "printf()" call.

And what is the "while (1)" there supposed to do, except for never returning ???

can you share the code / pseudo code , please ?

Thanks

antonius
Senior

so in main :

HAL_UART_Receive_IT(&huart2, (uint8_t *)aRxBuffer, 1000); 

and

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

      printf("GPS INTERRUPT!");

}

??

antonius
Senior

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

   if(huart->Instance==USART2)

  {

      printf("GPS INTERRUPT!");

        //update Usart2 flag here

   }

}         

> ...getting the hang of concurrent programming can take a little while...

One of the rules is:

NEVER EVER block in a routine associated with asynchronous events. Like interrupts.

A handler must finish before the next element arrives, or can arrive. Rather simple with 9600 baud.

https://community.st.com/s/feed/0D50X00009XkVxKSAV

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

have a read about a circular queue (buffer).

to start with try something easy like:

// pseudo code so, probably wont compile
#define MYUART HUART2 // or whatever
 
uint8_t rxBuffer[0x20]; // nb: I'm cheating: power of 2 means I can use 0x1F as a mask
uint32_t rxChars = 0; // nb: for a real example you'll need two index variables (in and out)
 
void startRx()
{
  // pretty inefficient but will probably be ok for 9600
 uint32_t offset = (rxChars & 0x1f); // so count is actual receive count but offset is buffer index
  HAL_UART_Receive_IT(MYUART, rxBuffer+offset, 1);
}
 
void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart)
{
 if (huart==MYUART)
{
 rxChars += 1; // char is already in our buffer, inc count and bail out quickly since this is a callback
}
}
 
void main()
{
   // ...
  uint32_t lastRxChars = 0xFFFF;
 
 // ...
 
if (lastRxChars != rxChars)
{
  printf("now I have %lu chars\n", rxChars);
  lastRxChars = rxChars;
  startRx();
}
  
}

Clive's example below is more how I did it; the HAL API is not particularly easy to use for "simple" protocols like NMEA.

where is Clive's example ? I didn't see it ? but what I have is HAL API,

does GPS need DMA or interrupt method is acceptable enough ? thanks