Sei sulla pagina 1di 10

PROGRAMAS CONVERSION EN C

Muchos microcontroladores ms nuevos tienen un reloj en tiempo real (RTC), donde se guardan la fecha y hora, incluso cuando el equipo est apagado. Muy a menudo la RTC ofrece la fecha y hora en BCD empaquetado. Para visualizarlos, sin embargo, hay que convertirlos a ASCII. En esta seccin se muestra la aplicacin de la lgica y las instrucciones de rotacin utilizadas en la conversin de BCD y ASCII. Nmeros ASCII En los teclados ASCII, cuando el "0" es presionado, la computadora proporciona el valor "0011 0000" (0x30). Similarmente proporciona el 0x31 (0011 0001) para la tecla "1", y as sucesivamente, como se muestra a continuacin: Cdigo ASCII de los dgitos 0-9

Tecla O 1 2 3 4 5 6 7 8 9

ASCII (hex) 0x30 0x31 0x 32 0x 33 0x 34 0x 35 0x 36 0x 37 0x 38 0x 39

Binario 011 0000 011 0001 011 0010 011 0011 011 0100 011 0101 011 0110 011 0111 011 1000 011 1001

BCD (desempaquetado) 00000000 00000001 00000010 00000011 00000100 00000101 00000110 00000111 0000 1000 0000 1001

Conversin de BCD empaquetado a ASCii El RTC ofrece la hora del da (hora, minuto, segundo) y la fecha (ao, mes, da) de forma continua, independientemente de si la alimentacin est encendida o apagada. Estos datos se proporcionan en BCD empaquetado. Para convertir de BCD empaquetado a ASCII, primero debe convertir a BCD desempaquetado. Entonces, el BCD desempaquetado se etiqueta con 011 0000 (0x30). Lo siguiente muestra la conversin de BCD empaquetado a ASCII. BCD empaquetado BCD desempaquetado ASCII
0x29 00101001 0x02, 0x09 00000010,00001001 0x32, 0x39 00110010,00111001

Converslon ASCII a BCD empaquetado Para convertir ASCII a BCD empaquetado, primero debe convertir a BCD desempaquetado (para deshacerse del 3), y luego combinar los nmeros para hacer BCD empaquetado. Por ejemplo, 4 y 7 en el teclado da 0x34 y 0x37, respectivamente. El objetivo es producir 0x 47 o "01000111", que est en BCD empaquetado. Tecla ASCII BCD desempaquetado BCD empaquetado 4 0x34 00000100 7 0x37 00000111 01000111 or 0x47

Escribir Un programa para convertir BCD a ASCII 0x29 y mostrar los bytes en PORTB y PORTC #include <avr/io.h> int main (void) { unsigned char x, y; unsigned char mybyte=0x29; DDRB = DDRC = 0xFF; // Puertos B y C como salidas x = mybyte & 0x0F; //enmascara los 4 bits superiores PORTB = x | 0x30; //forma un ASCII y = mybyte & 0xF0; // enmascara los 4 bits inferiores y = y >> 4; // desplaza los 4 bits inferiores PORTC = y | 0x30; // forma un ASCII while(1); return 0; } Escribir un programa en C para convertir dgitos ASCII '4' y '7' a BCD empaquetados y mostrarlos en PORTB. #include <avr/io.h> int main (void) { unsigned char bcdbyte; unsigned char w='4'; unsigned char z = '7'; DDRB = 0xFF; // Puerto B como salida w =w & 0x0F; //enmascara los 4 bits superiores para eliminar el 3 w = w << 4; //desplaza los 4 bits superiores para crear digito BCD z = z & 0x0F; //enmascara los 4 bits superiores para eliminar el 3 bcdbyte = w | z; //combina para hacer el BCD empaquetado PORTB = bcdbyte; while(1); return 0; }

Suma de comprobacin de byte en ROM


Para asegurar la integridad de los datos, cada sistema debe realizar el clculo de suma de comprobacin. Al transmitir datos de un dispositivo a otro, o al guardar y restaurar los datos a un dispositivo de almacenamiento se debe realizar el clculo de la suma de comprobacin para asegurar la integridad de los datos. La suma de comprobacin detectara cualquier alteracin de los datos. Para asegurar la integridad de los datos, el proceso de suma de comprobacin utiliza lo que se llama control de suma de comprobacin de un byte. La suma de comprobacin de un byte es un byte adicional que se fija en el extremo de una serie de bytes de datos. Para calcular el byte de suma de comprobacin de una serie de bytes de datos, los pasos siguientes pueden ser tomados:

