Capitulo 7 Convertidor analógico digital.pdf

23
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 (v i ) con la mitad de tensión de fondo de escala (V PS =V REF. =2 N xq, para un CAD de N bits); si v x >V PS /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 V PS /4; si v x <V PS /2, se toma MSB =0; y la nueva tensión de comparación es V PS /4. Para decidir el siguiente bit se procede de forma análoga: si el resultado de la segunda comparación es positivo (v x >C omparador ), 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 V PS /8, y así sucesivamente. V x 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, v x , 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

Transcript of Capitulo 7 Convertidor analógico digital.pdf

Page 1: 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

Page 2: Capitulo 7 Convertidor analógico digital.pdf

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.

Page 3: Capitulo 7 Convertidor analógico digital.pdf

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).

Page 4: Capitulo 7 Convertidor analógico digital.pdf
Page 5: Capitulo 7 Convertidor analógico digital.pdf

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.

Page 6: Capitulo 7 Convertidor analógico digital.pdf

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.

Page 7: Capitulo 7 Convertidor analógico digital.pdf

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

Page 8: Capitulo 7 Convertidor analógico digital.pdf

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

Page 9: Capitulo 7 Convertidor analógico digital.pdf

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;

Page 10: Capitulo 7 Convertidor analógico digital.pdf

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.

Page 11: Capitulo 7 Convertidor analógico digital.pdf

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.

Page 12: Capitulo 7 Convertidor analógico digital.pdf

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;

Page 13: Capitulo 7 Convertidor analógico digital.pdf

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

Page 14: Capitulo 7 Convertidor analógico digital.pdf

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.

Page 15: Capitulo 7 Convertidor analógico digital.pdf

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;

Page 16: Capitulo 7 Convertidor analógico digital.pdf

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);

Page 17: Capitulo 7 Convertidor analógico digital.pdf

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

Page 18: Capitulo 7 Convertidor analógico digital.pdf

#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)

Page 19: Capitulo 7 Convertidor analógico digital.pdf

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();

Page 20: Capitulo 7 Convertidor analógico digital.pdf

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);

Page 21: Capitulo 7 Convertidor analógico digital.pdf

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

Page 22: Capitulo 7 Convertidor analógico digital.pdf

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)

Page 23: Capitulo 7 Convertidor analógico digital.pdf

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