Skip to main content
MGami.1
Associate III
May 25, 2021
Solved

Transmit data on UART without using any HAL function

  • May 25, 2021
  • 5 replies
  • 6556 views

Dear all,

I am working on STM32F413 microcontroller. 

I want to transmit data on UART without using any HAL function. 

And I want to send data in non blocking mode means on interrupt mode not in polling mode.

Can anyone help me out in this?

Thanks

This topic has been closed for replies.
Best answer by waclawek.jan

First

  • read RCC, GPIO, UART chapters in RM

In the global variables:

  • prepare a circular buffer for Tx, i.e. define an array of bytes of a given size, and two variables for buffer head and tail

In startup part of main():

  • enable GPIO clocks in RCC
  • enable UART clock in RCC
  • set up UART pins in respective GPIO_MODER as AF, and the AF per pin assignment table in datasheet
  • set UART baudrate, and enable UART
  • don't enable UART Tx interrupt in UART yet
  • enable UART interrupt in NVIC, optionally set its priority

In the program:

  • write UART ISR, make sure its name matches the one in the vector table in startup file
  • in the ISR, read in the status bits and check if the Tx empty bit is set; if not, simply exit the ISR
  • check if there are bytes to transmit (i.e. buffer tail does not equal head), if yes, pick byte, place it into the transmit data register, increment (wrapping) tail and exit ISR
  • if there are no bytes to transmit, disable Tx interrupt in USART and exit

In main, during runtime, whenever need to transmit arises:

  • place the data into the circular buffer, after checking if there's space for it (i.e. if the new head won't go past tail)
  • store the new head
  • enable the Tx interrupt in USART

JW

5 replies

TDK
May 25, 2021
"If you feel a post has answered your question, please click ""Accept as Solution""."
Pavel A.
May 25, 2021

UART examples by Tilen Majerle. Mostly LL, no HAL. And DMA :thumbs_up:

https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx/tree/master/projects

Tesla DeLorean
Guru
May 25, 2021

>>Can anyone help me out in this?

I'm not interested in writing all this code, if you want to do it without the HAL at least understand how the HAL implements it at a register level, and how the Reference Manual describes the registers. And how the NVIC works on the CM4.

If you want to do register level coding you need to own the task

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
PHolt.1
Senior
May 25, 2021

A good way to do this stuff is to use cube IDE to generate the code, and then chop all the garbage (like error conditions which cannot happen unless the silicon is faulty) out of it, then paste the remainder into your project, and throw away the original "project". I have never done this but know somebody who does.

waclawek.jan
waclawek.janBest answer
Super User
May 25, 2021

First

  • read RCC, GPIO, UART chapters in RM

In the global variables:

  • prepare a circular buffer for Tx, i.e. define an array of bytes of a given size, and two variables for buffer head and tail

In startup part of main():

  • enable GPIO clocks in RCC
  • enable UART clock in RCC
  • set up UART pins in respective GPIO_MODER as AF, and the AF per pin assignment table in datasheet
  • set UART baudrate, and enable UART
  • don't enable UART Tx interrupt in UART yet
  • enable UART interrupt in NVIC, optionally set its priority

In the program:

  • write UART ISR, make sure its name matches the one in the vector table in startup file
  • in the ISR, read in the status bits and check if the Tx empty bit is set; if not, simply exit the ISR
  • check if there are bytes to transmit (i.e. buffer tail does not equal head), if yes, pick byte, place it into the transmit data register, increment (wrapping) tail and exit ISR
  • if there are no bytes to transmit, disable Tx interrupt in USART and exit

In main, during runtime, whenever need to transmit arises:

  • place the data into the circular buffer, after checking if there's space for it (i.e. if the new head won't go past tail)
  • store the new head
  • enable the Tx interrupt in USART

JW