How to Setup UART using Registers in STM32
This is yet another tutorial in the Register Based Series in STM32, and today we will see how can we setup the UART for Transmitting and receiving data.
This will be a simple setup, with no interrupts or DMA. We will simply receive and Transmit the data in the blocking mode. I will cover the Interrupts and DMA in the upcoming tutorials.
Let’s start with the PIN Setup for the UART
I am going to use the UART 2, and the Pins that I need to setup are Pin PA2 for Tx and Pin PA 3 for Rx
Since we are using the Pins for Alternate Function, we need to select the Alternate Function Mode in the MODE Register
- Here we will enable the Clock for the GPIOA Port
- Then select the Pins PA2 and PA3 in the Alternate Function mode
- This is done by writing ‘1 0’ (2) in the 4th and 6th positions.
Now the Pins are setup as the Alternate Functions, but we still need to choose which function exactly. For eg: Is it I2C, SPI or UART etc.
This can be done in the Alternate Function Register
- Here First we have to look up for which alternate function is associated with the UART 2
- In this case it’s AF7
- Now in the Alternate Function Register, we will choose the AF7 (0111) for the Respective Pins
Pin Config in F103
In some Microcontrollers, the Alternate Function Mode is not available Directly, for eg: in F103C8. Here We have to choose the Mode in a different way.
- Here First of all we need to choose the correct mode from the GPIO Configuration for Device Peripherals
- UART TX in full duplex mode should be set as Alternate Function Push Pull
- and UART RX should be set as Input Pull UP
- So we will configure the GPIO Control Register (CRL/CRH) based on this configuration.
Now the Pin Configuration is complete, we will move to the UART Configuration.
The most important Register used in UART configuration is UART Control Register 1 (CR1). Most of the Configuration is done here.
I have only included the important bits in the image. The rest are kept 0 for now. We will modify them as per the requirement in the future.
- We will enable the UART first. To setup other bits, UART needs to be enabled.
- Bit 12 is kept at 0, and it means there will be 1 start bit and 8 Data Bits.
- Then We will enable the Transmitter and Receiver.
- I am also selecting the Baud rate here. The details about the Baud Rate are mentioned below
Selecting the Baud Rate
The Baud Rate can be Programmed into the Baud Rate Register (UART_BRR). The calculation for the Baud Rate is Shown below
- Here the UART2 is connected to the APB1 Clock, and therefore the Fck = 45 MHz (APB1 Peripheral Frequency)
- Now If we want the Baud Rate of 115200, the MENSTISSA will come equal to 24, and the FRACTION = 7
- We will program these values in the 0th Position (for FRACTION) and in the 4th position (for MENTISSA) in the BRR Register.
This completes the Configuration part of the UART. Now we will see how to send or receive data using the UART
To handle the sending and the receiving, the STATUS Register plays a very vital part. Below is the picture of the Status register
- Here we are mainly interested in these 3 bits.
- TXE bit will be set once the content of the Data Register has been transferred to the Shift Register. Now the Shift Register will start sending the data to the Tx Line.
- In the means time we can put another data byte into the Data Register, and later that byte will also be transferred to the Shift register.
- Once all the data bytes have been transferred (after the stop bit is sent), the TC flag will be set.
- Similarly during the receive, we will wait for the RXNE bit to set.
- This bit is set if there is data in he DATA Register, and once it is confirmed, we can read the data.
- Here we will load he data into the Data Register, and wait for the TC bit to set.
- This will indicate that the data has been transferred
- During the receive, we will wait for the RXNE bit to set.
- This will indicate that there is some data available in the Data Register
- Now we will read the data
Here after initializing the system clock and the UART, we can send or receive data in the while loop.