PIC16: Problemas con la recepción de UART

Tengo un PIC16 para el que tengo la transmisión UART (asincrónica) que funciona bien, pero la recepción UART produce resultados no válidos.

Por ejemplo, ase interpreta como O, bse interpreta como 'y cse obtiene como N.

Aquí está mi función de recepción:

char UART_read(void) {
    while(!PIR1bits.RCIF) {}

    return RCREG;
}

Mi hipótesis es que la polaridad de UART es incorrecta para el receptor, por lo que, en particular, los bits de inicio/parada se estropean. Configuré el SCKPbit (consulte la página 302) para invertir los datos en el pin TX/CK pero no puedo encontrar un equivalente para el pin RX/DT.

¿Cuál podría ser la causa de que la recepción UART no funcione? ¿Cómo puedo invertir los datos en el pin RX/DT?

¿Cuál es la fuente de datos? ¿Está seguro de que la fuente y el sumidero tienen la misma velocidad en baudios, bits de parada, paridad, niveles de voltaje, etc.?
Además, ¿qué sucede si realiza una prueba de bucle invertido?
Noté algo similar cuando la velocidad en baudios no coincide correctamente con la frecuencia del oscilador interno. OSCCONbits.IRCFregistro configurado correctamente?

Respuestas (2)

EDITAR : esta respuesta se ha modificado para reflejar el comentario del autor de la pregunta y señala que tiene toda la razón en su diagnóstico del problema, que no es una información muy útil. La única información útil en la sección es el hecho de que no hay bit de inversión de recepción... Pero tal vez ayude a futuras personas a diagnosticar sus propios problemas de UART.


Así que echemos un vistazo

a se asigna a O, lo que significa que 01100001 se asigna a 01001111

b se asigna a ' lo que significa que 01100010 se asigna a 00100111

Supongamos que hay un 1 implícito antes de cada uno de ellos y un 0 implícito después (bits de inicio y parada). El módulo RX recibe una señal baja continua, luego el bit de parada se envía como alto, que se comerá como una señal inactiva, luego el 0 inicial se consumirá como bit de parada. Entonces los bits restantes se invertirán,

so 'a' == 1 10000110 0 initially (we send least significant bit first)
1 (implicit start bit) and starting 1 are both consumed as idle bits
then the first 0 is treated as a start bit
so received == 00001100 inverted (the extra zeros are the stop bit and idle bits after transmission has ended)
11110011 and reverse it (it was sent LSB first)
11001111 is what the inverted input would look like
01001111 is what's actually received which is super close!
if what you actually sent was "abc" all in a row, then the start bit of the b would make what was received 01001111 which matches exactly

'b' == 1 01000110 0 ==> 10001100 inverted and reversed gives
11001110 is what should have "logically" happened
00100111 actual
So that doesn't quite match, but if we assume that the "abc" is what happened again, we get
01001110 which is close enough (not sure where the shift came from)

Parece que acertó en el diagnóstico, desafortunadamente no hay un bit de configuración de "señal de inversión" similar en el receptor en el PIC. Aunque no es difícil poner un inversor en la ruta de recepción, ¡que por cierto es lo que recomendaría hacer!

Como señaló Olin, las señales rs-232 estándar son de +3 V a +15 V para un '1' lógico y de -3 V a -15 V para un '0' lógico. El PIC está diseñado para funcionar a niveles "TTL", lo que significa "lógica transistor-transistor". La idea es que el PIC esté diseñado para hablar con otras cosas que están físicamente cerca (es decir, en la misma placa) y, por lo tanto, la distancia de transmisión adicional y el rechazo de ruido proporcionados por los niveles completos de rs-232 no son necesarios para la operación "estándar". No es práctico poder generar completamente internamente los voltajes positivo/negativo necesarios para la operación rs-232 completamente internamente en el PIC, por lo que la comunicación rs-232 "normal" nunca fue realmente una opción.

Dado que los niveles TTL no son el estándar, sino un derivado del estándar (mismo protocolo para temporización, bits de inicio y parada, paridad, pero diferentes voltajes), no compre un "adaptador rs-232" de consumo para su computadora a menos que se adhiere a la norma. ¡Hacen adaptadores rs-232 de nivel TTL y son muy populares en los sitios web de aficionados! Consulte el cable de Adafruit o la ruptura de Sparkfun FTDI . Encuentro que, en general, si va a un conector DB9, probablemente sea un adaptador de nivel rs-232.

