PIC18F + MAX232 USART Extrañeza

De acuerdo, he estado luchando con esto durante semanas y me está volviendo loco. He estado trabajando con PIC durante mucho tiempo y estoy muy confundido acerca de por qué no puedo hacer que mi USART funcione.

En primer lugar, algunas preguntas para las personas que no quieren leer esta publicación pero que podrían ayudar:

  • ¿Cómo invierto las señales para usar con el chip MAX232?
  • ¿Deben establecerse TX y RX en salidas, entradas o salida para RX y entrada para TX? La hoja de datos dice uno, los ejemplos dicen otro.
  • ¿Necesito usar el PLL?
  • ¿Para qué sirven los indicadores USART_ADDEN_OFF y BAUD_IDLE_RX_PIN_STATE_HIGH y por qué no están en la documentación de C18?

Para todos los demás, aquí está la larga historia:

La configuración: PIC18F46K20 <--> MAX232 <--> PC

RC7 es RX y RC6 es TX.

El software de terminal es solo un intérprete de Python:

port = serial.Serial("COM6", 2400, timeout=5)
port.write("abcd")
print port.read(1)
etc...
  • Si conecto los pines T1in y R1out del MAX232, entonces el bucle invertido en serie funciona perfectamente desde mi PC, por lo que sé que la placa MAX232 está bien.
  • Saqué el PIC de su placa y está en una placa de prueba para la depuración. Las únicas cosas enchufadas son energía, tierra y TX y RX.

He probado una increíble cantidad de variaciones de código diferentes, ninguna funciona. Estas son algunas de las cosas que he probado:

Básicamente, esto se tomó en su totalidad de esta publicación: problema PIC18 USART

Tenga en cuenta el uso de un PLL y la configuración HS para BRGH, y que el pin TX está configurado para entrada, y solo RX está configurado para salida, al contrario de la hoja de datos.

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

void main(void)
{
char c = 'a';

TRISC = 0x80;
    // Internal osc. 8 MHz, PLL 4x
    OSCCON |= 0xE2;
    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, 207);

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

}

De todos modos, me siento tonto por no poder hacer que un USART tonto funcione, pero estoy completamente perplejo. ¿Qué me estoy perdiendo? ¿Qué estoy haciendo que es estúpido? Alguien por favor ayuda!

Además , estoy agotado: publicaré esto último antes de irme a la cama e intentaré más mañana.

Esto devuelve un flujo constante de galimatías, incluso si no estoy escribiendo nada en el USART desde la PC:

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

void main(void)
{
char test = 'a';
TRISC = 0xFF;
OSCCON |= 0b11100010;
OSCTUNEbits.PLLEN = 1;

    while (!OSCCONbits.IOFS);

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, 207);
    while (1)
    {
        WriteUSART(test);
        while(!DataRdyUSART());
        test = ReadUSART();
        Nop();
    }
}

ACTUALIZAR

Bien, ahora mi pin TX está a 0,00 voltios constantes. Es casi como si estuviera conectado directamente a tierra (muy bien puede ser en este punto, no lo sé). He intentado cambiar los PIC, hacer que transmita constantemente, hacer que no haga nada, cambiar los bits de configuración... nada parece ayudar. El pin RX se encuentra alto (lo cual es correcto, porque no recibe nada), pero el pin TX se encuentra plano a 0 V, ya sea que se suponga que debe transmitir o no.

Aquí está mi código actual:

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

void main(void)
{
char test = 't';
TRISCbits.RC7 = 1;
TRISCbits.RC6 = 0;
OSCCON = 0b11100010;
OSCTUNEbits.PLLEN = 0;

    while (!OSCCONbits.IOFS);

baudUSART(BAUD_IDLE_CLK_LOW & 
          BAUD_AUTO_OFF & 
          BAUD_8_BIT_RATE & 
          BAUD_IDLE_RX_PIN_STATE_HIGH &
          BAUD_IDLE_TX_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, 207);
    while (1) {
//       WriteUSART(test);
//      while(!DataRdyUSART());
//        test = ReadUSART();
        Nop();
    }
}

