0
\$\begingroup\$

I am learning bare metal embedded development using CMSIS Core framework. The problem I am facing is with UART communication. I am getting additional garbage value along with the character I am sending from a STM32F103C8T6 MCU. The garbage value comes only with few characters. e.g. a --> a, c --> c?

Detailed logs are mentioned below.

Couple of questions:

  • why is there an additional garbage value
  • why is this with some characters only
  • even if I leave out the GPIOA AF configuration, the UART works

Here is the code I have written so far:

#include "usart1.h"
#include "stm32f103xb.h"


void initUsart(void){
    /**
     * enable alternate funtion
     * enable clock for USART1
     * enable clock for PORTA
     */
    RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
    RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;

    /**
     * configure PORTA pins
     * PA9 (TX) -> AF output push-pull
     * PA10 (RX) -> input floating
     */
    GPIOA->CRH &= ~(GPIO_CRH_CNF9  | GPIO_CRH_MODE9);   // reset PA9
    GPIOA->CRH &= ~(GPIO_CRH_CNF10 | GPIO_CRH_MODE10);  // reset PA10
    GPIOA->CRH |= GPIO_CRH_MODE9_1;
    GPIOA->CRH |= GPIO_CRH_MODE9_0;
    GPIOA->CRH |= GPIO_CRH_CNF9_1;
    GPIOA->CRH |= GPIO_CRH_CNF10_0;

    /**
     * set baud rate to 9600
     * 8MHz/(16*9600) = 52.08
     * DIV_Fraction = 16*0.08 = 1.28 -> 1 = 0x1
     * DIC_Mantissa = mantissa(52.08) = 52 = 0x34
     * BRR = 0x341
     */
    USART1->BRR = 0x341;

    /**
     * enable USART
     * word length 8 bits
     * no parity
     * enable Tx and Rx
     * one stop bit
     */
    USART1->CR1 |= USART_CR1_UE;
    USART1->CR1 |= USART_CR1_TE;
    USART1->CR1 |= USART_CR1_RE;
}

void send(char data){
    /* wait till TDR gets empty */
    while(!(USART1->SR & USART_SR_TXE));

    /* wite data to data register */
    USART1->DR = (data & 0xFF);
}

char read(){
    /* wait till data is loaded into RDR */
    while(!(USART1->SR & USART_SR_RXNE));

    /* read data from data register */
    return (uint8_t) (USART1->DR & 0xFF);
}

#include "usart1.h"    

int main(void){
    initUsart();
    
    while(1){
        send(read());
    }
}

// echoed ASCII characters
abc�de�f�ghi�j�kl�mno�pq�r�st�uvw�x�yzA�B�CD�EFG�H�IJK�LM�N�OP�QRS�TU�V�WXY�Z

// hex dump
0000000 61 62 63 ef bf bd 64 65 ef bf bd 66 ef bf bd 67 | abc...de...f...g
0000010 68 69 ef bf bd 6a ef bf bd 6b 6c ef bf bd 6d 6e | hi...j...kl...mn
0000020 6f ef bf bd 70 71 ef bf bd 72 ef bf bd 73 74 ef | o...pq...r...st.
0000030 bf bd 75 76 77 ef bf bd 78 ef bf bd 79 7a 41 ef | ..uvw...x...yzA.
0000040 bf bd 42 ef bf bd 43 44 ef bf bd 45 46 47 ef bf | ..B...CD...EFG..
0000050 bd 48 ef bf bd 49 4a 4b ef bf bd 4c 4d ef bf bd | .H...IJK...LM...
0000060 4e ef bf bd 4f 50 ef bf bd 51 52 53 ef bf bd 54 | N...OP...QRS...T
0000070 55 ef bf bd 56 ef bf bd 57 58 59 ef bf bd 5a 0d | U...V...WXY...Z.
0000080 0a                                              | .
0000081 

I am using an ESP-Prog as serial-usb adapter.

ESP-Prog    STM32
VDD ---- 3V3
GND ---- GND
TXD ---- A9
RXD ---- A10

Thanks in advance for putting any effort into this.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ This could be many things, what type of system clock are you using? if its an internal non PLL you will get inaccuracies/jitter. Are you sure about the speed of your APB2? I fell into that one :) \$\endgroup\$
    – Sorenp
    Commented Jan 5, 2021 at 10:13
  • \$\begingroup\$ Honestly, not sure about that. Figured the frequency should be 8MHz, got to know while playing with TIM1. \$\endgroup\$ Commented Jan 5, 2021 at 10:40
  • \$\begingroup\$ You need to describe precisely the electrical connection of the two devices. What voltages are the using for communication? \$\endgroup\$ Commented Jan 5, 2021 at 13:33
  • \$\begingroup\$ Crossposting is prohibited \$\endgroup\$ Commented Jan 5, 2021 at 14:29
  • \$\begingroup\$ @ElliotAlderson, I have updated the wiring details. \$\endgroup\$ Commented Jan 5, 2021 at 15:48

2 Answers 2

1
\$\begingroup\$

I suspect you're using the default internal HSI RC oscillator rather than a crystal and the HSE oscillator as the timing source, which is making the serial communications unreliable. If the temperature changes greatly (you can try gently heating the MCU chip as a test) it will likely fail with any adapter. The CH340 may be more tolerant to badly mistimed serial signals, depending on how they do the sampling.

So, I think the issue is not with the serial<-> TTL chip and associated crystal but with the setup of your chip (and the hardware).

Here (screen cap from the configuration utility) is the block diagram of the relevant part of the STM32F103C8T6 clock configuration showing it properly set up to use the 8MHz crystal.

enter image description here

\$\endgroup\$
1
  • \$\begingroup\$ Setting clock source to HSE didn't solve the issue. RCC->CR |= RCC_CR_HSEON; RCC->CFGR |= RCC_CFGR_SW_HSE; \$\endgroup\$ Commented Feb 10, 2021 at 14:10
0
\$\begingroup\$

It's the ESP Programmer that I am using as a USB-TTL adapter which is adding additional garbage data. I tried with regular USB-TTL adapter which works fine.

Edit : This issue is with the FTDI chip in particular (present in both ESP Prog and FTDI232RL Serial to USB converter). However I used an Arduino Nano as USB-TTL adapter which had CH340 chip and is not adding the garbage data.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I have a hard time believing this. The FTDI chips are widely used and you seem the first person to encounter this problem. \$\endgroup\$
    – Codo
    Commented Feb 9, 2021 at 15:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.