problema PIC18 USART

4

Ok, mi próximo problema con PIC18 ...

USART - No puedo hacer que transmita nada sensible. Todo lo que obtengo son xs al azar y signos de interrogación invertidos.

Estoy usando la misma configuración de BAUD que he usado muchas veces en los PIC16 bastante a gusto. He intentado volver a calcular la configuración de baudios a partir de la fórmula, he intentado diferentes velocidades de baudios y diferentes frecuencias de cristal para dar diferentes precisiones de baudios, pero todo lo que obtengo son los mismos dos caracteres incorrectos.

Si cambio el valor de baudios a algo completamente incorrecto, se pone más alboroto al azar que solo estos dos caracteres.

He intentado esto en 2 PIC18 diferentes, tanto mi '4455 como mi' 14K50 - ambos hacen exactamente lo mismo.

Aquí está mi programa:

void main()
{
    OpenUSART ( USART_TX_INT_OFF &
                USART_RX_INT_OFF &
                USART_ASYNCH_MODE &
                USART_EIGHT_BIT &
                USART_BRGH_HIGH &
                USART_CONT_RX, 103);
    baudUSART(  BAUD_IDLE_CLK_HIGH &
                BAUD_8_BIT_RATE &
                BAUD_WAKEUP_OFF &
                BAUD_AUTO_OFF);
    while(1)
    {

        WriteUSART('F');
        WriteUSART('o');
        WriteUSART('o');
        WriteUSART(13);
        WriteUSART(10);
    }
}

El 103 I se calculó a partir de un cristal de 16MHz a 9600 baudios según la fórmula en la hoja de datos para el PIC.

Entonces, ¿qué me estoy perdiendo?

UPDATE

Sincronizando el flujo de datos con un 'alcance, he determinado que se ejecuta en realidad a 2400 baudios (la configuración de la computadora a 2400 baudios lo confirma).

Lo he comprobado y el cristal está oscilando a 16 MHz.

La fórmula para calcular el BAUD es:

\ $ \ frac {F_ {osc}} {(16 * (n + 1))} \ $

donde Fosc es la frecuencia del oscilador, y n es el número que se pasa al generador de velocidad en baudios.

\ $ \ frac {16,000,000} {(16 * (103 + 1))} = \ frac {16,000,000} {(16 * 104)} = \ frac {16,000,000} {1664} = 9615.384615385 \ $

Entonces, ¿por qué se está ejecutando a 2400 baudios?

Sé que no son mis cálculos: la tabla de baudios en la hoja de datos cita 119 para 9600 baudios en un cristal de 18.432 MHz, por lo que 103 para un 16 MHz es perfectamente razonable.

Cosas que he probado:

  • Cambie a BRGH = 0 - ralentiza aún más la velocidad de transmisión
  • Cambie a un temporizador de 16 bits no a 8 bits: reduce la velocidad de transmisión hasta un rastreo.

Entonces, ¿qué tiene de extraño este UART?

    
pregunta Majenko

2 respuestas

6

El problema aquí es que Microchip omitió por defecto el CPUDIV a / 4, lo que significa que el reloj interno del PIC se estaba ejecutando a un cuarto de la frecuencia esperada, por lo que los cálculos fueron todos incorrectos.

Tomó algo de tiempo resolver esto, pero configurando

#pragma config CPUDIV = NOCLKDIV

parece solucionar el problema. Además, debido a que estoy usando un MAX232 vinculado a la salida, tengo que invertir las señales:

baudUSART(BAUD_IDLE_CLK_LOW & 
          BAUD_AUTO_OFF & 
          BAUD_8_BIT_RATE & 
          BAUD_IDLE_RX_PIN_STATE_HIGH);

OpenUSART (USART_TX_INT_OFF &
           USART_RX_INT_OFF &
           USART_ASYNCH_MODE &
           USART_EIGHT_BIT &
           USART_CONT_RX &
           USART_ADDEN_OFF &
           USART_BRGH_HIGH, 103);
    
respondido por el Majenko
2

Este programa de prueba funcionó bien con un 18F4520:

/Test.c
//Tx RC6 (pin 44)
//Rx RC7 (pin 1)

#include <p18cxxx.h>
#include <usart.h>

#pragma config OSC = INTIO67, MCLRE = ON

void main (void)
{
    char c;

    TRISC = 0x80;       // RC6 output, RC7 input

    // Internal osc. 8 MHz, PLL 4x
    OSCCON |= 0x72;
    OSCTUNEbits.PLLEN = 1;

    // wait until IOFS = 1 (osc. stable)
    while (!OSCCONbits.IOFS)
        ;


/*
* Open the USART configured as
* 8N1, 2400 baud, in polled mode
*/
  OpenUSART (USART_TX_INT_OFF &
             USART_RX_INT_OFF &
             USART_ASYNCH_MODE &
             USART_EIGHT_BIT &
             USART_CONT_RX &
             USART_BRGH_HIGH, 103);

    while (1)
    {
        putcUSART('1');
        c = 0;
        c = getcUSART();
        Nop();
    }

}
    
respondido por el Leon Heller

Lea otras preguntas en las etiquetas