Question
Problem with easy UART transmission. I would like some help, Thanks
I am trying to spam the character 'A' over UART.
I've done a lot of digging in the reference manual and online but can't get it to work.
I think there is something wrong with the buad rate but it is just a guess.:grinning_face_with_sweat:
The MCU is a STM32F103C8.
Functions not in main.c explained below.
#include <stdint.h>
#include "setup.h" // Defines things like GREEN_LED pins which are specific to my setup
#include "../gpio.h" // Includes some GPIO functions I wrote to make interfacing it easier
volatile uint32_t *RCC_APB2ENR = (volatile uint32_t*) 0x40021018; // RCC_APB2ENR +0x18 RCC_BASE: 0x40021000
volatile uint32_t *USART1_SR = (volatile uint32_t*) 0x40013800; // ALso SR register
volatile uint32_t *USART1_DR = (volatile uint32_t*) 0x40013804; // Data register
volatile uint32_t *USART1_BRR = (volatile uint32_t*) 0x40013808; // Baud rate register
volatile uint32_t *USART1_CR1 = (volatile uint32_t*) 0x4001380C; // Control register 1
volatile uint32_t *USART1_CR2 = (volatile uint32_t*) 0x40013810; // Control register 2
volatile uint32_t *USART1_CR3 = (volatile uint32_t*) 0x40013814; // Control register 3
void enableIOPortClocks()
{
// GPIO Enable
*RCC_APB2ENR |= (1UL << 0); // Enable alternate funciton clock
*RCC_APB2ENR |= (1UL << 2); // Enable port a
*RCC_APB2ENR |= (1UL << 3); // Enable port b
*RCC_APB2ENR |= (1UL << 4); // Enable port c
}
// Configures LED pins to have to correct output mode.
// simplePinMode( ... ) does the same as pinMode( ... ) here
void setupLEDs()
{
pinMode(PORTB, RED_LED, PIN_MODE.out50MHz, PIN_CNF_OUTPUT.pushPull);
simplePinMode(LED_PORT, GREEN_LED, pinModes.output);
pinMode(PORTB, WHITE1_LED, PIN_MODE.out50MHz, PIN_CNF_OUTPUT.pushPull);
pinMode(PORTB, WHITE2_LED, PIN_MODE.out50MHz, PIN_CNF_OUTPUT.pushPull);
}
void setupUSART1()
{
// Set TX and RX pins
pinMode(PORTA, 9, PIN_MODE.out50MHz, PIN_CNF_OUTPUT.altPushPull);
// PORTA->CRH |= (0b1011 << 4); // Same as line above
pinMode(PORTA, 10, PIN_MODE.in, PIN_CNF_INPUT.floating);
*RCC_APB2ENR |= (1UL << 14); // Enable USART1 clock
*USART1_BRR &= ~(0xFFFF); // Clear buadrate
*USART1_BRR |= 0x1D4C; // Set buadrate
*USART1_CR1 |= (1UL << 3); // Transmitter enable
// *USART1_CR1 |= (1UL << 2); // Reciever enable. Does not matter
*USART1_CR1 |= (1UL << 13); // USART enable
}
int main()
{
enableIOPortClocks();
setupLEDs();
setupUSART1();
if (*USART1_CR1 & (1UL << 13)) // Simple and unnecessary check if usart enable bit is set
{
digitalWrite(LED_PORT, GREEN_LED, HIGH);
}
while (1)
{
// wait till transmit data register is empty
while (!(*USART1_SR & (1UL << 7)))
{
digitalWrite(LED_PORT, WHITE2_LED, HIGH); // Turns on LED on breadboard
}
digitalWrite(LED_PORT, WHITE2_LED, LOW); // Turns off LED on breadboard
for (int i = 0; i < 500000; i++) // So the LED off tine is long enough to be visible.
{
// Wait
}
// Send character
*USART1_DR = ('A' & 0xFF);
}
}(simple)pinMode(); Sets pin MODE and CNF bits.
digitalWrite(); Sets pin high or low;
I am using STM32CubeIDE and used a empty STM32 project.
Thank you for reading this! It would be amazing if you could spot the mistake!=)
