Skip to main content
Singh12
Associate
May 21, 2021
Question

UART Transmit, bare metal (no HAL OR LL). I just want to transfer 1 charater(later i would do a string) I am reading the character through hercules. Baud rate is 115200. (16Mhz / 115200 = 0x8B) here's the code. where am i going wrong?

  • May 21, 2021
  • 2 replies
  • 1606 views

#include<stdint.h>

#include "usart.h"

void

clock_init(void);

void

clock_init(void)

{

 RCC->CR &= ~(RCC_CR_HSIDIV);

 RCC->CR |= RCC_CR_HSION;

}

int 

main()

{

 clock_init();

 usart_init();

 while(1)

 {

 }

}

#include <stdint.h>

#include "stm32g0xx.h"         // Device header

#include "usart.h"

void

isr(void);

uint8_t *ptr = "H";

uint8_t s = 2;

void

usart_init()

{

 RCC->APBENR1 |= RCC_APBENR1_USART2EN;

  

 GPIOA->AFR[0] |= GPIO_AFRL_AFSEL2_0;

 GPIOA->MODER  &= ~GPIO_MODER_MODE2;

 GPIOA->MODER  |= GPIO_MODER_MODE2_1;

 GPIOA->AFR[0] |= GPIO_AFRL_AFSEL3_0;

 GPIOA->MODER  &= ~GPIO_MODER_MODE3;

 GPIOA->MODER  |= GPIO_MODER_MODE3_1;

 NVIC_SetPriority(USART2_IRQn, 0);

 NVIC_EnableIRQ(USART2_IRQn);

  

 RCC->APBENR2  |= RCC_APBENR2_SYSCFGEN;

 RCC->APBENR1  |= RCC_APBENR1_PWREN;

  

 USART2->CR1  |= USART_CR1_TXEIE_TXFNFIE;

 USART2->CR1  |= USART_CR1_TE;

 USART2->BRR   = 0x8B;

  

 USART2->CR2  &= ~(USART_CR2_LINEN | USART_CR2_CLKEN);

 USART2->CR3  &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);

  

 USART2->CR1  |= USART_CR1_UE;  

}

void

USART2_IRQHandler(void)

{

 isr();

}

void

isr(void)

{

 if (s == 0)

 {

  USART2->CR1 &= ~(USART_CR1_TXEIE_TXFNFIE);

 }

 else

 {

  USART2->TDR = (uint8_t)((*ptr) & (uint8_t)0xFF);

  ptr++;

  s--;

 }

}

This topic has been closed for replies.

2 replies

waclawek.jan
Super User
May 21, 2021

Read out and check the GPIO and UART registers content.

I don't see GPIO clock being enabled.

JW

Singh12
Singh12Author
Associate
May 21, 2021

I am sorry, the clock_init function actually had one more line. but while writing the question here, i did a mistake.

void clock_init(void)

{

 RCC->CR &= ~(RCC_CR_HSIDIV);

 RCC->CR |= RCC_CR_HSION;

 RCC->IOPENR |= RCC_IOPENR_GPIOAEN;

}

I am enabling the clock of GPIOA too.

While running in debug mode, the TDR register also gets the 0x48 value(HEX code ASCII of character 'H').

still, on hercules application on my pc, i dont recieve anything.

using HAL USART driver, i could do it in 3 minutes, without any issue.

gbm
Lead III
May 24, 2021

There are many small mistakes and many lines of unnecessary code, setting the bits which are already zeros to zeros.. The whole UART programming should take just 2 lines:

USART2->BRR = (HCLK_FREQ + BAUD_RATE / 2) / BAUD_RATE;

USART->CR1 = USART_CR1_RE | USART_CR1_TE | USART_CR1_UE.

No need to touch CR2 and CR3. No need to set IRQ priority to 0 - it s already 0 after reset. No need to enable HSI - it's already enabled.

Do not enable TXE interrupt untli you have something to send. Disable it BEFORE writing the last character to be sent.

If you can do it with HAL in 3 minutes, then without HAL it should take 1 minute, as you need 1/3rd of the code. ;)

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice