Electronic – smt32 f10x invalid characters over uart

ckeilmicrocontrollerstm32stm32f10x

I'm currently working on a quadcopter using the STM32F103. Instead of using the provided Std Periph Driver which is big I'm creating my own Periph Driver which is object oriented which also helps me understand the processor better.

I've gotten to stage where I have the core working and moved on to the USART. I've recreated the USART standard drive following the space procedures stated both in the code and the reference manual.

OUTPUT:

enter image description here

As you can see some characters aren't displayed right. I've checked every function called and every variable used a lot of times and they all checkout. I'm out of ideas. Is there anything I'm doing wrong, or OO porgramming a no no in embedded because that's the only other thing i can think of.

The output for the above is as follows.

Here is the code for USART-:

USART.h HERE

USART.cpp HERE

MAIN.cpp

#include "SysCore.h"
#include "USART.h"
/**
* @brief  Public/global hall instance, use extern to use in another 
                    file (can't be used in C). By having it this as a reference, 
                    it removes the worry or having to check it for a null reference
*/
System::Hal *globalHal;

//usart config
System::USARTConfig *usartConfig;


extern "C" void SysTick_Handler (void)
{
   /*Call HAL tick to increment its tocks*/
   globalHal->Tick();
}

void SendChar(uint8_t character, System::USART *usart)
{
   //send the character
   usart->SendData(usartConfig, (uint8_t)character);        
   while(usart->GetFlagStatus(usartConfig, USART_FLAG_TC) == RESET)
   {}
}

void SendMessage(char MESSAGE[], uint8_t length, System::USART *usart )
{
   for(uint8_t i = 0; i < length; i++)
   {
        SendChar((uint8_t)MESSAGE[i], usart);
   }
}

int main(void)
{
//Creates the instance of HAl (singleton please)
System::Hal *hal = new System::Hal();
//Set global extern Hal pointer
globalHal = hal;

//Init the Hal 
hal->Hal_init();
//Init the system tick
hal->InitTick();


//enable rcc for ports
hal->Rcc->APB2PeriphClock(System::APB2Peripheral::Gpioc | 
System::APB2Peripheral::Gpioa  | 
System::APB2Peripheral::Usart1 |
System::APB2Peripheral::Afio, HAL_Enable);


/*----------------USART----------------*/
//TX pin 9
System::GPIOConfig *usartTxPort = new System::GPIOConfig(GPIO_Pin_9, GPIOA, GPIO_Mode_AF_PP, GPIO_Speed_50MHz);
//RX pin 10
System::GPIOConfig *usartRxPort = new System::GPIOConfig(GPIO_Pin_10, GPIOA, GPIO_Mode_IN_FLOATING, GPIO_Speed_50MHz);

//initalize the gpio
hal->Gpio->Init_GPIO(usartTxPort);
hal->Gpio->Init_GPIO(usartRxPort);


usartConfig = new System::USARTConfig();

//configure usartConfig     
usartConfig->USARTx = USART1;
usartConfig->BuadRate = 9600;
usartConfig->Mode = USART_Mode_Rx |USART_Mode_Tx ;
usartConfig->StopBits = USART_StopBits_1;
usartConfig->Parity = USART_Parity_No;
usartConfig->HardwareFlowControl = USART_HardwareFlowControl_None;
usartConfig->WordLength = USART_WordLength_8b;

//passing usartConfig will initalize the usart
System::USART *usart = new System::USART(usartConfig);

usart->UsartCmd(usartConfig, HAL_Enable);

SendChar('\r', usart);
SendChar('\n', usart);
SendChar('a', usart);
SendChar('b', usart);
SendChar('c', usart);
SendChar('d', usart);
SendChar('e', usart);
SendChar('f', usart);
SendChar('g', usart);
SendChar('h', usart);
SendChar('i', usart);
SendChar('j', usart);
SendChar('k', usart);
SendChar('l', usart);
SendChar('m', usart);
SendChar('n', usart);
SendChar('o', usart);
SendChar('p', usart);
SendChar('q', usart);
SendChar('r', usart);
SendChar('s', usart);
SendChar('t', usart);
SendChar('u', usart);
SendChar('v', usart);
SendChar('w', usart);
SendChar('x', usart);
SendChar('y', usart);
SendChar('z', usart);

SendChar('A', usart);
SendChar('B', usart);
SendChar('C', usart);
SendChar('D', usart);
SendChar('E', usart);
SendChar('F', usart);
SendChar('G', usart);
SendChar('H', usart);
SendChar('I', usart);
SendChar('J', usart);
SendChar('K', usart);
SendChar('L', usart);
SendChar('M', usart);
SendChar('N', usart);
SendChar('O', usart);
SendChar('P', usart);
SendChar('Q', usart);
SendChar('R', usart);
SendChar('S', usart);
SendChar('T', usart);
SendChar('U', usart);
SendChar('V', usart);
SendChar('W', usart);
SendChar('X', usart);
SendChar('Y', usart);
SendChar('Z', usart);

while(true);
}

HalModule, HAL and GPIOConfig are working fine, and even if they weren't I don't need them since there's no use of them when using USART.

Best Answer

The characters that are being corrupted are the ones that have long runs of the same bit in their binary representation. It seems like four consecutive identical bits is roughly the number it takes to confuse your serial line.

This is often a problem with non-clocked serial data streams, where transitions (0->1 or 1->0) are required to re-synchronize the receiver's clock with the sender's before it drifts too far. However, normally it takes a lot more than four bits in a row to lose sync, which suggests that the two ends of your serial line have clocks that are way out of sync with each other.

You should also read duskwuff's answer, which proposes a reason you might be seeing the two ends lose clock synchronization so quickly, and what you could do about it.