martes, 11 de diciembre de 2012

Conversor A/D D/A PCF8591

En esta entrada vamos a utilizar el integrado PCF8591 para realizar una conversión Analógico-Digital(Lectura), y posteriormente una conversión Digital-Analógica(escritura).
Este componente es un conversor de 8 bit que nos permite realizar lecturas analógicas y también nos da la opción de realizar escritura.
Para realizar la comunicación entre el Pic y el conversor lo vamos a realizar mediante el Bus I2c.

Ejercicio:

El objetivo de esta práctica es el siguiente: mediante el Pic 18F4550 y el conversor PCF8591 realizar un conversor análogico-digital y digital-análogico.
El programa a desarrollar tendrá el siguiente funcionamiento, en el momento que ejecutemos el programa realizaremos una lectura analógica mediante la entrada AIN0 del PCF8591, y la mostraremos en el Lcd.
En el momento que activemos el pulsador RA3, nos pasa a realizar la escritura(Digital-Analógico), a través del pin Aout de nuestro conversor. En función de la combinación de de las entradas utilizadas RA0, RA1, RA2, mostraremos 8 valores diferentes de escritura en el Lcd.

Una vez que hemos analizado el ejercicio, en primer lugar tenemos que analizar el datasheet del PCF8591, para entender su estructura a nivel de Hardware y comprender su funcionamiento a nivel de soft.

El siguiente paso será realizar el esquemático en Isis para posteriormente generar el código y realizar la simulación en Proteus.

PIC 18F4550

Hemos definido las entradas RA0, RA1, RA2, RA3 para los pulsadores de entrada.
RA3-> Corresponde al pulsador para cambiar de lectura a escritura.
RA2-> Pulsador combinacional para escritura 
RA1-> Pulsador combinacional para escritura 
RA0-> Pulsador combinacional para escritura 


Los pines RB0 y RB1 corresponden a SDA y SCL
El puerto D se ha destinado al conexionado del LCD, en función de su librería.
Reset por Hardware a través de MCLR
Aquí podemos ver el conexionado del Pic.



LCD

Como indiqué anteriormente para las conexiones del LCD han sido establecidas en función de la libreria "lcd.c" y se ha utilizado el puerto D del pic.



PCF8591

Para realizar el conexionado del conversor, hemos tomado como guía su propio datasheet.
Las líneas de SDA y SCL la hemos conectado en Pull-Up, ya que estamos haciendo una comunicación vía I2c.
Los pines A0, A1, A2 Y EXT, lo hemos conectado a Gnd.
En VREF Y Gnd, hemos conectado +5v y gnd, ya que estos pines corresponden a las tensiones de referencia que hemos establecido.
La entrada AIN0 esta conectada a la salida del potenciómetro, pues en ese pin realizaremos la lectura  análogica.
Por último el pin AOUT es el pin de escritura, donde hemos conectado un volíimetro para comparar la información mostrada en el Lcd y la salida AOUT.
Adicionalmente he añadido un debugger de I2C que nos proporciona Proteus como herramienta.




Este es el resultado final del esquemático en Isis.




Una vez realizado el esquemático de conexiones Hardware en Isis, pasaremos a realizar la programación.

PROGRAMACIÓN

Abriremos el entorno de MPlab y crearemos un nuevo Proyecto, que en este caso yo lo he llamado CONVERSOR_DA_AD.
Lo primero de todo en el código definiremos los dispositivos y estableceremos su configuración, en la cabecera.


#include <18f4550.h>
#FUSES  INTHS,MCLR,PUT,BROWNOUT
#use delay(INTERNAL=8MHZ)
#use I2C(Master, sda=pin_b0, scl=pin_b1)  // habilitamos I2C y definimos SDA y SCL 
#include <lcd.c>

A continuación definiremos las variables globales.

float volt,LecA;
int x,cambio=0;
int estado=0;

Funciones 
Hemos programado 3 funciones, lectura_an(lectura análogica), lectura_di(lectura digital), printf_di(printf en el Lcd)
Esta parte es muy importante, ya que es donde vamos a establecer la configuración de lectura en I2c y la escritura. Para ello tenemos que haber analizado el datasheet.


void lectura_an() // funcion lectura analogica en I2C
{
i2c_start();           // Inicio la comunicación I2C
i2c_write(0b10010000); // Envío Dirección I2C del PCF8591
delay_ms(10);
i2c_write(0b00000000); // Envío Configuración del PCF8591 para ADC por AIN0
delay_ms(10);
i2c_start();           // Condicion de inicio repetida I2C
i2c_write(0b10010001); // Envío Dirección I2C del PCF8591 
}