1. Sume todos los bytes juntos y no tome en cuenta el acarreo. 2. Tome el complemento a 2 de la suma total. Este es el byte de suma de comprobacin, que se convierte en el ltimo byte de la serie. Para realizar la operacin de suma de comprobacin, se suman todos los bytes, incluyendo el byte de suma de comprobacin. El resultado debe ser cero. Si no es cero, uno o ms bytes de datos han sido cambiados (daado). Ejemplo : Supongamos que disponemos de 4 bytes de datos hexadecimales: 0x25, 0x62, 0x52H y 0x3F. (a) Determinar el byte de suma de comprobacin, (b) realizar la operacin de suma de verificacin para garantizar la integridad de los datos, y (c) Si el segundo byte, 0x62, se ha cambiado a 0x22, muestre cmo la suma de comprobacin detecta el error. Solucin: (a) Encuentre el byte de suma de comprobacin. 0x25 + 0x62 + 0x3f + 0x52 Suma total 1 0x18 (no tomando en cuenta el acarreo) Complemento a dos 0xE8 (b) Realizamos la suma de comprobacin para detectar la integridad de los datos 0x25 0x62 0x3f 0x52 0xE8 2 0x00(no tomando en cuenta el acarreo) (c) Si el segundo byte 0x62 es cambiado por 0x22, muestre como la suma de comprobacin detecta el error. 0x25 0x22 0x3f 0x52 0xE8 1 0xC0 (no tomando en cuenta el acarreo da 0x C0, significa que la data esta corrupta)

+ + + +

+ + + +

Escriba un programa C de para calcular la suma de comprobacin de bytes de los datos correspondientes al ejemplo anterior. #include <avr/io.h> int main(void) unsigned char mydata[] ={ 0x2 5, 0x62, 0x3F, 0x52} ; unsigned char sum = 0; unsigned char X; unsigned char chksumbyte; DDRD=DDRB=DDRC = 0xFF; //Port D , Port B y Port C son salidas for(x=0; x<4; x++) { PORTD mydata[x] ; //enviar cada byte al PORTA sum = sum + mydata[ xl ; //sumarlos juntos PORTB = sum; //enviar la suma al PORTB } chksumbyte = ~sum + 1; //Complemento a dos PORTC = chksumbyte; // enviar la suma de comprobacin al PortC while(1); return 0; } Escriba un programa en C para realizar el paso de chequeo del ejemplo anterior. Si el datos bueno, enva carcter ASCII 'G' al PORTD. En caso contrario, enviar 'B' a PORTD. #include <avr/io.h> int main(void) unsigned char mydata[] ={ 0x2 5, 0x62, 0x3F, 0x52,0xE8} ; unsigned char checksum = 0; unsigned char X; DDRA = 0xFF; //PortD salidas for(x=0; x<5; x++) checksum=checksum + mydata[x] ; if (checksum == 0) PORTD = 'G'; else PORTD = 'B'; while(1); return 0; } Cambie uno o dos valores de la matriz mydata y simular el programa para ver los resultados.

Conversin de Binario (hex) a decimal y ASCII en C


La funcin printf es parte de la biblioteca estandar l/O en C y puede hacer muchas cosas, incluyendo la conversin de datos binarios (hex) a decimal, o viceversa. Pero printf toma mucho espacio en la memoria y aumenta el hex sustancialmente. Por esta razn, en los sistemas basados en el microcontrolador AVR, es mejor saber cmo escribir nuestra propia funcin de conversin en vez de usar printf Una de las conversiones ms ampliamente utilizadas es la conversin binario a decimal. En dispositivos tales como ADCs (analgico-a-digital), los datos se proporcionan al microcontrolador en binario. En algunos RTCs, la hora y la fecha tambin se proporcionan en binario. Con el fin de mostrar datos binarios, tenemos que convertirlo a decimal y luego a ASCII. Debido a que el formato hexadecimal es una manera conveniente de representar datos binarios, se refieren a los datos binarios como hexadecimal, datos binarios 00-0xFF convertido a decimal nos da 000 a 255. Una forma de hacerlo es dividimos por 10 y guardamos el resto. Por ejemplo, 11111101 o 0xFD es 253 en decimal. La siguiente es una versin de un algoritmo para la conversin de hex (binario) a decimal: Hex FD/OA 19/0A Cociente 19 2 Resto 3 (digito bajo) LSD 5 (digito medio) 2 (digito alto) (MSD)

