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:
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...
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?
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.
Oli Glaser
bhilburn
bhilburn