USART ARM,STM32 BARE-METAL USART CODİNG
USART introduction :The USART offers a flexible means to perform Full-duplex data exchange with external equipments requiring an industry…
USART ARM,STM32 BARE-METAL USART CODİNG
USART introduction :The USART offers a flexible means to perform Full-duplex data exchange with external equipments requiring an industry standard NRZ asynchronous serial data format. A very wide range of baud rates can be achieved through a fractional baud rate generator.
USART main features • Configurable oversampling method by 16 or 8 to achieve the best compromise between speed and clock tolerance • Baud rate generator systems • Programmable data word length (7, 8 or 9 bits) • Programmable data order with MSB-first or LSB-first shifting • Configurable stop bits (1 or 2 stop bits) • Synchronous master/slave mode and clock output/input for synchronous communications • Parity control: — Transmits parity bit — Checks parity of received data byte • Interrupt sources with flags

Character transmission procedure To transmit a character, follow the sequence below:
- Program the M bits in USART_CR1 to define the word length.
- Select the desired baud rate using the USART_BRR register.
- Program the number of stop bits in USART_CR2.
- Enable the USART by writing the UE bit in USART_CR1 register to 1.
- Select DMA enable (DMAT) in USART_CR3 if multibuffer communication must take place. Configure the DMA register as explained in Section 33.5.10: USART multiprocessor communication.
- Set the TE bit in USART_CR1 to send an idle frame as first transmission. 7. Write the data to send in the USART_TDR register. Repeat this for each data to be transmitted in case of single buffer. — When FIFO mode is disabled, writing a data to the USART_TDR clears the TXE flag. — When FIFO mode is enabled, writing a data to the USART_TDR adds one data to the TXFIFO. Write operations to the USART_TDR are performed when TXFNF flag is set. This flag remains set until the TXFIFO is full.
- When the last data is written to the USART_TDR register, wait until TC = 1. — When FIFO mode is disabled, this indicates that the transmission of the last frame is complete. — When FIFO mode is enabled, this indicates that both TXFIFO and shift register are empty. This check is required to avoid corrupting the last transmission when the USART is disabled or enters Halt mode.
Even parity : The parity bit is calculated to obtain an even number of “1s” inside the frame of the 6, 7 or 8 LSB bits (depending on M bit values) and the parity bit. As an example, if data = 00110101 and 4 bits are set, the parity bit is equal to 0 if even parity is selected (PS bit in USART_CR1 = 0).
Odd parity : The parity bit is calculated to obtain an odd number of “1s” inside the frame made of the 6, 7 or 8 LSB bits (depending on M bit values) and the parity bit. As an example, if data = 00110101 and 4 bits set, then the parity bit is equal to 1 if odd parity is selected (PS bit in USART_CR1 = 1)

example source : http://keshavsps.blogspot.com/2017/11/parity-bit.html

Lets coding, first step determine the pins to use usart Tx/Rx order Pa2/Pa3, then clock bus must be initialize then mode register and alternate function register must configured . RCC,MODER, AFR

RCC->IOPENR |= (1U << 0); //Enable clock for GPIOA RCC->APBENR1 |= (1U << 17); //Enable clock for USART2
GPIOA->MODER &= ~(3U << 22); //Alternate func. configured start GPIOA->MODER |= (2U << 22); // for pin 2 port A set 10 to a.f. GPIOA->AFR[0] &= ~(0xFU << 42); GPIOA->AFR[0] |= (1 << 42); //USART2_TX was defined AF1 so 1U must write to ARFx(bit3)
GPIOA->MODER &= ~(0xFU << 23); GPIOA->MODER |= (2U << 23); GPIOA->AFR[0] &= ~(0xFU << 43); GPIOA->AFR[0] |= (1U << 43); //1 the value comes table13 afx //USART2_RX was defined AF1 so 1U must write to ARFx(bit3)

mode register source stm

then now configurate usarts registers those Control Reg(CR), Baud Rate Register(BRR), then NVIC must arrenged interrupt order and wake up. Bit0 :usart enable, Bit2 : reciever enable, Bit3 : transmitter enable, these bit are essential.
// cr 0. enable 2.receive 3.transmi 5. receive interrupt USART2->CR1 = 0; //RESET USART CONTROL REG USART2->CR1 |= (1U << 3); //TRANSMiT ENABLE USART2->CR1 |= (1U << 2); //RECiEVE ENABLE USART2->CR1 |= (1U << 5); //Bit 5 RXFNEIE: RXFIFO not empty interrupt enable // iNTERRUPT ENABLE WHiLE DATA RECiEVE USART2->BRR = (uint16_t)(SystemCoreClock / baud) ; //BAUD RATE REG USART2->CR1 |= (1U << 0); // USART ENABLE
NVIC_SetPriority(USART2_IRQn ,1); NVIC_EnableIRQ(USART2_IRQn);



Now when the buffer is emtpy interrupt occurs so we must coding handler function as defined name. Function name must be USART_IRQHandler(void), Data must write Transmite Data Register to transmit data, USARTx->TDR, and data size must be uint8_t
void USART_IRQHandler(void) { uint8_t data = (uint8_t)USART2->RDR; printChar(data); }
void printChar( uint8_t ch) { USART2->TDR = (uint16_t)ch; while( !(USART2->ISR & (1U << 6 ))); //6. bit set when TX is done }
You get the whole code on a file from : https://github.com/neomehmet/stm32G031k8_USART/blob/main/main.c.txt
Mehmet KOSE — GTU — ELECTRONICS
메타데이터
- post_id
- ca83f1e2a3e9
- slug
- usart-arm-stm32-bare-metal-usart-codi̇ng-ca83f1e2a3e9
- url
- https://medium.com/@neosapienss/usart-arm-stm32-bare-metal-usart-codi%CC%87ng-ca83f1e2a3e9
- canonical_url
- https://medium.com/@neosapienss/usart-arm-stm32-bare-metal-usart-codi%CC%87ng-ca83f1e2a3e9
- author_url
- https://medium.com/@neosapienss
- status
- ok
- fetched_at
- 2026-06-20 20:29:01