¿Enviar valores enteros a través de la comunicación serie en PIC a PIC?

2

Necesito pasar valores enteros de un PIC a otro a través del puerto serie

para char puedo usar el siguiente código

char data1='a';
TXREG=data1;                                     
while(PIR1.TXIF==0); 

pero cuando intento pasar una variable de tipo int, devuelve un equivalente ASCII ..

¿Hay alguna forma de recibir los datos como un entero en lugar de un tipo de carácter?

    
pregunta Suraj Bhawal

3 respuestas

7

Ya está enviando valores enteros a través de UART con el código que muestra. Aparentemente, su problema es enviar enteros que tienen más de 8 bits de ancho.

El UART solo envía de forma inherente bytes de 8 bits (en la configuración más común) a la vez. Si desea enviar un entero más ancho, debe enviar más de un byte para representar ese entero. Por ejemplo, puede decidir que todos los enteros de múltiples bytes se envíen en el orden de bytes menos significativo al más significativo. Si tiene un entero de 16 bits para enviar, primero envíe los 8 bits inferiores y luego los 8 bits superiores. El PIC receptor hace lo contrario. Primero recibe los 8 bits bajos, luego los 8 bits altos y los escribe consecutivamente en la memoria para que el resto del sistema pueda acceder al valor como un entero de 16 bits.

Los enteros de 24 bits, por ejemplo, se envían de la misma manera, excepto que se necesitan 3 bytes en lugar de 2. Los enteros de 32 bits requieren el envío de 4 bytes.

Tenga en cuenta que nada de esto tiene nada que ver con el envío de valores numéricos para aparecer en un emulador de terminal. Los terminales muestran caracteres. Cada carácter posible tiene un código binario predeterminado. Envía el byte que contiene el código para un carácter, y ese carácter aparece en el terminal. Por ejemplo, el código para la letra "A" es 65. Si envía el byte 65, un terminal mostrará "A". Del mismo modo, el envío 48 hace que el terminal muestre "0". Busque algo llamado código ASCII. Eso le dirá cuáles son los valores de bytes para cada uno de los caracteres que puede mostrar el terminal.

Aquí hay un ejemplo para ilustrar todo lo anterior. Supongamos que desea enviar el valor entero de 16 bits 9525. Convirtámoslo a HEX para poder ver los bytes individuales fácilmente: 2535h. Anteriormente ha decidido enviar valores de múltiples bytes en orden de bytes bajo a alto. Los dos bytes que enviará son, por lo tanto, 35h y 25h en ese orden. Estos tienen los valores decimales 53 y 37. Usted envía estos bytes, y el otro PIC recibe 53 y 37. Tenga en cuenta que (37 * 256) + 53 = 9525, que es el valor que está transmitiendo.

Si estos terminales fueran interceptados por un terminal, obtendríamos los mapas de caracteres a 53 y 37, que son "5" y "%". Entonces, el terminal mostrará "5%" cuando envíe 9525. Si desea que el terminal muestre "9525", tendrá que enviar los valores de bytes para los caracteres "9", "5", "2" y " 5 ". Esos son 57, 53, 50 y 53. Eso es mucho más complicado, ya que el PIC tiene que averiguar los dígitos decimales del entero binario que tiene, convertirlos a los códigos de caracteres para esos dígitos y luego enviarlos.

En general, es mucho más fácil hacer cualquier tipo de conversión de interfaz de usuario en la PC y dejar que el PIC envíe y reciba archivos binarios nativos. Convertir el número entero binario 9525 a los caracteres "9525" es trivial para la PC, pero puede requerir un espacio de código sustancial y ciclos en un PIC pequeño.

    
respondido por el Olin Lathrop
4

Si envía un solo valor de 8 bits de un UART a otra computadora, solo será un valor binario. Digamos que tienes un número como 52.

char data = 52;        // or char data = 0x34;

y envió los datos a través del UART;

TXREG = data;
while(PIR1.TXIF==0);

Si conectó un programa de terminal como RealTerm , configúrelo para recibir sus datos y configure la opción Mostrar como Hex [espacio ] mostrará el valor en hexadecimal como:

34

ya que el hex 34 (3 * 16 + 4) es lo mismo que 52. Si cambia la pantalla a ASCII, en cambio, solo mostrará un 4 ya que el código ASCII para 4 es 0x34, que es una representación incorrecta para Valor que se envió.

A continuación, puede enviar el valor de 8 bits en hexadecimal, un mordisco de 4 bits a la vez:

char data = 52;    // or char data = 0x34;

TXREG = (data & 0xf0) >> 4;
while(PIR1.TXIF==0);

TXREG = data & 0x0f;
while(PIR1.TXIF==0);

Esto podría ponerse en un bucle, pero es más fácil de ver de esta manera.

Para mostrar los caracteres, una vez más necesitas poner RealTerm en modo Hex [espacio]. Los nibbles se mostrarán en la pantalla como 03 04. Ya que estos no son dígitos ASCII correctos, no se mostrarán correctamente en la configuración de visualización ASCII.

Si desea ver los caracteres ASCII reales, deberá agregar un carácter '0' (0x30) a cada valor, como este:

char nibble;
nibble = ((data & 0xf0) >> 4) + '0';

Sin embargo, esto solo funcionará para los valores 0-9; los valores hexadecimales A-F no se mostrarán correctamente ya que 9 y A no están uno al lado del otro en el alfabeto ASCII. Así que tienes que agregar una sentencia if para manejar esto:

char data = 52;    // or char data = 0x34;
char nibble;

nibble = ((data & 0xf0) >> 4) + '0';
if (nibble > '9') nibble += 'A' - '9';
TXREG = nibble;
while(PIR1.TXIF==0);

nibble = (data & 0x0f) + '0';
if (nibble > '9') nibble += 'A' - '9';
TXREG = nibble;
while(PIR1.TXIF==0);

Ahora los dígitos aparecerán en la pantalla ASCII como 34.

Hay una forma más de hacer esto, y es enviar el valor como caracteres decimales. Eso requiere una conversión del número binario 52 (o 0x34) a una representación de cadena equivalente del número decimal, en este caso "52". Hay varias formas de hacer esto en C, una es itoa (entero a ASCII) y la otra es sprintf. Cualquiera de los dos necesitará un poco de código de biblioteca, lo cual, dependiendo del tamaño de flash de su microcontrolador, puede o no ser un problema.

Aquí está cómo hacerlo usando sprintf:

char buf[5];    
char data = 52;       // or char data = 0x34;
unsigned char i;

sprintf(buf,"%d",data);

i = 0;
while (buf[i]!='
char data = 52;        // or char data = 0x34;
') { TXREG = buf[i++]; while(PIR1.TXIF==0); }

El printf convierte el valor en datos a decimal (debido al% d) y lo almacena como caracteres ASCII en la matriz de caracteres buf. El tamaño máximo del número es de cuatro caracteres, ya que un número de 8 bits firmado puede ir de -127 a 128. Las cadenas C terminan con un '\ 0' (nulo), por lo que la matriz debe tener cinco elementos. El bucle while luego envía caracteres hasta que se alcanza el carácter nulo.

    
respondido por el tcrosley
3

Para enviar un valor entero a través del UART, debe enviar 2 bytes. Por ejemplo:

int data = 0x1234;
TXREG = data & 0xff;
while(PIR1.TXIF==0); 
TXREG = (data >> 8) & 0xff;
while(PIR1.TXIF==0);
    
respondido por el Alexxx

Lea otras preguntas en las etiquetas