¿Qué diablos hice para que hiciera eso? Tenga en cuenta que también reconstruí mi código anterior (un ejemplo de arriba, que anteriormente solo escupía galimatías), y ahora el voltaje también es 0.0V con ese archivo hexadecimal. Además, el loopback MAX232 aún funciona correctamente. ¿Eh?

¿Qué software de terminal estás usando? ¿Cómo está configurado? Además, ¿ha verificado los PIC Rx/Tx con un osciloscopio y/o ha confirmado la continuidad entre todas las líneas con un multímetro?
Agregué una nota en la parte superior sobre la configuración de mi terminal (todo Python). Todavía no he verificado con un alcance porque no tengo uno a mano; es posible que viaje a algún lugar mañana donde haya uno. Sin embargo, tengo voltajes confirmados con un multímetro.
Agregué una actualización al final de mi publicación, si tienes alguna idea :-/

Respuestas (2)

De acuerdo, para cualquiera que alguna vez se encuentre con algo como esto en el futuro:

El problema era que había una fuga del rastro de energía al rastro en serie, de modo que aparecía una onda de 60 Hz en la línea SPI, lo que obviamente estropearía las cosas.

Sé que la probabilidad de que esta misma solución se aplique a otras personas es pequeña, ¡pero tal vez al menos te dé algunas ideas!

Viejo consejo:

  • Dividirlo en secciones.

  • Siempre que sea posible, elimine la complejidad que pueda estar interfiriendo en el funcionamiento básico de la conexión de bajo nivel.

  • Trate de probar una cosa a la vez y cambie una cosa a la vez.

    Puede verificar N cosas que pueden suceder como resultado de un cambio, pero esto corre el riesgo de enmascarar qué está causando qué.

    Idealmente, los cambios solo se dirigirían a una sola área en su efecto).


ENTONCES:

El pin TX debe configurarse como salida.

Si está utilizando un circuito integrado RS232 (que invierte), el nivel de inactividad de TX en el PIC debe ser alto.

Si desea ver si el reloj PIC y las conexiones de comunicaciones funcionan como se espera, puede usar una rutina de TX un poco golpeada (muchas alrededor) para enviar caracteres a la PC. Si no puede obtener ningún dato que se muestre de esta manera, su conexión es sospechosa de alguna manera. Si obtiene algún rastro de datos en la PC, puede modificar las cosas hasta que funcione y luego saber qué debe hacer su PIC a través de UART

La funcionalidad de bajo nivel de TX se puede confirmar midiendo el voltaje con un voltímetro.

  • Si inactivo = 1 lógico = alto = 5 V (digamos) y envía un bucle cerrado
    y envía nulo ($ 00)

  • entonces el voltaje caerá a un bajo % de 5V.
    por ejemplo, si puede enviar SIN demora entre caracteres * (depende del almacenamiento en búfer, etc.), entonces estaría enviando:
    inicio = 0, 8 x bajo, 1 x parada = 5 V, por lo que vería 1/10 x 5 V = 0,5 V CORRIENTE CONTINUA.

    Si tiene un retraso entre los caracteres, el voltaje aumentará en consecuencia.

Sin alcance: si envía caracteres tx a la PC en un bucle, debería ver un cambio de voltaje cuando envía y debería ver que el voltaje en la salida RS232 también cambia pero con polaridad opuesta.

La salida RS232 a la PC debe estar inactiva baja y luego cambiarse de la manera opuesta a la prueba anterior.

¡Muchas gracias por los consejos! Seguí tu consejo y puse el pin TX en salida. Además, comencé a verificar los voltajes y, de alguna manera, ahora tengo un pin TX que se encuentra en una constante de 0.0 V (esto no sucedía antes). Verifique el final de mi publicación para ver la actualización que muestra mi código actual. ¿Pensamientos?