smt32 f10x caracteres no válidos sobre uart

4

Actualmente estoy trabajando en un quadcopter usando STM32F103 . En lugar de usar el Std Periph Driver proporcionado, que es grande, estoy creando mi propio Periph Driver que está orientado a objetos, lo que también me ayuda a entender mejor el procesador.

He llegado a la etapa en la que tengo el núcleo funcionando y pasé al USART. He recreado la unidad estándar USART siguiendo los procedimientos de espacio establecidos en el código y en el manual de referencia.

SALIDA:

Comopuedever,algunoscaracteresnosemuestrancorrectamente.Hecomprobadocadafunciónllamadaycadavariablesehautilizadomuchasvecesytodashanfinalizadoelprocesodepago.Mehequedadosinideas.¿Hayalgoqueestoyhaciendomal,oelprogramadeprogramaciónOOno,no,noestáincrustadoporqueesaeslaúnicaotracosaenlaquepuedopensar?

Lasalidadeloanterioreslasiguiente.

AquíestáelcódigoparaUSART-:

USART.h AQUÍ

USART.cpp AQUÍ

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 y GPIOConfig funcionan bien, e incluso si no lo fueran, no los necesito, ya que no se usan cuando se usa USART.

    
pregunta kelvinmac

3 respuestas

0

Los caracteres que se están corrompiendo son los que tienen carreras largas del mismo bit en su representación binaria. Parece que cuatro bits idénticos consecutivos es aproximadamente el número que se necesita para confundir su línea serie.

Esto suele ser un problema con los flujos de datos seriales no sincronizados, donde las transiciones (0- > 1 o 1- > 0) son necesarias para volver a sincronizar el reloj del receptor con el del remitente antes de que se desvíe demasiado. Sin embargo, normalmente se necesitan más de cuatro bits seguidos para perder la sincronización, lo que sugiere que los dos extremos de la línea serie tienen relojes que no están sincronizados entre sí.

También deberías leer la respuesta de duskwuff, que propone una razón por la que podrías estar viendo que los dos extremos pierden la sincronización del reloj tan rápido, y qué podrías hacer al respecto.

    
respondido por el Glenn Willen
0
  

Como puede ver, algunos caracteres no se muestran correctamente.

En lugar de que otras personas intenten ver qué está mal, tal vez debería simplemente indicar qué está mal.

  

He comprobado todas las funciones llamadas y cada variable se ha utilizado muchas veces y todas se han verificado. Me he quedado sin ideas.

Intentaría asegurarme de que obtuviste la velocidad de transmisión en ambos extremos; por ejemplo, ¿su oscilador interno, si se usa aquí, es lo suficientemente preciso? ¿O si su cristal externo está en una frecuencia que produce una tasa de error demasiado alta para la velocidad de transmisión deseada? ...

Una cosa menor para su código es que puede acelerar la transmisión si comprueba si hay un búfer lleno al comienzo de sendchar () en lugar de esperar a que se complete la transmisión al final.

  

¿Hay algo que estoy haciendo mal, o el programa de OO no, no, no está incrustado porque esa es la única otra cosa en la que puedo pensar?

no hay ningún error inherente con OO, especialmente para un chip tan rico en recursos.

    
respondido por el dannyf
0

Has mencionado en un comentario que:

  

No me he metido con el oscilador interno o el cristal externo, por lo que todo está funcionando correctamente.

Esta es probablemente la fuente de tu problema. El oscilador interno HSI no es especialmente preciso; con la calibración de fábrica, tiene una tolerancia de aproximadamente ± 2%, que es demasiado amplia para un UART.

Si abre el cristal HSE y lo activa como la fuente del reloj, el UART debería comenzar a comportarse.

    
respondido por el duskwuff

Lea otras preguntas en las etiquetas