Escribir un programa C para convertir 11111101 (hex FD) a decimal y mostrar los dgitos en PORTB, PORTC, y PORTD. #include <avr/io.h> int main(void) unsigned char x, binbyte, d1, d2, d3; DDRB = DDRC = DDRD =0xFF; //Ports B, C, y D salidas binbyte = 0xFD; // byte binario (hex) x = binbyte / 10; //divide por 10 d1= binbyte % 10; //obtiene el resto de la division (LSD) d2 = x % 10; // digito medio d3 = x/10; // digito mas significativo (MSD) PORTB d1; PORTC d2; PORTD d3; while(1); Return 0; }

Muchos compiladores tienen algunas funciones predefinidas para convertir tipos de datos. En la siguiente Tabla se puede ver algunas de ellas. Para utilizar estas funciones, el archivo stdlib.h deben ser incluido. Tenga en cuenta que estas funciones pueden variar en diferentes compiladores. TabIa: Funciones de conversin de tipos de datos en C Funciones Descripcin de la funcin int atoi (char * str) Convierte la cadena str a un entero. long atoi (char * str) Convierte la cadena str a entero largo . void itoa (int n, char * str) Convierte el nmero entero n a una cadena de caracteres str. void ltoa (int n, char * str) Convierte el numero entero largo n a cadena de caracteres str. float atof (char * str) Convierte los caracteres de la cadena str a un valor flotante.

SERIALlZACION DE DATOS EN C

Serializar datos es una forma de enviar un byte de datos un bit a la vez a travs de un nico pin de un microcontrolador. Hay dos maneras de transferir un byte de datos en serie: l. Usando el puerto serie. En el uso del puerto serie, el programador tiene un control muy limitado sobre la secuencia de transferencia de datos. Los detalles del puerto serie del AVR y la transferencia de datos se discuten mas adelante. 2. El segundo mtodo de serializacin de datos es la transferencia de datos un bit de una vez y controlar la secuencia de datos y espacios entre ellos. En muchas nuevas generaciones de dispositivos tales como LCD, ADC, y EEPROM, las versiones serie estn llegando a ser popular debido a que ocupan menos espacio en una placa de circuito impreso. Aunque podemos utilizar estndares como I2C, SPI y CAN, no todos los dispositivos son compatibles con dichas normas. Por esta razn tenemos que estar familiarizado con la serializacin de datos utilizando el lenguaje C. Examine los siguientes cuatro ejemplos para ver cmo la serializacin de datos se hace en C.

Escribir un programa para enviar el valor 0x44 en serie, un bit a la vez a travs PORTC, pin 3. El LSB debera ir en primer lugar. #include <avr/io.h> #define serPin 3 int main(void) { unsigned char conbyte = 0x44; unsigned char regALSB; unsigned char x; regALSB = conbyte; DDRC |= (1<<serPin); for(x=0;x<8;x++) { if(regALSB & 0x01) PORTC |= (1<<serPin); else PORTC &= ~(1<<serPin); regALSB = regALSB >>1; } while(1); return 0; } Escriba un programa en C para enviar el valor 0x44 serialmente un bit a la vez va PORTC, pin3. El bit MSB debe ir en primer lugar. #include <avr/io.h> #define serPin 3 int main(void) { unsigned char conbyte = 0x44; unsigned char regALSB; unsigned char x; regALSB = conbyte; DDRC |= (1<<serPin); for(x=0;x<8;x++) { if(regALSB & 0x80) PORTC |= (1<<serPin); else PORTC &= ~(1<<serPin); regALSB = regALSB <<1; } while(1); return 0; }

