cancel
Showing results for 
Search instead for 
Did you mean: 

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?

Singh12
Associate

#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--;

 }

}

3 REPLIES 3

Read out and check the GPIO and UART registers content.

I don't see GPIO clock being enabled.

JW

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

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. 😉