UART, minicom y ASCII

5

Estoy intentando enviar mi nombre ( Ziga ) a través de mi microcontrolador UART a mi PC. Las líneas GND, Tx, Rx del microcontrolador están conectadas directamente al convertidor UART-USB CP2102 que se enchufa en mi PC .

Mi PC está ejecutando el sistema operativo Linux y estoy usando la aplicación minicom para verificar la información transferida. Durante la transmisión, mi terminal minicom imprime algunos símbolos extraños (haga clic para ampliar):

ysihabilitolaopción" HEX display " obtengo estos valores (haga clic para ampliar):

Losvaloresson0x5C=92,quees\enASCII,luego0xFC=252,quenotieneningúnsignoenASCIIantiguo,porloqueseconvierteen?,entonceshay0x40=64iguala@enASCIIyfinalmente0x81=129,quedenuevonoestádefinidoenelantiguoASCII,porloqueseconvierteen?.

mientrasobtengolaimagencorrectaenmiosciloscopio(hagaclicparaampliar):

¿PorquénoobtengoZigaZigaZigaZiga...enlaconsolaminicom?Losvaloresparalasletrasindividualessoncorrectosdeacuerdoconlatabla ASCII .

ADD 1 :

Tomé una imagen del osciloscopio de la letra a de Ziga . Espero que esto pueda ayudar a determinar si la velocidad en baudios del microcontrolador es correcta.

ADD2:

Intentéusar2bitsdeparadaenminicomasícomoenmicrocontroladoryobtengounresultadodiferentequeesaúnpeor:solotransfiere3caracteresenlugardecuatro(Zigatienecuatro).Echaunvistazo:

AGREGAR3:

Encontréestainformaciónsobreosciladoresexternos.¿SignificaestoqueelrelojPCLKmencionadoenelmicrocontrolador manual del usuario es 12Mhz ?

ADD4:

Entonces,nosdimoscuentadequedebíaserunproblemadevelocidaddetransmisión,asíqueempecéaleer manual del usuario y descubrí en la página 21 que mi PCLK = 3MHz por defecto. Luego elegí un algoritmo en la página 509 para calcular los valores:

DLL = 0
DLM = 13

DIVADDVAL = 1
MULVAL = 2

Estos valores me deberían dar 9600 baudrate según la ecuación (4) en la página 508. Bueno, da 9615.384615, que debe tener una precisión del 0.16%. Entonces comencé a programar y establecí los valores de arriba de esta manera:

DLL &= ~(0xFF);                //setting first byte to 0  (divisor latch least signifficant byte)
DLL |= 13;                     //setting first byte to 13 (divisor latch least signifficant byte)
DLM &= ~(0xFF);                //setting first byte to 0 (divisor latch most signifficant byte) -- not really needed
DLM |= 0;                      //setting first byte to 0 (divisor latch least signifficant byte) -- not really needed
FDR |= (1<<5); FDR &= ~(1<<4); //setting value MULVAL
FDR |= 0x1;                    //setting value DIVADDVAL

Pero todavía no tengo la velocidad correcta ...

    
pregunta 71GA

4 respuestas

1

Acabo de encontrarme con este mismo problema. La configuración de la velocidad en baudios de 9600 del OP funcionó para mí donde los valores calculados en el manual no lo hicieron.

El problema para mí fue que el código de inicio predeterminado utilizado en mi proyecto (Keil que usa el paquete LPC4000_DFP-1.1.0) llama a una función "SystemInit" que configura los registros de reloj en valores sin restablecimiento.

La función problemática reside en "system_LPC407x_8x_177x_8x.c". La función se llama desde el código de inicio en "startup_LPC407x_8x_177x_8x.s".

Una solución es copiar ambos archivos en su proyecto en lugar de usar los estándar y modificar el archivo C para configurar los relojes de la forma que desee. Alternativamente, puede modificar el archivo de ensamblador para evitar la llamada a "SystemInit" por completo; sin embargo, tenga en cuenta que en este caso necesitará configurar el coprocesador (como en "fpu_init", que se llama desde "SystemInit"), ya que esto parece ser necesario para el funcionamiento normal (todavía no estoy claro por qué).

    
respondido por el Carl
3

Creo que tienes un desajuste en la velocidad de transmisión.

A 9600 baudios, cada bit debe ser ~ 104us ancho . Aquí hay un ASCII 5 real en el alcance con un solo bit cronometrado en 105us ...

(tengaencuentaqueASCII5esunaherramientaútilpararealizarpruebasporquealternaunosycerosenbinario)

A9600baudios,unsolobytedebeser ~ 833us wide (8 bits de datos, sin contar el inicio y el final) ....

Surastreomuestralosmismos8bitsquetoman~300us,porloquesurelojdeserieesaproximadamente 2.7x demasiado rápido.

Intente configurar su velocidad de baudios en Minicom en 26656 baudios y vea lo que obtiene. Si ve Ziga , entonces puede comenzar a buscar por qué el reloj de serie es demasiado rápido.

    
respondido por el bigjosh
2

Lo que se muestra se ve como el típico barfo de baudios.

