Capitulo 7 Convertidor analógico digital.pdf
-
Upload
alfredo-vazquez -
Category
Documents
-
view
63 -
download
8
Transcript of Capitulo 7 Convertidor analógico digital.pdf
Capitulo 7 Convertidor analógico digital. 7.0 introducción.
El convertidor A/D integrado en los microcontroladores, y la mayor parte de los convertidores A/D
periféricos, están basados en él algoritmo de aproximaciones sucesivas: primero se compara la
tensión de entrada (vi) con la mitad de tensión de fondo de escala (VPS=VREF.=2Nxq, para un CAD de
N bits); si vx>VPS/2, el bit de más peso de la salida (MSB) del CAD se pone a 1, y se incrementa la
tensión de comparación en VPS/4; si vx<VPS/2, se toma MSB =0; y la nueva tensión de comparación
es VPS/4. Para decidir el siguiente bit se procede de forma análoga: si el resultado de la segunda
comparación es positivo (vx>Comparador), el bit se pone a 1; en caso contrario, se pone a cero. El
tercer nivel de comparación será, respectivamente, el anterior o más o menos VPS/8, y así
sucesivamente. Vx debe permanecer constante durante todo el tiempo de conversión, que será
tanto más largo cuanto mayor sea N. Esos niveles de comparación los obtiene un convertidor
digital analógico (CDA).
La relación entre la tensión de entrada del CAD, vx, y el código de salida D, queda descrita
mediante la característica de transferencia. Muchos convertidores se diseñada con dicha
característica desplazada Q/2 hacia la izquierda; es decir, los umbrales de transición de un código a
otro son tensiones múltiplo de Q/2 y no de Q. En realidad, la transición de un código de salida a
otro no se produce siempre para el mismo valor de la tensión de entrada, sino que unas veces se
produce para una tensión ligeramente superior y otras para una tensión ligeramente inferior. El
intervalo de tensiones que llevan a un mismo código de salida se denomina anchura de código.
Como umbral de transición se toma aquella tensión para la que hay una probabilidad del 50% de
que la transición se produzca en una tensión mayor o en una tensión menor. Para un CAD ideal, el
ancho de código es 1LSB para todos los códigos, y la línea que une los centros de los escalones de
la característica de transferencia es una recta de pendiente unidad que pasa por el origen.
En un CAD real, la línea a través del centro de los escalones puede presentar un error de cero
(offset) y cero error de ganancia. Sí hay un error de cero, todos los umbrales de transición están
desplazados en el mismo sentido y en la misma magnitud. Si hay un error de ganancia, una vez
corregido el error de cero, resulta que dicha línea es una recta que no tiene pendiente unidad.
También puede suceder que la anchura de código cambie de uno a otro código, en cuyo caso se
habla de no linealidad diferencial (DNL). DNL se define como la diferencia entre la anchura de cada
código y la anchura ideal (1 LSB), y puede ser positiva o negativa. Si para un código concreto,
DNL=-1 LSB, quiere decir que o bien el código precedente no se observa nunca, o bien DNL está
especificada en unas condiciones extremas en las que difícilmente se observaría el código
precedente. El resultado global de DNL es la denominada no linealidad integral (INL), que es una
medida de cuánto se aparta la línea a través del centro de los escalones de la característica de
transferencia actual respecto a la línea recta de pendiente unidad, una vez se han corregido los
errores de cero y de ganancia, si los hubiere. Si los errores de cero y de ganancia se corrigen
mediante calibración, INL es factor que (junto con la cuantificación) limita la incertidumbre sobre
el valor de la entrada que han dado lugar al código de salida observado. Si no hay calibración, la
incertidumbre viene determinada por el error absoluto, que es la suma de los errores de cero,
ganancia y no linealidad.
7.1 Convertidor analógico digital.
Un convertidor analógico digital (ADC) es un dispositivo capaz de convertir un nivel de voltaje
analógico en un determinado valor binario (digital).
Un convertidor analógico digital establece una relación entre su entrada y salida, dependiendo de
la resolución con que este cuente. El valor de la resolución se obtiene, del valor máximo de
entrada y la cantidad máxima de salida en dígitos binarios.
El convertidor del atmega48 posee una resolución de 10 bits. Utiliza el método de aproximaciones
sucesivas y puede ser multiplexado en 6 canales single ended.
7.2 consideraciones del ADC.
Para utilizar de mejor manera el convertidor analógico digital del AVR atmega48, se debe tener en
cuenta las siguientes consideraciones:
7.2.1 Tiempo de conversión.
Para realizar una conversión con una máxima resolución de diez bits, la frecuencia del circuito de
aproximaciones sucesivas debe estar entre 50 KHZ. y 200 KHZ. Si se requiere una resolución
menor, se puede trabajar con frecuencias superiores a 200 KHZ.
Para obtener las frecuencias aceptables, el modulo del ADC contiene un circuito de pre escala.
Una vez que se inicia una conversión, el ADC toma 13 ciclos de reloj para llevar a cabo una
conversión. Exceptuando la primera conversión que toma 25 ciclos de reloj.
7.2.2 Tensión de referencia.
El voltaje en el pin VREF indica que el intervalo de tensión de la conversión. Las referencias de
tensión pueden ser seleccionadas entre AVCC, tensión de referencia interna de 1.1 volts o la tensión
en el pin externo AREF. Si se ocupa el pin de AREF, se recomienda conectar un capacitor entre el
pin y tierra con el propósito de aumentar la inmunidad al ruido del ADC.
7.2.3 Definiciones.
El comportamiento ideal de un convertidor single ended analógico digital de n bits, es convertir
linealmente la tensión entre tierra y VREF en 2n pasos. El código más pequeño corresponde a 0,
mientras el más alto corresponde a 2n-1.
Offset: la desviación de la primera conversión comparada con el valor ideal.
Error de ganancia: una vez ajustado el offset, el error de ganancia es la desviación del
resultado obtenido en el valor más grande comparado contra su valor ideal.
No linealidad integral (INL). Una vez ajustados el offset y el error de ganancia, el error de
no linealidad integral es el valor de la desviación máxima de una conversión actual
comparada contra una conversión ideal (0.5 LSB).
No linealidad diferencial (DNL): la máxima desviación del ancho del código actual (el
intervalo entre dos conversiones adyacentes) con respecto al código ideal.
Error de cuantización: debido a la cuantización de la tensión de entrada dentro de un
intervalo finito de valores, un cierto intervalo de tensiones de entrada (1 LSB) se
codificaran en el mismo valor.
Certeza absoluta: es la máxima desviación de una configuración actual, comparada contra
una conversión ideal de cualquier código. Este es un efecto compuesto del offset, error de
ganancia, DNL, INL y error de cuantización (2 LSB).
7.3 Configuración del ADC.
7.3.1 Registro de convertidor analógico digital, ADC.
Cuando una conversión analógica digital se ha completado, el resultado es colocado en este par de
registros. Cuando se lee el ADCL, el registro no actualiza hasta leer el ADCH, si el resultado es
ajustado a la izquierda y no se requieren más de 8 bits, se puede leer solamente ADCH. De otra
forma, se debe leer primero el registro ADCL, después el registro ADCH.
7.3.2 Registro de selección de multiplexor, ADMUX.
Bit 7:6 – REFS1:REFS0: Bits de selección de referencia. Selecciona la referencia de tensión
para el ADC. La opción de referencia de tensión interna no debe utilizarse si se tiene
conectado el pin AREF.
Bit 5 – ADLAR: Resultado alineado a la izquierda del ADC.
Bit 4 – Reservado.
Bit 3:0 – MUX3:MUX0: Selección de canal analógico. Selecciona que canal de ADC se
utiliza.
REFS1 REFS0 Selección de tensión de referencia
0 0 AREF, Referencia interna VREF apagada 0 1 AVCC con capacitor externo en AREF 1 0 Reservado 1 1 Referencia interna 1.1 volts con capacitor externo en AREF
Tabla 7.1 selección de tensión de referencia.
MUX3:0 Entrada single ended
0000 ADC0 0001 ADC1 0010 ADC2 0011 ADC3 0100 ADC4 0101 ADC5
Tabla 7.2 selección de canal analógico.
7.3.3 Registro de control y de estado A, ADCSRA.
Bit 7 – ADEN: Habilitación del ADC. Escribir un uno en este bit, activa el ADC.
Bit 6 – ADSC: Inicia la conversión. En modo de conversión simple, escribir este bit a uno,
inicia cada conversión. En modo conversión continua (free running), escribir un uno inicia
la conversión Permanece en uno mientras dure la conversión.
Bit 5 – ADATE. Cuando este bit es puesto a uno, se habilita el auto disparo del ADC. El ADC
inicializa la conversión sobre el flanco de subida de la señal de disparo. La señal de disparo
se selecciona mediante los bits de disparo, ADTS en ADCSRB.
Bit 4 – ADIF: Bandera de interrupción por conversión del ADC. Se activa esta bandera
cuando una conversión del ADC se completo.
Bit 3 – ADIE: Habilitación de interrupción por ADC. Si este bit se activa y también esta
activado el bit I del SREG.
Bit 2:0 – ADPS2:ADPS0: Pre escala del reloj del ADC.
ADPS2 ADPS1 ADPS0 Factor de división
0 0 0 2 0 0 1 2 0 1 0 4 0 1 1 8 1 0 0 16 1 0 1 32 1 1 0 64 1 1 1 128
Tabla 7.3 Pre escala de reloj para el ADC.
7.3.4 ADCSRB – ADC Registro B de Control y Status.
Bit 7, 5:3 – Reservados. Bit 2:0 – ADTS[2:0]: fuente de auto-disparo del ADC. Si ADATE en ADCSRA es
puesta en uno, los valores de estos bits seleccionan la fuente de disparo en una
conversión ADC. Si ADATE es puesto a cero, estos bits no tiene efecto en la
conversión. La conversión es disparada por el flanco de subida de la bandera de
interrupción. Conmutación al modo de conversión continua (free running)
(ADTS[2:0]=0) no provoca un evento de disparo aun cuando la bandera de
interrupción sea puesta a uno.
ADTS2 ADTS1 ADTS0 Fuente de disparo
0 0 0 Modo conversion continua
0 0 1 Comparador analógico
0 1 0 Solicitud de interrupción externa 0
0 1 1 Timer/counter0 comparación canal A
1 0 0 Timer/counter0 sobre flujo
1 0 1 Timer/counter1 comparación canal B
1 1 0 Timer/counter1 sobre flujo
1 1 1 Timer/counter1 evento de captura
Tabla selección de Fuentes de disparo del ADC.
7.3.5 DIDR0 – Registro 0 entrada digital des-habilitadora.
Bits 7:6 – Reservados. Bit 5:0 – ADC5D...ADC0D: ADC5...0 entrada digital des-habilitadora. Cuando estos bits
son puestos a uno se anula la entrada analógica correspondiente.
7.4 Practica del ADC.
7.4.1 Objetivo.
Conocer el funcionamiento del convertidor analógico digital del microcontrolador atmega48 y los
registros que interviene en su funcionamiento.
7.4.2 Material.
Cantidad Descripción
10 LEDs 10 Resistores de 220 Ω 1 Resistor de 10 KΩ 1 Capacitor electrolítico de 0.1 Ωµ/16V 1 Programador avrs 1 Microcontrolador atmega48 1 Fuente de poder de 5 volts Pinzas, cable telefónico, protoboard
7.4.3 Desarrollo
Diagrama
7.4.4 Código
//------------------------Inicio de programa
#include <avr/io.h>
#include <avr/signal.h>
#include<avr/interrupt.h>
void init_ADC(void)
DDRB=0XFF;
DDRD=0XFF; //Puertos B y D como salidas
ADMUX=0; //Alineación a la derecha canal 0
ADCSRA=_BV(ADEN)|_BV(ADEN)|_BV(ADIE)|_BV(ADPS2)|_BV(ADPS0);
//125 HZ @4 MHZ
ADCSRB=0x00; free running mode
sei(); //Habilitación de interrupciones globales
INTERRUPT (SIG_ADC)
PORTD=ADCL; //sacar contenido del ADC a los puertos B y D
PORTB=ADCH;
int main(void)
init_ADC(); //inicializar el ADC
ADCSRA|=_BV(ADCSC); //iniciar conversiones
while(1);
//__________________fin de programa
7.5 Información adicional
7.5.1 Practica del ADC.
Uso del ADC
Descripción. Este programa permite visualizar a través de los LEDs, el valor en binario tomado del ADC conectado a un potenciómetro. El ADC se trabaja a manera de conversión simple y se toman sólo 8 de los 10 bits de resolución, los cuales se ajustan para que la salida vaya de 0 a 63, que es representada por los LEDs conectados al microcontrolador.
Diagrama Esquemático.
Materiales. 1 Potenciómetro. 6 LEDs. 7 Resistores de 220 Ohms. 1 Microcontrolador ATmega8.
Introducción. El ADC convierte señales continuas a números discretos. El ADC es un dispositivo electrónico que pasa un nivel de voltaje de entrada a un valor digital proporcional a la magnitud de la entrada, la salida digital puede estar descrita por diferentes codificaciones. En este caso, el ADC a utilizar es el del microcontrolador ATmega8 el cual es un ADC de 10 bits de resolución, de los cuales sólo se emplean 8. Las características principales del ADC del ATmega8 son: - Resolución de 10 bits. - ± 2 bits de precisión. - 13 ciclos de reloj de tiempo de conversión. - 6 canales de entrada multiplexados, en el encapsulado de 28 terminales. - Intervalo de voltaje de entrada de 0-Vcc. - Selector de voltaje de referencia de 1.1volts - Tipos de conversión continuo o simple - Interrupción de conversión - Ahorro de energía
Potenciómetro. El potenciómetro es un tipo de resistor variable el cual varia conforme se gira la perilla que tiene, en este caso el potenciómetro es empleado para generar un divisor de voltaje el cual al variar el valor del resistor, la salida de voltaje también cambiara proporcionalmente.
El potenciómetro tiene 3 patas las cuales son:
Programa en C.
#include<avr/io.h> //librería de entrada salida #include<util/delay.h> //librería de retardos
int main (void) //inicia el programa principal int ADC_val; //declaración de la variable ADC_val DDRD = 0xFF; //las terminales del puerto D son salidas ADCSRA = 0xF0; //configurar el registro ADCSRA ADMUX = 0x22; //configurar el registro ADMUX
while(1) //inicio del ciclo infinito ADCSRA|=_BV(ADSC); //Activar el bit ADSC del registro ADCSRA inicio de
//conversión
ADC_val=(ADCH*63)/255; //ajustar la recta para que vaya de 0 a 63 PORTD = ADC_val; //la salida del puerto D se iguala a ADC_val
//fin del ciclo infinito
//fin del programa principal
Detalles del programa.
ADCSRA = 0xF0;
Para el registro ADCSRA se asigno 0xF0 o 0b11100000, hexadecimal o binario respectivamente. El
bit 7 ADEN habilita el uso del ADC, y el bit 6 ADSC al escribirle un uno inicia la conversión.
ADCSRB = 0x00;
Para el registro ADCSRB se asigno 0x00 o 0b00000000, hexadecimal o binario respectivamente. El
bit 2 al 0 se pone en cero para tener free.
ADMUX = 0x22;
Se activan los bits 5 y 2 por lo que el registro queda como 0b00100010 (lo que es igual en
hexadecimal a 0x22), al activar el bit 1 le indicamos al ADC que tome la entrada del pin del ADC2
Con el bit 5 (ADLAR) del registro ADMUX se configurara la manera en la que deposita el valor en
los dos registros, para este caso se configuro de la siguiente manera, en la que como se puede ver
se ignoraron los dos bits más significativos.
ADCSRA|=_BV(ADSC);
Al estar trabajando el ADC en este modo es necesario indicarle cada cuando tiene que realizar la
conversión, con esta instrucción sólo entra al bit ADSC del registro y lo habilita, no se modifica
cualquier otro valor del registro ADCSRA.
ADC_val=(ADCH*63)/255;
Ya que el valor del ADCH es de 8 bits (como se ve en la imagen al ajustar el ADLAR), se tiene que
ajustar la salida a que sea de 6 bits, ya que se están usando sólo 6 LEDs, esto se hace ajustando la
recta, multiplicando por el máximo de nuestra salida ideal y dividiéndolo por el máximo de la
salida obtenida.
7.6 Uso del ADC en combinación con el LCD
7.6.1 Para esta parte se emplea el siguiente diagrama.
7.6.2 El programa a emplear es el siguiente:
//----------------inicio del programa
#include <avr/io.h> //se llama la librería de entrada salida
#include <avr /interrupt.h> //se llama la librería de interrupciones
#include “lcd.h” //se llama a la subrutina del LCD
int adc_value; //se declara una variable entera adc-value
ISR (SIG_ADC) //si se presenta la interrupción se entra en esta subrutina
adc_value=ADC; //se iguala a la variable entera adc_value con el resultado del ADC
//termina la subrutina de interrupción
void init_adc(void) //subrutina de inicialización del ADC
ADMUX=0; //resultados alineados a la izquierda, se emplea el canal 0
ADCSRA=_BV(ADEN)|_BV(ADFR)|_BV(ADIE)|_BV(ADPS2)|-BV(ADPS0)|_BV(ADSC);
sei(); //se habilita la interrupción global
void to_ascii(void) //subrutina para presentar los resultados en el LCD
long resultado;
resultado=adc_value;
resultado*=4889;
lcd_putc(resultado/1000000+`0`);
resultado%=1000000;
lcd_putc(`.`);
lcd_putc(resultado/1000000+`0`);
resultado%=1000000;
lcd_putc(resultado/1000000+`0`);
resultado%=1000000;
lcd_putc(resultado/1000000+`0`);
int main (void)
lcd_init(LCD_DISP_ON);
init_adc();
lcd_puts( “voltaje”)
while(1)
lcd_gotoxy(10,1);
to_ascii();
//-----------------fin de programa
//_________inicio de la librería lcd.h
/* prototipo de funciones */
void lcd_init(char dispAttr);
void lcd_clrscr(void);
void lcd_command(char cmd);
void lcd_putc(char c);
void lcd_puts(char *s);
/* Definiciones de puertos y terminales */
#define LCD_DATA4_PORT PORTD //Puerto para bit de datos 0
#define LCD_DATA5_PORT PORTD //Puerto para bit de datos 1
#define LCD_DATA6_PORT PORTD //Puerto para bit de datos 2
#define LCD_DATA7_PORT PORTD //Puerto para bit de datos 3
#define LCD_RS_PORT PORTD//Puerto para línea RS
#define LCD_RW_PORT PORTD//Puerto para línea RW
#define LCD_E_PORT PORTD//Puerto para línea Enable
#define LCD_DATA4_PIN 4 //pin para bit de datos 0
#define LCD_DATA5_PIN 5 //pin para bit de datos 1
#define LCD_DATA6_PIN 6 //pin para bit de datos 2
#define LCD_DATA7_PIN 7 //pin para bit de datos 3
#define LCD_RS_PIN 1 //pin para línea RS
#define LCD_RW_PIN 2 //pin para línea RW
#define LCD_E_PIN 3 //pin para línea Enable
/* Instrucciones, comandos y bits */
#define LCD_DISP_OFF 0x08 //apaga display
#define LCD_DISP_ON 0x0C //enciende display, sin cursor
#define LCD_DISP_ON_BLINK 0x0D //enciende display, con parpadeo
#define LCD_DISP_ON_CURSOR 0x0E //enciende display, con cursor
#define LCD_DISP_ON_CURSOR_BLINK 0x0F //enciende display, con cursor y parpadeo
#define LCD_CLR 0 //DB0: limpia display
#define LCD_BUSY 7 //DB7: LCD ocupado
/* Definiciones para tamaño de display */
#define LCD_LINES 2 //numero de líneas visibles del LCD
#define LCD_DISP_LENGTH 16 //numero de caracteres visibles del LCD
#define LCD_START_LINE1 0x80 //Dirección de DDRAM de la línea 1
#define LCD_ START_LINE2 0XC0 // Dirección de DDRAM de la línea 2
/* función set: longitud de datos y número de líneas
#define LCD_FUNCTION_4BIT_1LINE 0x20 //4 bits interface, 1 linea, 5x7 puntos
#define LCD_FUNCTION_4BIT_2LINE 0x28 //4 bits interface, 2 linea, 5x7 puntos
/* definición de funciones */
#define lcd_e_delay() asm volatile(“rjmp 1f\n 1:”);
#define lcd_e_high() LCD_E_PORT|=_BV(LCD_E_PIN);
#define lcd_e_low() LCD_E_PORT&=~_BV(LCD_E_PIN);
#define lcd_rw_high() LCD_RW_PORT|=_BV(LCD_RW_PIN);
#define lcd_RW_high() LCD_RW_PORT&=~_BV(LCD_RW_PIN);
#define lcd_rs_high() LCD_RS_PORT|=_BV(LCD_RS_PIN);
#define lcd_rs_high() LCD_RS_PORT&=~_BV(LCD_RS_PIN);
#define DDR(x) (*(&x-1)) /*address of data direction register of port x */
#define PIN(x) (*(&x-2)) /*address of input register of port x */
/* función de retardo */
void delay (void)
int i;
for (i=0; i<500; i++);
/* función de cambio de enable */
void lcd_e_toggle(void)
lcd_e_high();
lcd_e_delay();
lcd_e_low();
/* función de lectura */
char lcd_read(char rs)
char data;
if (rs)
lcd_rs_high(); //RS=1: leer dato
else
lcd_rs_low(); //RS=0: leer bandera de ocupado
lcd_rw_high(); //RW=1 modo de lectura
/* Configurar pines de datos como entradas */
DDR(LCD_DATA4-PORT) &=~_BV(LCD_DATA4_PIN);
DDR(LCD_DATA5-PORT) &=~_BV(LCD_DATA5_PIN);
DDR(LCD_DATA6-PORT) &=~_BV(LCD_DATA6_PIN);
DDR(LCD_DATA7-PORT) &=~_BV(LCD_DATA7_PIN);
/* leer nibble alto */
lcd_e_high();
data=0;
if ( PIN(LCD_DATA4_PORT) & _BV(LCD_DATA4_PIN)) data | 0x10;
if ( PIN(LCD_DATA5_PORT) & _BV(LCD_DATA5_PIN)) data | 0x20;
if ( PIN(LCD_DATA6_PORT) & _BV(LCD_DATA6_PIN)) data | 0x40;
if ( PIN(LCD_DATA7_PORT) & _BV(LCD_DATA7_PIN)) data | 0x80;
lcd_e-low();
lcd_e_delay();
/* Leer nibble bajo */
lcd_e_high();
if ( PIN(LCD_DATA4_PORT) & _BV(LCD_DATA4_PIN)) data | 0x01;
if ( PIN(LCD_DATA5_PORT) & _BV(LCD_DATA5_PIN)) data | 0x02;
if ( PIN(LCD_DATA6_PORT) & _BV(LCD_DATA6_PIN)) data | 0x04;
if ( PIN(LCD_DATA7_PORT) & _BV(LCD_DATA7_PIN)) data | 0x08;
lcd_e_low();
return data;
void lcd_write(char data, char rs)
if(rs) //escribir dato (RS=1, RW=0)
lcd_rs_high();
else //escribir instrucciones (RS=0, RW=0)
lcd_rs_low();
lcd_rw_low();
/* Configurar pines de datos como salidas */
DDR(LCD_DATA4_PORT) | = _BV(LCD_DATA4_PIN);
DDR(LCD_DATA5_PORT) | = _BV(LCD_DATA5_PIN);
DDR(LCD_DATA6_PORT) | = _BV(LCD_DATA6_PIN);
DDR(LCD_DATA7_PORT) | = _BV(LCD_DATA7_PIN);
/* Escribir nibble alto */
LCD_DATA7_PORT &= ~_BV(LCD_DATA7_PIN);
LCD_DATA6_PORT &= ~_BV(LCD_DATA6_PIN);
LCD_DATA5_PORT &= ~_BV(LCD_DATA5_PIN);
LCD_DATA4_PORT &= ~_BV(LCD_DATA4_PIN);
If(data & 0x80) LCD_DATA7_PORT |=_BV(LCD_DATA7_PIN);
If(data & 0x40) LCD_DATA6_PORT |=_BV(LCD_DATA6_PIN);
If(data & 0x20) LCD_DATA5_PORT |=_BV(LCD_DATA5_PIN);
If(data & 0x10) LCD_DATA4_PORT |=_BV(LCD_DATA4_PIN);
lcd_e_toggle();
/* escribir nibble bajo */
LCD_DATA7_PORT &= ~_BV(LCD_DATA7_PIN);
LCD_DATA6_PORT &= ~_BV(LCD_DATA6_PIN);
LCD_DATA5_PORT &= ~_BV(LCD_DATA5_PIN);
LCD_DATA4_PORT &= ~_BV(LCD_DATA4_PIN);
If(data & 0x08) LCD_DATA7_PORT |=_BV(LCD_DATA7_PIN);
If(data & 0x04) LCD_DATA6_PORT |=_BV(LCD_DATA6_PIN);
If(data & 0x02) LCD_DATA5_PORT |=_BV(LCD_DATA5_PIN);
If(data & 0x01) LCD_DATA4_PORT |=_BV(LCD_DATA4_PIN);
lcd_e_toggle();
void lcd_waitbusy(void)
char c;
while ( (c=lcd_read(0)) & (1<<LCD_BUSY)); //esperar hasta que se desocupe
void lcd_init(char dispAttr)
DDR( LCD_RS_PORT) |=_BV(LCD_RS_PIN);
DDR( LCD_RW_PORT) |=_BV(LCD_RW_PIN);
DDR( LCD_E_PORT) |=_BV(LCD_E_PIN);
DDR(LCD_DATA4_PORT) |_BV(LCD_DATA4_PIN);
DDR(LCD_DATA5_PORT) |_BV(LCD_DATA5_PIN); DDR(LCD_DATA6_PORT) |_BV(LCD_DATA6_PIN);
DDR(LCD_DATA7_PORT) |_BV(LCD_DATA7_PIN);
delay();
LCD_DATA5_PORT= _BV(LCD_DATA5_PIN); //LCD_FUNCTION_4BIT_1LINE>>4
lcd_e_toggle();
lcd_command(LCD_FUNCTION_4BIT_2LINES);
lcd_command(dispAttr);
/* Función para ubicarse en X, Y */
void lcd_gotoxy(char x, char y)
if (y==0)
lcd_command(LCD_SATART_LINE1+x);
else
lcd_command(LCD_SATART-LINE2+x);
/* Función para limpiar pantalla */
void lcd_clrscr(void)
lcd_command(1<<LCD_CLR);
/* Función para envió de comando */
void lcd_command(char cmd)
lcd_waitbusy();
lcd_writ(cmd,0);
/* función para escribir un carácter */
void lcd_putc(char c)
if(c==`\n`)
lcd_command(LCD_START-LINE2);
return;
lcd_waitbusy();
lcd_write(c, 1);
/* función para escribir una cadena de caracteres */
void lcd_puts(char *s)
char c:
while( ( c= *s++)
lcd_putc©;
// final de la librería