Autor Tema: PCF8591P, Ejemplo de lectura y escritura "simultanea" de analogicas.  (Leído 3201 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Diploko

  • PIC10
  • *
  • Mensajes: 9
PCF8591P, Ejemplo de lectura y escritura "simultanea" de analogicas.
« en: 16 de Noviembre de 2010, 17:08:38 »
Hola a todos!
Estos días estuve peleandome un módulo I2C de analógicas, el PCF8591P, y gracias a los ejemplos ya existentes en el foro he podido arreglarmelas pero como me ha dado bastante lata a pesar de ello y también he leido unos cuantos mensajes de dificultades varias con éste módulo por parte de otras personas que también se iniciaban, ahora me decido a mostrar este ejemplo que combina la lectura de los 4 canales y la escritura del canal de salida analógica con una sola función.
El programa varía la frecuencia de un variador (salida analogica del PCF8591) y lee el consumo de éste (con una de las entradas analogicas del PCF8591)

Código: C
  1. /*
  2. Prueba entradas y salida analógicas PCF8591P.
  3. Probado con un variador controlando la referencia de frecuencia y leyendo el consumo.
  4. Funciona ok.
  5.  
  6. Conexiones PCF8591P:
  7. pines 1,2,3,4,11: N.C.
  8. pines 5,6,7: Address (6)
  9. pines 8,12,13: GND
  10. pines 9,10: SDA y SCL (Bus I2C)
  11. pines 14,16: VDD
  12. pin   15: + Salida analogica
  13.  
  14. */
  15.  
  16. #include <16F877.h>
  17.  
  18. #FUSES HS,NOPROTECT,PUT,BROWNOUT,NOLVP,NOWDT,DEBUG
  19. #USE DELAY(CLOCK=20000000)
  20. #USE I2C(MASTER,SDA=PIN_C4,SCL=PIN_C3,FORCE_HW)
  21. #USE FAST_IO(B)    
  22. #USE rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)  
  23.  
  24. #include <PCF8591P.c>
  25.  
  26. #byte port_a = 5
  27. #byte port_b = 6
  28. #byte port_c = 7
  29. #byte port_d = 8
  30. #byte port_e = 9
  31.  
  32. int rfVariador,ain0,ain1,ain2,ain3;
  33.  
  34. void main()
  35. {  
  36.        
  37.         printf("Inicio 0\n");
  38.        
  39.         //Definición de E/S
  40.         set_tris_a(0b00111111);  
  41.         set_tris_d(0b11111111);  
  42.         set_tris_e(0b00000111);  
  43.         set_tris_b(0b00000000);  
  44.         set_tris_c(0b00000000);  
  45.        
  46.  
  47.         while(true)
  48.         {
  49.                
  50.                 // Prueba completa del módulo PCF8591P
  51.                
  52.                
  53.                 rfVariador=ain1;                        // Lectura del canal 1 (tengo un potenciómetro de 10k para probar rápidamente)
  54.                 printf("Ref Frecuencia: \%u\n",rfVariador);             // Monitorizo por RS232 la referencia de frecuencia del variador
  55.                
  56.                 // Lectura y Escritura 4 canales Analogicas I2C.
  57.                 ain0=rwPCF8591P(0,rfVariador);                                 
  58.                 printf("Entrada AIN-0 PCF8591P: \%u\n",ain0);          
  59.                 ain1=rwPCF8591P(1,rfVariador);
  60.                 printf("Entrada AIN-1 PCF8591P: \%u\n",ain1);          
  61.                 ain2=rwPCF8591P(2,rfVariador);
  62.                 printf("Entrada AIN-2 PCF8591P: \%u\n",ain2);          
  63.                 ain3=rwPCF8591P(3,rfVariador);
  64.                 printf("Entrada AIN-3 PCF8591P: \%u\n\n",ain3);
  65.                        
  66.                 // Retardo bucle.
  67.                 delay_ms(200);
  68.                
  69.         }
  70. }

En el "PCF8591P.c" están las funciones de solo lectura, solo escritura y lectura/escritura:
Código: C
  1. // Las funciones están pensadas para funcionar como DIRECCION ó Nodo 6 (110)
  2.  
  3.  
  4. // Seleccionamos el módulo PCF8591P del bus I2C y damos un valor a la salida analógica
  5. void writePCF8591P(int dato)
  6. {
  7.         i2c_start();                    // Inicio comunicación I2C  
  8.         i2c_write(0b10011100);  // Envío Dirección I2C del PCF8591   (Nodo6)
  9.         i2c_write(0b01000000);  // Envío Configuración del PCF8591 para Conv. DA  
  10.         i2c_write(dato);                // Envío el dato de salida analógica
  11.         i2c_stop();                             // Detengo comunicacion I2C
  12. }
  13.  
  14.  
  15. // Lectura analogica 4 canales del módulo PCF8591P.
  16. int readPCF8591P(int canal)
  17. {
  18.         int lectura,control,addressWrite,addressRead;
  19.        
  20.         if(canal<=3)
  21.         {
  22.                 addressWrite=0b10011100;
  23.                 addressRead=0b10011101;
  24.                
  25.                 switch(canal)
  26.                 {
  27.                         case 0: control=0b01000001;             // Para leer el canal 0 hay que indicar que leemos queremos leer el 1          
  28.                                         break;
  29.                        
  30.                         case 1: control=0b01000010;             // Para leer el canal 0 hay que indicar que leemos queremos leer el 2          
  31.                                         break;
  32.                        
  33.                         case 2: control=0b01000011;             // Para leer el canal 0 hay que indicar que leemos queremos leer el 3
  34.                                         break;
  35.                        
  36.                         case 3: control=0b01000000;             // Para leer el canal 0 hay que indicar que leemos queremos leer el 0
  37.                                         break;                 
  38.                 }
  39.                
  40.                 i2c_start();                           
  41.                 i2c_write(addressWrite);        // Byte de dirección. Modo Escritura, nodo 6.
  42.                 i2c_write(control);             // Byte de control.
  43.                 i2c_write(0);                   // Dato salida analógica.
  44.                 i2c_stop();
  45.                
  46.                 i2c_start();
  47.                 i2c_write(addressRead);         // Modo Lectura Nodo 6
  48.                 lectura=i2c_read(0);            // Lectura de datos.
  49.                 i2c_stop();                                     // Detengo comunicacion I2C
  50.                
  51.         }
  52.         else
  53.                 lectura=0;
  54.        
  55.         return lectura;
  56.        
  57. }
  58.  
  59.  
  60. // Funcion que ejecuta la Lectura y Escritura sobre el módulo PCF8591P
  61. int rwPCF8591P(int canal, int write)
  62. {
  63.         int lectura,control,addressWrite,addressRead;
  64.        
  65.         if(canal<=3)
  66.         {
  67.                 addressWrite=0b10011100;
  68.                 addressRead=0b10011101;
  69.                
  70.                 switch(canal)
  71.                 {
  72.                         case 0: control=0b01000001;             // Para leer el canal 0 hay que indicar que leemos queremos leer el 1          
  73.                                         break;
  74.                        
  75.                         case 1: control=0b01000010;             // Para leer el canal 0 hay que indicar que leemos queremos leer el 2          
  76.                                         break;
  77.                        
  78.                         case 2: control=0b01000011;             // Para leer el canal 0 hay que indicar que leemos queremos leer el 3
  79.                                         break;
  80.                        
  81.                         case 3: control=0b01000000;             // Para leer el canal 0 hay que indicar que leemos queremos leer el 0
  82.                                         break;                 
  83.                 }
  84.                
  85.                 i2c_start();                           
  86.                 i2c_write(addressWrite);        // Byte de dirección. Modo Escritura, nodo 6.
  87.                 i2c_write(control);             // Byte de control.
  88.                 i2c_write(write);                       // Envío el dato de salida analógica
  89.                 i2c_stop();
  90.                
  91.                 i2c_start();
  92.                 i2c_write(addressRead);         // Modo Lectura Nodo 6
  93.                 lectura=i2c_read(0);            // Lectura de datos.
  94.                 i2c_stop();                                     // Detengo comunicacion I2C
  95.                
  96.         }
  97.         else
  98.                 lectura=0;
  99.        
  100.         return lectura;
  101.  
  102. }


Se podría optimizar la función de lectura-escritura aportando como variable para el canal un array y después usar un for recorriendo así los canales...

Lo único que me parece extraño es que para leer el canal 0 haya que indicarle canal 1 y así sucesivamente...  :?, alguién sabe porqué?.

Pues nada más, espero que sea interesante para alguien  ;-).

Salu2!