USART receiving nonsense (STM32F0)

Kater Source

I have an implementation for USART communication from a GPS module to a STM32F091 microcontroller. For some reason I only receive nonsense. I have already tried setting different Baud Rates, but none gave me a proper result.

Now I am unsure if maybe there is something funky with prescaler settings or something else I forgot.

The relevant code looks as follows:

peripherals.c

/* Clock settings */
void clock_init(void)
{
    /* Enable HSI clock */
    RCC->CR |= RCC_CR_HSION;

    /* Enable clocks on Port A, B, F */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE);

    /* Enable USART clocks */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
}

/* Select Alternate Port Functions */
void alt_init(void)
{
    /* Port A: USART1 */
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);

    /* Port B: USART3 */
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_4);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_4);
}

usart.c

USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

/* Baud rate */
uint32_t bd = 9600;

void usart_init(void)
{

    /* ##################### USART 1 ##################### */
    /* USART GPIO Settings */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* USART Settings */
    USART_InitStructure.USART_BaudRate = bd;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl =
    USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);

    /* Enable USART because it's disabled in USART_Init */
    USART_Cmd(USART1, ENABLE);

    /* ##################### USART 2 ##################### */

    /* ##################### USART 3 ##################### */
    /* Disable USART3 in order to use SWAP */
    USART_Cmd(USART3, DISABLE);

    /* Swap TX and RX pins */
    USART3->CR2 |= USART_CR2_SWAP;

    /* Enable USART3 */
    USART_Cmd(USART3, ENABLE);

    /* USART GPIO Settings */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /* USART Settings */
    USART_InitStructure.USART_BaudRate = bd;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl =
    USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART3, &USART_InitStructure);

    /* Enable USART because it's disabled in USART_Init */
    USART_Cmd(USART3, ENABLE);

    /* Enable USART Interrupts */
    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
    USART_ITConfig(USART3, USART_IT_TXE, ENABLE);

    /* Enable external interrupts */
    NVIC_InitStructure.NVIC_IRQChannel = USART3_8_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* ##################### USART 4 ##################### */

}

stm32f0xx_it.c

#include <main.h>

void USART3_8_IRQHandler(void)
{
    char t[] = "U";
    uint16_t byte = 0;
    if (USART_GetFlagStatus(USART3, USART_FLAG_RXNE) != RESET) // Data reception
    {
        byte = USART_ReceiveData(USART3);
        (*pRXD3).Buffer[(*pRXD3).wr] = byte;
        (*pRXD3).wr = ((*pRXD3).wr + 1);

        USART_SendData(USART1, t[0]);

        USART_GetFlagStatus(USART3, USART_IT_ORE);
        USART_ClearITPendingBit(USART3, USART_IT_RXNE);
    }
    return;
}

The USART_SendData bit is for communication with my PC, so I can see if I receive the letter U or more nonesense.

I have also checked the content of the DR register (by way of checking the Buffer I write its content to) of USART3 directly so I know the STM32F091 receives (or rather interperts) my GPS output wrong.

The GPS module uses a default baudrate of 9600 which I do not change.

Let me know if there's any additional info

cinterruptstm32baud-rateusart

Answers

answered 6 months ago Kater #1

After a lot of searching and the suggestions of everyone in the comments, I figured out that the System Clock was not set up properly. The following pieces of code were necessary in addition to what was already in the 'clock_init'.

peripherals.c

/* Clock settings */
void clock_init(void)
{
    ....

    /* Select System Clock to be HSI */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);

    /* Select USART clock source to be System Clock */
    RCC_USARTCLKConfig(RCC_USART1CLK_SYSCLK);
    RCC_USARTCLKConfig(RCC_USART3CLK_SYSCLK);

    ....

}

Thanks to everyone for the help.

comments powered by Disqus