Escriba un programa C para obtener a un byte de datos en serie un bit a la vez a travs de PORTC, pin 3. El LSB debe venir primero. #include <avr/io.h> #define serPin 3 int man (void) { unsigned char x; unsigned char REGA=0; DDRC &= ~(1<<serPin); //serPin es una entrada for(x=0; x<8; x++) //repite para cada bit de REGA { REGA = REGA >> 1; //desplaza REGA hacia la derecha un bit REGA |= (PINC & (1<<serPin))<< (7-serPin); //copia el bit en el pin serPin } //del PORTC al MSB de REGA. while(1); return 0; } Escriba un programa C para obtener a un byte de datos en serie un bit a la vez a travs de PORTC, pin 3. El MSB debe venir primero. #include <avr/io.h> #define serPin 3 int man (void) { unsigned char x; unsigned char REGA=0; DDRC &= ~(1<<serPin); //serPin es una entrada for(x=0; x<8; x++) //repite para cada bit de REGA { REGA = REGA << 1; //desplaza REGA hacia la izquierda un bit REGA |= (PINC & (1<<serPin)) >> serPin; //copia el bit en el pin serPin } //del PORTC al LSB de REGA. while(1); return 0; }

Para adaptarlos a la realidad estos programas deberan tener unos retardos para la lectura o escritura del pin.

ASIGNACIN DE MEMORIA EN C Usando el espacio de programa (cdigo) para datos predefinidos fijos es una opcin muy utilizada en el AVR y en los microcontroladores. Veremos cmo utilizar los programas en lenguaje C para acceder a los datos almacenados en la memoria ROM.

Espacio de datos en Flash, RAM y EEPROM del AVR


En el AVR tenemos tres espacios en que se almacenan los datos. Son los siguientes: 1. Los bytes del espacio en SRAM de 64K tienen un rango de direccin de 0000-0xFFFF. Como hemos visto en antes, muchos de los chips de AVR tienen menos de 64K bytes para la SRAM. 2. El espacio de programas (cdigo). Este espacio en la ROM Flash del chip se utiliza para almacenamiento de los programas(opcodes) y por lo tanto esta directamente bajo el control del contador programa (PC). 3. El espacio de EEPROM. Este espacio puede guardar los datos cuando el equipo est apagado. Es por eso que utilizamos EEPROM para guardar variables que no debe perderse cuando el equipo est apagado. Por ejemplo, el punto de ajuste de temperatura de un sistema de enfriamiento debe ser cambiado por los usuarios y no se puede almacenar en el espacio de programa. Asimismo, se deben guardar cuando el equipo est apagado, por lo que se le coloca en la EEPROM. Adems, cuando no hay suficiente espacio de cdigo, podemos colocar las variables permanentes en EEPROM para ahorrar espacio de cdigo. Tamao (Bytes) de memoria para algunos miembros de la familia ATmega Flash SRAM EEPROM 8K 256 256 16K 1K 512 32K 2K 1K 64K 4K 2K 128K 8K 4K Vamos a mostrar cmo leer o escribir desde y hacia la EEPROM mediante programacin C. Se debe tomar en cuenta que los diferentes compiladores de C tienen sus funciones incorporadas o directivas para acceder a cada tipo de memoria. En CodeVision, para definir una variable const en la memoria Flash, slo tiene que poner la directiva Flash antes de ella. Adems, para definir una variable en la memoria EEPROM, puede poner la directiva eeprom delante : Flash unsigned char myNum [] = "Hola"; // usar espacio cdigo Flash eeprom unsigned char = 7;// utilizar el espacio EEPROM Escriba un programa en C para almacenar 'G' en la ubicacin de EEPROM 0x005F. #include <avr/io.h> int main(void) { while(EECR & (1<<EEWE)); // espera a que termine la escritura anterior EEAR = 0x5f; //Coloca la direccion en el registro de direccion EEDR = 'G'; //Coloca el dato en el registro de datos EECR |= (1<<EEMWE); EECR | = (1<<EEWE) ; //Arranca la escritura en la EEPROM while(1); return 0; }

Escriba un programa en C para leer el contenido de la ubicacin 0x005F de EEPROM en el PORTB. #include <avr/io.h> int main(void) { DDRB = 0xFF; while(EECR & (1<<EEWE)); // espera a que termine la escritura anterior EEAR = 0x5f; //Coloca la direccin en el registro de direccin EECR |= (1<<EERE); //Inicia la lectura de la EEPROM escribiendo en EERE PORTB= EEDR ; //Mueve el dato desde el registro de datos al puerto B while(1); return 0; }

Potrebbero piacerti anche