void lectura_di()  // funcion escritura analógica
{
i2c_start();
i2c_write(0b10010000);    // byte de direccion I2C PCF8591
delay_ms(10);
i2c_write(0b01000000);    // byte de configuracion como escritura en Aout
delay_ms(10);
i2c_start();                        // Condicion de inicio repetida I2C
i2c_write(0b10010000);
}

void printf_di()

{
volt=x*0.01953125;   // multiplica la variable X por 0,01953125. 5voltios/256= 0,01953125
printf(lcd_putc,"\nTension: %1.2f V",volt);
}

Por último el programa principal, en el cual se puede observar que esta gobernado por los If, que representan la acción de los pulsadores y se ejecuta con un Swich case.

void main()
{
lcd_init();// activa el lcd 
lectura_an(); 
do
    {
if(cambio==0)
{
   if(input(PIN_A3)==1) / / si pulsa RA3 escritura analogica
   {
lectura_di();   // funcion escritura
cambio=1;
   }
else
{
estado=0; // si RA3 esta abierto lectura analogica
  }
}
if(cambio==1)
{

    if((input(PIN_A0)==0)&&(input(PIN_A1)==0)&&(input(PIN_A2)==0))
      {
estado=1;
      }
    if((input(PIN_A0)==0)&&(input(PIN_A1)==0)&&(input(PIN_A2)==1))
      {
estado=2;
      }
    if((input(PIN_A0)==0)&&(input(PIN_A1)==1)&&(input(PIN_A2)==0))
      {
estado=3;
      }
    if((input(PIN_A0)==0)&&(input(PIN_A1)==1)&&(input(PIN_A2)==1))
      {
estado=4;
      }
    if((input(PIN_A0)==1)&&(input(PIN_A1)==0)&&(input(PIN_A2)==0))
      {
estado=5;
      }
    if((input(PIN_A0)==1)&&(input(PIN_A1)==0)&&(input(PIN_A2)==1))
      {
estado=6;
      }
    if((input(PIN_A0)==1)&&(input(PIN_A1)==1)&&(input(PIN_A2)==0))
      {
estado=7;
      }
    if((input(PIN_A0)==1)&&(input(PIN_A1)==1)&&(input(PIN_A2)==1))
      {
estado=8;
      }
}

    switch(estado) 
    {
    case 0:  // lectura analogica digital

lcd_gotoxy(1,2);     
LecA=i2c_read();  //Hago la lectura de A0
LecA=(LecA*5.0)/256.0;             
printf(lcd_putc,"\n\r dato: %1.3f",LecA); 
delay_ms(100);    
    break;

    case 1:    // conversion D_A   0,19 voltios   000
x=10;
i2c_write(x);
printf_di();
    break;
      
    case 2:  // conversion D_A  0,976 voltios 001
x=50;
i2c_write(x);
printf_di();
    break;
      
    case 3:  // conversion D_A  1,46 voltios      010
x=75;
i2c_write(x);
printf_di();
    break;

    case 4:  // conversion D_A  1,95 voltios     011
x=100;
i2c_write(x);
printf_di();
    break;
       
    case 5:  // conversion D_A  2,92 voltios      100
x=150;
i2c_write(x);
printf_di();
    break;

    case 6:  // conversion D_A  3,41 voltios      101
x=175;
i2c_write(x);
printf_di();
    break;

    case 7:  // conversion D_A  3,90 voltios      110
x=200;
i2c_write(x);
printf_di();
    break;

    case 8:  // conversion D_A  4,98 voltios      111
x=255;
i2c_write(x);
printf_di();
    break;
  }
}
while(1);
}

SIMULACIÓN

Abriremos el archivo isis, y cargaremos el archivo *.cof en el Pic, una vez hecho, ejecutaremos el programa con Run
En primer lugar podemos ver la lectura Analógica




En el momento que mantenemos pulsado RA3, cambiamos a escritura(Digital-Analógico), en la primera imagen todos los pulsadores combinacionales están en 000 y nos mostrará el valor de tensión del case 1.



Al introducir la combinación 111, nos mostrará la combinación del case 8, es decir 4,98 voltios.



Aquí podemos ver un vídeo de su funcionamiento.



Descarga aquí el código

No hay comentarios:

Publicar un comentario