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, a
se interpreta como O
, b
se interpreta como '
y c
se 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 SCKP
bit (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?
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.
O
(la letra), no un 0
(el número). Entonces 01100001
, 01100010
, 01100011
asigne a 01001111
, 00100111
, 01001110
respectivamente. 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í 01100001
se vuelve ~10110000
, 01100010
se vuelve ~11011000
y 01100010
se vuelve ~10100111
, todo coincidiendo con lo que recibo.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?
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 .
EUSART
capí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.
apalopohapa
apalopohapa
viejo k
OSCCONbits.IRCF
registro configurado correctamente?