UART
Last updated
Last updated
Imagine you want to transfer 8-bit data to another board, one way is to connect 8 wires to another board:
However, this is terrible. What if we want to transfer 32-bit data? We would need a lot of wires.
This calls for communication protocols, which aims to allow devices to communicate with each other using as few wires as possible.
UART is a protocol used for serial communication and is used when the rate of transmission is not a concern. For example, UART could be used to send control commands but it isn't suitable to send high resolution images.
In our embedded system, UART is commonly used between two different boards or when trying to send data from an mobile/desktop application to your board using bluetooth.
UART sends your data in serial, asynchronous mode.
Serial communication is the process of sending data one bit at a time. For example, if we want to transmit data from UART1 to UART2, data will be sent bit by bit from the TX pins and received by the RX pins.
Asynchronous means that there is no common clock signal between the sender and receivers. In other words, the clocks of the STM32 and the bluetooth device may be different. As there is no way for the receiving side to determine the transmission speed dynamically, we need to predefine the same baud rate on both sides for the communication.
To check which serial ports can be used as UART, you need to take a look on the main board, there should be small text UART X
(Should be UART 1 and 3).
1. Word Length, Parity and Start/Stop Bits
During transformation, data is sent in a packet. According to the standard of uart, it sends 1 start bit (must), 5/6/7/8 bits of data (not 9), 1 bit of parity check (optional),1/1.5/2 bit of stop bit.
You do not need to modify these parameters for now, just use the default values and make sure the config on both sides of communication is the same. The two extra bit of start bit and stop bit are handled automatically by stm32 and coolterm(later discussed) and you don't have to worry about them.
2. Baud rate
Baud rate is the number of bits of the signal sent per second and have predefined standards.
Possible baud rate values: 9600, 14400, 19200, 38400, 57600, 115200, 128000, 230400, 256000, 460800 ...
115200
is the most common and quickest speed that works on most devices without any problem, therefore, recommended in this tutorial. For example, standard windows (or, .net) utilities does not support anything above 115200. Our setting uses 1 start bit, 8 data bits, 0 parity bit and 1 stop bit, which means that 8 bit = 1 byte out of 10 bits sent are data, with a baud rate of 115200, effectively 11520 bytes of data could be sent in one second.
Note Make sure the baud rates on both sides of the communication are the same.
Like most board/pin controls you have learnt so far, a UART port needs to be initialised before it is available for use. The init functions should already be called in main.c based on your board configuration.
From main.c:
After the initialization, you can start sending and receiving data by calling functions from the HAL Library.
Helper functions documentation for your reference: https://www.disca.upv.es/aperles/arm_cortex_m3/llibre/st/STM32F439xx_User_Manual/group__uart__exported__functions__group2.html
Transmit function
HAL_UART_Transmit()
transmits the given data within the time limit.
huart
: UART handler. HAL Library needs to know what UART port should be used for data transfer. &huart1 and &huart3 are the possible values.
pData
: Data array. Here it means the sequence of data that you want to transmit.
Size
: The length of data array.
Timeout
: Time limit for transmitting data. If huart is busy for some reasons (for example, sending other data), the program will stay for at most Timeout millisecond to wait until the sending operation is completed. if the program reaches time limit, it will give up to transmit data.
TX Example:
Receive function
HAL_UART_Receive()
receives the given data within the time limit.
huart
: UART handler. HAL Library needs to know what UART port should be used for data receive. &huart1 and &huart3 are the possible values.
pData
: Data array. Here it means the array that you want to store received data in.
Size
: The length of data array.
Timeout
: Time limit for receiving data. If huart is busy for some reasons (for example, not receiving any data), the program will stay for at most Timeout millisecond to wait until the receiving operation is completed. if the program reaches time limit, it will give up to receive data.
RX Example:
Blocking vs Non-Blocking:
When calling HAL_UART_Transmit() / HAL_UART_Receive(), your code will pause at the function call until data is successfully transmitted / received.
In some situations this is problematic, for example:
Direct download Coolterm for everyone: https://github.com/UST-Robotics-Team/Software-Tutorial-2022/releases/tag/coolterm (Below are for your information) Coolterm (Windows / Mac): https://freeware.the-meiers.org/ Serial Debug Assistant (Microsoft Store only): https://apps.microsoft.com/store/detail/serial-debug-assistant/9NBLGGH43HDM HTerm (Windows only): http://der-hammer.info/pages/terminal.html
We use Coolterm for demonstration, but there are different ways to interact with UART signals. Some examples are Tera term, mobile applications, and python/C# programs written by yourself using Bluetooth stack. However, we may not be able to provide support to people not using Coolterm.
Locate the UART1/UART3 port on your STM32 (it's below your ST-Link port/flashing port) and connect your TTL to the UART port as follows.
5V0
V
TXD
R
RXD
T
GND
G
If you are using HC-05 (one of the bluetooth modules), please follow the pin arrangement below:
5V
V
TX
R
RX
T
GND
G
5V0
5V
GND
GND
TX
RX
RX
TX
For hardware, our UART ports follow the pin order of "VTRG".
Open coolterm and set up as below:
For the CoolTerm terminal, raw mode means that data will be sent when you press a key on the keyboard, whereas there will be an extra line for you to input a whole string and send at once in line-mode. This two modes mostly matter when configuring the Bluetooth device and will be covered later.
Local echo means that CoolTerm will display what you typed and does not affect what you send/receive.
For Mac users choose DANNY2
For Win users choose the new added com port (e.g. COM5)
Connect the USB-TTL with your device as follows:
Hold the button on HC05 while plugging in the USB to the computer
Release the button, HC05 should be in "AT" mode and the led should flash slowly.
Set CoolTerm baud rate to 38400 and connect. (or try 9600 if 38400 doesn't work)
Type AT
and press enter. If it replies OK
then you can use the following AT commands to configure the device. Otherwise, check the steps above again.
Note that some commands (such as AT+NAME=...
/AT+NAME?
) may require you to hold the button while pressing enter to work.
Note that AT command is case-sensitive.
List of commands:
AT
: For Testing only
AT+RESET
: Back to normal mode, doesn't mean reset configs
AT+NAME?
: Return name of the device
AT+NAME=<Param>
: Set name to <Param>
AT+PSWD?
: Return password
AT+PSWD=<Param>
: Set password to <Param>
AT+UART=<Param>,<Param2>,<Param3>
: Set baud rate, stop bit (0 -- 1 bit, 1 -- 2 bit), no. of parity bit (recommended settings: AT+UART=115200,0,0)
AT+UART?
: Return setting of uart
AT+ROLE=<Param>
: Set the module role (0 -- Slave, 1 -- Master)
AT+ROLE?
: Return the module role
AT+CMODE=<Param>
: Set the connection mode (0 -- specified device, 1 -- any device)
AT+CMODE?
: Return the connection mode
AT+ORGL
: Reset all setting to default ones
AT Command Manual for HC-05: https://s3-sa-east-1.amazonaws.com/robocore-lojavirtual/709/HC-05_ATCommandSet.pdf
AT Command Manual for HC-08(Reference only): https://www.rhydolabz.com/documents/30/hc05_bluetooth.pdf
After configuring the device, you may plug it onto UART port of your STM32 board. The computer should be able to find the device when power is given to HC05. After pairing with the device, rescan the port in the "serial port" option of coolterm and new ports should appear. The port that requires time connecting is likely the correct port, as your computer is acting as the master side and need to wait for HC05 to respond, while the other port waits for HC05 actively connect with the computer(which will not happen).
Adding in HC05 allow you to communicate wirelessly, but the actual usage is the same with connecting directly.
Step 0: Default baudrate during configuration is 38400, make sure to set it in CoolTerm.
Step 1: Connect, then ping with AT, should reply with OK
Step 2: Enquire and set the name of the module
Step 3: Enquire and set the password of the module
Step 4: Set the role of the module to Slave(Your computer is the master)
Step 5: Set connection mode to 1 (This allows it to connect to any nearby devices)
What you should see in coolterm:
Strings to send:
Turn on LEDx: +x
Turn off LEDx: -x
e.g. to turn on LED1: +1
; to turn off LED3: -3
.
Toggle LEDx: /x
LED should keep toggling until a +
or -
command is sent.
You should parse these commands on the mainboard and perform the appropriate action.
note: in C, you do not directly compare two strings (i.e. " "==" "
is invalid), instead, you compare each char (i.e. ' '==' '
is valid)
Step 1: Connect, then ping with AT, should reply with OK. (try 9600 if 38400 doesn't work)