HiGuys, I have been trying for days trying to get the UART on the STM32F030R8 to work, I have following the datasheet and the reference manual step by step but it just doesn't work. Using the STM32 CubeMX I got it to work but I dont see where I am wrong. Could anyone point out my mistake. I am pasting the functions I am using to step the MCU below.
Thanks for the help.
#include <__cross_studio_io.h> #include <stm32f30x.h>
#ifndef _HW_Init_H #define _HW_Init_H #endif
void Port_Init(void) { RCC->AHBENR |= (RCC_AHBENR_GPIOAEN ); RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN | RCC_APB2ENR_SPI1EN ; RCC->APB1ENR |= RCC_APB1ENR_USART2EN ; GPIOA -> MODER |= GPIO_MODER_MODER7_1 | GPIO_MODER_MODER5_1 | GPIO_MODER_MODER2_1 | GPIO_MODER_MODER6_1 | GPIO_MODER_MODER3_1; /* | GPIO_MODER_MODER13_1 | GPIO_MODER_MODER14_1;*/ GPIOA -> OSPEEDR |= GPIO_OSPEEDER_OSPEEDR9 | GPIO_OSPEEDER_OSPEEDR10 | GPIO_OSPEEDER_OSPEEDR7 | GPIO_OSPEEDER_OSPEEDR3 ; GPIOA -> PUPDR |= GPIO_PUPDR_PUPDR9_0 | GPIO_PUPDR_PUPDR7_0 | GPIO_PUPDR_PUPDR10_0 ;
/*GPIOA -> MODER = GPIO_MODER_MODER7_0 ; /* so far this statement causes the CPU to freeze */
return; }
void UART_Init(void) { USART2 -> BRR = 0x341; USART2 -> CR1 |= USART_CR1_UE ; USART2 -> CR1 |= USART_CR1_TE ; return; }
void UART_SendChar(char a) { int TC ;
while ((USART2-> ISR & USART_ISR_TXE) == 0); USART2-> TDR = a ; return ; }
void UART_SendString( char* data, int length ) { int send=0 ; if ((USART2->ISR & USART_ISR_TC) == USART_ISR_TC) { USART2->TDR = data[send++]; } }
void SPI_Init(void) { SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_BR_2; /* (1) */ SPI1->CR2 = SPI_CR2_SSOE | SPI_CR2_RXNEIE | SPI_CR2_FRXTH| SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0; /* (2) */ SPI1->CR1 |= SPI_CR1_SPE; /* (3) */ GPIOA -> MODER |= GPIO_MODER_MODER10_0 ; }
void SPI_Send_Byte(char data) { if ((SPI1->SR & SPI_SR_TXE) == SPI_SR_TXE) /* Test Tx empty */ { /* Will inititiate 8-bit transmission if TXE */ *(uint8_t *)&(SPI1->DR) = data; while ((SPI1->SR & SPI_SR_BSY) == SPI_SR_BSY) {
} return ; } }
char SPI_send_Stream(char stream[] , int length) { int stream_index = 0 ; char byte;
CLEAR_BIT(GPIOA->ODR , GPIO_ODR_10) ; while (stream_index < length ) { byte = stream[stream_index]; SPI_Send_Byte(byte); stream_index ++ ; } SET_BIT(GPIOA->ODR , GPIO_ODR_10) ; }
void Clock_setup(void) { /*int check= 0 ; RCC -> CFGR |= RCC_CFGR_PLLMULL6 | RCC_CFGR_SWS_1 ;*/ }
Explaining why "this statement causes the CPU to freeze" when uncommented.
Perhaps you can review the posting instructions for source code so what you provided is more readable. And provide comments about what the desired pins/effect should be if coded correctly.
GPIOA initialization seems to be doing a lot of unnecessary work, not at all clear what UART pins are being used, or if the right AF selection is being made. Assume you can't OR everything into the state you want from the state its in.
Should check TXE, not TC
Hi, I really appreciate you taking your time out to answer. Here is the code once again in better formatting. I have removed the irrelevant code and I am showing you only the initiliazing routines.
First routine is called to setup the PORTS:
void Port_Init(void) { RCC->AHBENR |= (RCC_AHBENR_GPIOAEN ); RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN | RCC_APB2ENR_SPI1EN ; RCC->APB1ENR |= RCC_APB1ENR_USART2EN ; GPIOA -> MODER |= GPIO_MODER_MODER7_1 | GPIO_MODER_MODER5_1 | GPIO_MODER_MODER2_1 | GPIO_MODER_MODER6_1 | GPIO_MODER_MODER3_1; GPIOA -> OSPEEDR |= GPIO_OSPEEDER_OSPEEDR9 | GPIO_OSPEEDER_OSPEEDR10 | GPIO_OSPEEDER_OSPEEDR7 | GPIO_OSPEEDER_OSPEEDR3 ; GPIOA -> PUPDR |= GPIO_PUPDR_PUPDR9_0 | GPIO_PUPDR_PUPDR7_0 | GPIO_PUPDR_PUPDR10_0 ; return; }
After this the UART is initialized:
And then to send the data I am using this code :
while ((USART2-> ISR & USART_ISR_TXE) == 0); USART2-> TDR = a ; return ;
You mention an F0 part but use an F3 series include file. Which pins is the USART using? Would need to make sure the GPIOA->AFR are programmed correctly. The USART would need to be enabled
Why having "return;" in the end if your functions? They will automatically end when reaching the last "}" without any need for an extra "return;" statement. The existence of the "return;" statement is to allow conditional return earlier in a function.