Uno de sus diagramas muestra que está enviando 8 bits en 300 µs, lo que significa 26.7 kBaud. Ese es un valor extraño. Pruebe una velocidad de transmisión estándar, como 9600, y asegúrese de que su PC esté configurada para eso. 9600 baudios significa 104.2 µs por tiempo de bit, por lo que 8 bits deben tomar 833 µs y un carácter completo de 10 bits (1 bit de inicio, 8 bits de datos, 1 bit de parada) 1,04 ms.

    
respondido por el Olin Lathrop
1

Este hilo aún no está resuelto, pero descubrimos que tenía una discrepancia de velocidad de transmisión de UART y puedo confirmarlo. Pero ¿dónde está el problema? Si leo LPC4088 manual del usuario puedo leer que usa el oscilador interno de 12MHz (p.7). Gracias a ti también encontré el capítulo de generación de reloj (p.21) con este esquema:

Ahora,paracomprenderesto,necesitamosbuscarenladocumentaciónlosvalorespredeterminadosdelosmultiplexoresCLKSRCSEL[0]=0(p.34),CCLKSEL[8]=0(p.33)yeldivisorPCLKSEL[4:0]=0x4(p.34).Porlotanto,deberíaobtenerPCLK=12Mhz/4=3MHz,perocreoqueestonoesciertoodebehaberunerrorconelalgoritmoparacalcularlatasadebaudiosolaecuación(p.508,p.509):

Enmicaso,intentécalcularconPCLK=3MHzyqueríabaudrate9600.AsíqueprimerocalculéDL_EST=PCLK/(16*9600)=19.53(ESTsignificaestimación)yestonoesunnúmeroentero,porloqueFR_EST=1.5yDL_EST=PCLK/(16*9600*1.5)=13.02=13.AcontinuacióncalculamosFR_EST=PCLK/(16*9600*13)=1.5024.Sostienequemi1.5<FR_EST<1.9paraquepuedaleerlosvaloresdeundivisorlatchDLdelatabla(p.510):

Delastablasycálculosanterioressededucequeenmicaso:

DIVADDVAL=1MULVAL=2DL=13

DebidoaqueDL=13=0000000000001101consisteenelcierredeldivisor,elbytemenossignificativoDLLyelcierredeldivisor,elbytemássignificativoDLM,esosdossonigualesa:

DLL=13DLM=0

UtilicéesosvaloresparaprogramarlavelocidadenbaudiosdeUARTdeLPC4088,peronoobtuve9600comodebería.Inclusoverifiquédosveceslaecuaciónsuministradaquedevuelve9615.384615yestoes0.16%precisoquesevebien.

Bueno,mediporvencidoconelalgoritmo/ecuacióndeNXPytratédetrabajarporpruebayerrorydescubríque:

DIVADDVAL=1MULVAL=2DL=255//thismeansDLL=255andDLM=0

Devolví9600baudrateypudecomunicarmeconmiPCmuybien.Perosigosinsabercuáleselerror.¿EstoyhaciendoalgoincorrectoenelcódigooesNXPquienproporcionólosalgoritmosincorrectos?

AquíestámiprogramadeCenplenofuncionamiento.¿Notastealgúnerror?

#include"LPC4088-ioconfig.h"
#include "LPC4088-system.h"
#include "LPC4088-gpio.h"
#include "LPC4088-uart.h"


int main(){

    //PIN settings    
    IOCON_P0_0 &= ~(0x67F);
    IOCON_P0_0 |= (1<<1);
    IOCON_P0_1 &= ~(0x67F);
    IOCON_P0_1 |= (1<<1);

    //turn on UART3
    PCONP |= (1<<25);

    //we set 8-bit characters, no parity, one stop-bit in LCR register
    //LCR.DLAB = 1
    LCR |= (0x3);
    LCR &= ~(0x7C);
    LCR |= (1<<7);

    //set DLL[0-7] = 255, DLM[0-7] = 0, FDR[0-3] = 1, FDR[4-7] = 2
    //values obtained by trial & error - NXP's algorithms don't work
    DLL &= ~(0xFF);
    DLL |= 255;
    DLM &= ~(0xFF);
    DLM |= 0;

    FDR &= ~(0xFF); 
    FDR |= 1;           //DIVADDVAL 
    FDR |= (2<<4);      //MULVAL

    //LCR.DLAB = 0 
    LCR &= ~(1<<7);

    //enable Rx and Tx FIFO
    FCR |= 0x1;

    unsigned char posiljka[] = "Ziga";

    while(1){

        for ( int i = 0 ; i < ( sizeof(posiljka)/sizeof(posiljka[0]) -1 ) ; ++i ){

            //we read LSR and wait for THR to empty
            while ( (LSR & (1<<5)) != (1<<5) );

            //send one character at a time
            THR = posiljka[i];
        }
    }
}
    
respondido por el 71GA

Lea otras preguntas en las etiquetas

Comentarios Recientes

en SNES y JVC (en los discos 101, 105, 111 y 113) juntos; y fue escrito en dos disquetes y medio con pantalla y guión RSPade 104KB / 328K. <| endoftext |> La Bandera Americana Made in America (Maracanã) está hecha por un fabricante, propietario y elevador mexicano de mandolina Proximo que cree que ese estadounidense El símbolo y la cultura son los únicos recursos del mundo, por lo tanto, la fabricación puede pasar al siguiente nivel. Se presenta como un artesano consumado que presenta la moneda estadounidense... Lees verder