Eso es un O(la letra), no un 0(el número). Entonces 01100001, 01100010, 01100011asigne a 01001111, 00100111, 01001110respectivamente. Además, recuerde que los bits se envían LSB primero. Entonces, si la línea de recepción está invertida, el bit más a la derecha 1 es el bit de inicio. Así 01100001se vuelve ~10110000, 01100010se vuelve ~11011000y 01100010se vuelve ~10100111, todo coincidiendo con lo que recibo.
@Randomblue: corregí mi respuesta para hacer el análisis correctamente y agregué algunas notas adicionales sobre la discrepancia de rs-232 y TTL para la interacción entre PIC y computadora.
Ninguno de los dos productos que vinculó para convertir señales de nivel lógico a RS-232. Ambos parecen ser convertidores de USB a serie, lo que no se aplica aquí.
@OlinLathrop: nunca estuve muy seguro de cómo se llamaba el protocolo real. "Serial" implica cualquier protocolo de comunicación no paralelo, y el "Protocolo serial asíncrono" parecería permitir todo tipo de métodos de encuadre de caracteres diferentes, endianness, etc. Tiene razón en que los enlaces que di no son para, explícitamente, rs -232 adaptadores. ¿Es USB a UART el término correcto? El cable Adafruit en realidad se llama a sí mismo un "cable USB FTDI TTL-232", por lo que supuse que "adaptador rs-232 de nivel TTL" era un título apropiado.
@OlinLathrop: En cuanto a su aplicabilidad a esta conversación, admito que estaba suponiendo sobre el uso de Randomblue aquí. Dijo que estaba tratando de conectar su computadora con Windows 7 a su proyecto (en el comentario debajo de su respuesta), y le di enlaces a productos que lo harán más fácil para él. Podría usar circuitos max232 para interconectar el chip que tiene ahora con el adaptador serial que tiene ahora, pero asumo que, como la mayoría de los aficionados, se dará cuenta de que se cansa rápidamente y querrá un método más simple.

Para ver si necesita inversión, observe el nivel de inactividad de la línea. El UART de nivel lógico normal indica inactividad alta. Dado que invirtió la salida, debería estar en ralentí bajo. Si el otro dispositivo está usando señales invertidas para recibir (su transmisión), entonces casi seguro que está usando los mismos niveles para sus transmisiones (su recepción). Verifique con un osciloscopio, pero probablemente necesite inversión, que se puede hacer con una puerta lógica de inversor o simplemente un transistor y una resistencia o dos considerando la baja velocidad de datos.

¿Cómo pensaste que la recepción funcionaría sin inversión cuando la transmisión lo requería?

Agregado:

Ahora ha revelado que simplemente conectó las líneas PIC UART a las líneas de recepción y transmisión RS-232 y de alguna manera ejecutó todo para que funcionara. Los niveles lógicos digitales usados ​​por el PIC y los niveles RS-232 no son compatibles, y alto/bajo también están invertidos. Se supone que RS-232 está por debajo de -5 V para línea inactiva (espacio) y por encima de +5 V para activo (marca). Claramente, un PIC no puede garantizar estos niveles al transmitir, y estos niveles pueden dañarlo al recibir. Los niveles lógicos digitales normales son alto para el espacio y bajo para la marca, que es también lo que hace el PIC, excepto algunos limitados, como el suyo, donde una o ambas líneas se pueden invertir.

Algunos chips receptores RS-232 juegan sueltos con las especificaciones RS-232 y funcionan con señales de 0-5 V que impulsan su línea de recepción. Aparentemente, este es el caso con su PC, por lo que pudo recibir caracteres en la PC después de invertir la línea de transmisión PIC. Para que la transmisión PC --> PIC funcione, debe invertir la señal y asignar el resultado al rango Vss a Vdd del PIC. Si no lo hace, puede dañar el PIC, lo que puede haber ocurrido ya.

Todo esto es por lo que se creó el tipo de chip MAX232. Este se alimenta desde el PIC Vdd y Vss, contiene sus propias bombas de carga para generar los voltajes RS-232, tiene el circuito de controlador y receptor adecuado en cada lado, y también realiza la inversión. Muchas empresas hacen una serie de variantes de esto. Estos son chips muy comunes y disponibles.

También puede obtener pequeños módulos que tienen el chip convertidor, la bomba de carga y las tapas de la fuente de alimentación, y el conector DB-9 estándar, todo en una sola unidad. Hago uno de estos que incluso se vende en microchipdirect. Consulte http://www.microchipdirect.com/ProductSearch.aspx?Keywords=TEMRS002 .

Para responder a su pregunta, estoy usando lo que supongo que es una configuración extremadamente común: Win7 con TeraTerm en un lado y PIC16 en el otro. ¿No debería UART "simplemente funcionar"?
@Random: Absolutamente no, ya que incluso una mirada superficial a las especificaciones relevantes habría revelado. Conectar un PIC directamente a un RS-232 puede dañar el PIC y no proporcionar los niveles correctos en el lado RS-232, incluso si simplemente invirtió las señales lógicas. Es por eso que existen chips como el MAX232 común y sus muchas variantes e imitaciones. Realmente necesitas leer algunas especificaciones de vez en cuando.
No tienes idea de cuántas veces he leído el EUSARTcapítulo (a partir de la página 291 de la hoja de datos de PIC16 ). No hay mención o advertencia con respecto a las conexiones directas a RS232 o MAX232. ¿Dónde fallé en el proceso? Supuse que el capítulo de la hoja de datos PIC16 sobre EUSART cubriría el caso de uso común: RS232.
La hoja de datos menciona los niveles máximos de entrada en cualquier pin. RS232 está muy por encima de esos niveles. Realmente no está dentro del alcance de la hoja de datos de PIC16 explicar cómo convertirlos. En general, si está tratando de conectar dos cosas, no puede esperar obtener toda la información leyendo las especificaciones de solo una de ellas.
@Random: no es trabajo de Microchip, y desordenaría la hoja de datos para explicar RS-232 o qué conversiones se necesitan para conectar el PIC a otra cosa. Documentan lo que hace el PIC. Es su trabajo saber a qué está conectando el PIC y agregar cualquier circuito de interfaz que pueda ser necesario según las especificaciones del otro lado.