Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
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
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; }
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.
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.
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; }