2023-05-08 11:21 PM
Hey folks, I did try the bare metal programming videos on Udemy, and got so facinated, that decided to try on other board. As expected the code from the tutorial is not working on the other board. However I have checked, and re cheked the registry values that I provide, with the documentation of the correct board, and all seems to be OK, In addition to that I added 120 MHz for APB1 bus frequency, but I am still not getting anything on RealTerm.
In Udemy they do not respond to my questions, regarding other boards, so I really hope to get some help here. Thank you!
The device is Nucleo L4R5ZI, here is the code:
#include <stdint.h>
#include <stdio.h>
#include "stm32l4xx.h"
#define GPIOAEN (1U<<0)
#define UART2EN (1U<<17)
#define SYS_FREQ 120000000
#define APB1_CLK SYS_FREQ
#define CR1_TE (1U<<3)
#define CR1_UE (1U<<0)
#define ISR_TXE (1U<<7)
static uint16_t compute_uart_div(uint32_t PeriphClk, uint32_t Baudrate);
static void uart_set_baudrate (USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t Baudrate);
static void uart2_write(uint8_t ch);
void uart2_tx_init (USART_TypeDef *USARTx);
int __io_putchar (int ch)
{
uart2_write(ch);
return ch;
}
int main(){
uart2_tx_init (USART2);
while (1)
{
printf ("Hello from STM32L4....\n\r");
}
}
void uart2_tx_init (USART_TypeDef *USARTx)
{
//*******************Configure the UART pin*******************
//Enable clock access to GPIOA for PA2 as TX line
RCC->AHB2ENR |= GPIOAEN;
//Set PA2 mode as alternate function mode
GPIOA->MODER &=~(1U<<4);
GPIOA->MODER |=(1U<<5);
//Set the alternate function type to UART
GPIOA->AFR[0] |=(1U<<8);
GPIOA->AFR[0] |=(1U<<9);
GPIOA->AFR[0] |=(1U<<10);
GPIOA->AFR[0] &=~(1U<<11);
//*******************Configure the UART module*******************
//Enable clock access to UART2
RCC->APB1ENR1 |=UART2EN;
//Configure baudrate
uart_set_baudrate (USARTx, APB1_CLK, 115200);
//Configure transfer direction
USARTx->CR1 = CR1_TE;
// Enable UART module
USARTx->CR1 |= CR1_UE;
}
static void uart2_write(uint8_t ch)
{
//Wait for transmit data register to be empty
while (!(USART2->ISR & ISR_TXE)) {}
//Transmit value
USART2->TDR = (ch & 0xFF);
}
static void uart_set_baudrate (USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t Baudrate)
{
USARTx->BRR = compute_uart_div( PeriphClk, Baudrate);
}
static uint16_t compute_uart_div(uint32_t PeriphClk, uint32_t Baudrate)
{
return ((PeriphClk + (Baudrate/2))/Baudrate);
}
Solved! Go to Solution.
2023-05-09 01:13 AM
Welcome, @Valkan Pavlov, to the community!
The reason is probably that you have not adjusted the UART used for printf over the virtual COM port. The NUCLEO-L4R5ZI does not use UART2, but LPUART1.
Does it answer your question?
Regards
/Peter
2023-05-09 12:54 AM
Do you compile it as C or C++?
2023-05-09 01:13 AM
Welcome, @Valkan Pavlov, to the community!
The reason is probably that you have not adjusted the UART used for printf over the virtual COM port. The NUCLEO-L4R5ZI does not use UART2, but LPUART1.
Does it answer your question?
Regards
/Peter
2023-05-09 01:31 AM
C
2023-05-09 01:34 AM
If the code that you paste is coplete, You use wrong sysclk value. After reset the board have used MSI oscilator and have set value around 4 MHz but you set 120 MHz without PLL configuration. Try set
#define SYS_FREQ 4000000
Your code works for me on this SYS_FREQ
2023-05-09 01:50 AM
Tx, yes it is complete. I did try with 120 MHz, 80MHz, 16MHz, and 4MHz. But I will try again with 4.
It id not work. Did you use it with the same board?
2023-05-09 01:53 AM
I checked it on TeraTerm. Make sure for your COM settings, number of zeros in "clock define " etc :) Perhaps try reset board using button at the end
2023-05-09 01:55 AM
And look at @Peter BENSCH answer. You use UART through USB (ST-LINK) or from gold pins?
2023-05-09 02:00 AM
Yes, it requires some "dig" into documentation, so it was faster to check again with 4 I plan to do this now. I use the USB.
2023-05-09 02:03 AM
LPUART1 is good choice :)