Electronic – Trouble getting USART working on STM32 (stm32f103c8t6)

microcontrollerserialstm32stm32f10xuart

I started working with with stm32f103c8t6 recently and I was able to set GPIO to input and output, however when I try to set USART it just does not work. I'm trying to write directly to registers, because I would like to understand how things work on the lower level, but I do realise that there are some helper libraries for working with USART.

Anyway I follow instructions from: Official reference manual on how to get USART Transmission working, but the code does not work, there is nothing in USART terminal on my PC. I do realise there is a lot of room for error. Here is my code for initializing and sending USART Transmission on stm32f103c8t6:

void initUartTransmission(){
    //1. Enable the USART by writing the UE bit in USART_CR1 register to 1.
    USART1 -> CR1 |= (0x1 << 13);
    //2. Program the M bit in USART_CR1 to define the word length.
    USART1 -> CR1 &= ~(0x1 << 12);
    //3. Program the number of stop bits in USART_CR2.
    USART1 -> CR2 &= ~(0x1 << 12);
    USART1 -> CR2 &= ~(0x1 << 13);
    // 4. Select DMA enable (DMAT) in USART_CR3 if Multi buffer Communication is to take
    // place.
    // I'm skipping this, because I'm not interested in DMA at this time
    // 5. Select the desired baud rate using the USART_BRR register.
    // I'm not certain of the clock speed I have. The board has 8 MH cristal,
    // but I'm not sure if it's enabled
    float f = ((float)(8000000/16)/9600);
    int q = (((int)f)&0x0FFF);
    int k = (float)(f - (float)q);
    k = (float)(k * 16);
    USART1 -> BRR = ((q<<0)|(((int)k&0x0F)<<8));
    //6. Set the TE bit in USART_CR1 to send an idle frame as first transmission.
    USART1 -> CR1 |= (0x1 << 3);
    //Enable clock for USART1
    RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
}

void void writeUart(){
    while(!(USART1 -> SR & (1<<7))){
        USART1->DR = 'c';
    }
}

I've been trying different configurations, but I just couldn't get it to work. I am confident in connections between the board and my USB USART adapter, because I have experience with Atmega328p.

I would appreciate any help.

Best Answer

Enable the peripherals in RCC first, both the UART and the I/O port. (Port A if using the default pin mapping.) Until that point the peripherals are completely disabled, including their register interface, writes to USART1->CR1 etc have no effect. This line should go to the top:

RCC->APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN;

Configure GPIO alternate output

All pins are in input mode at reset. To enable the output signal on the TX pin, you should set PA9 to

  • Output mode, (max speed 2 MHz)
  • Alternate function output push-pull

See the description of GPIOA->CRL/GPIOA->CRH in the reference manual for the bit settings.