Autor Tema: Duda sobre I2C  (Leído 1605 veces)

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

Desconectado yeestrada

  • PIC10
  • *
  • Mensajes: 15
Duda sobre I2C
« en: 27 de Abril de 2011, 12:43:48 »
tengo una duda, estoy tratando de guardar los valores que obtengo del conversor ad en una memoria eeprom externa, pero no se si voy por buen camino, estoy usando ua memoria 24lc256:

#include <16F877A.h>                ///   libreria para el manejo del pic16f877a
#device ADC=10
#include <stdlib.h>
#include "24256.c"
#priority rda,ad,timer1,timer0
#use delay(clock=20000000)          ///   declara  la frecuencia del cristal 20mhz
#use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)

#use fast_io(A)
#use fast_io(B)
#use fast_io(C)                     ///   con esta instruccion evitamos que
#use fast_io(D)                     ///   se este configurando cada vez que usamos
#use fast_io(E)                     ///   alguna instruccion de entrada o salida

#byte porta = 5
#byte portb = 6
#byte portc = 7                     /// se definen direcciones de memoria
#byte portd = 8
#byte porte = 9

#define EEPROM_SDA PIN_c4
#define EEPROM_SCL PIN_c3

   int nums[7];
   int temporal;
   int cont_letras;                    //variable para contar los 8 numeros que se puede entrar por Tx serie
   int16 time;                           //hasta 300 segundos entre recuperaciones de muestras
   int16 cant_var;                       //hasta 2000 muestras que es necesario recojer
   int cont_seg;
   int16 cont_time;
   int16 cont_var;
   int estado_leds;
   int var_in_rand;
   int16 lectura_ad;
   int canal_ad;

int Tabla(int a)        //tabla para visualizar numeros por el 7segmentos
{
  switch(a)
  {
      CASE 0:RETURN 0b00111111;
      CASE 1:RETURN 0B00000110;
      CASE 2:RETURN 0B01011011;
      CASE 3:RETURN 0B01001111;
      CASE 4:RETURN 0B01100110;
      CASE 5:RETURN 0B01101101;
      CASE 6:RETURN 0B01111101;
      CASE 7:RETURN 0B00000111;
      CASE 8:RETURN 0B01111111;
      CASE 9:RETURN 0B01100111;
  }
}

int Is_num(int a)
{
   if(a>=48 && a<=57)
    return 0;                          //si es 0 es un numero sino es otro
   return 1;
}

void actualiza_led(int i)
{
   switch(i)
   {
   case 0: portb= 0B11111110;         //PC
           portd= 0B01110011;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B00111001;
           break;
   case 1: portb= 0B11111110;         //Ad
           portd= 0B01110111;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B01011110;
           break;
   case 2: portb= 0B11111110;         //Sd
           portd= 0B01101101;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B01011110;
           break;
   }
}


#use delay(clock=20000000)

void LeerAD(int canal)
{
   lectura_ad = 0;
   setup_port_a( ALL_ANALOG );
   setup_adc( ADC_CLOCK_INTERNAL );
   set_adc_channel(canal);
   lectura_ad = read_adc();
   delay_ms(20);
   setup_adc (adc_off);

}



#int_TIMER0                         //directiva para it del timer0
void TIMER0_isr()
{
    actualiza_led(estado_leds);
    set_timer0(81);
}

#int_TIMER1                         //directiva para it del timer0
void TIMER1_isr()
{
   if(cont_seg > 9)
   {
      cont_seg = 0;
      if(cont_time < time)
         cont_time++;
      else
      {
         cont_time = 0;
         canal_ad = 0;
         while (canal_ad>Cool
         {
         LeerAD(canal_ad);
         write_ext_eeprom(_mul(cont_var,2),lectura_ad);
         canal_ad++;
         }
      }
   }
   cont_seg++;
   set_timer1(3063);
}

#int_rda
void rda_isr()
{
   if(cont_letras < 7)
   {
      temporal = getc();
      if(Is_num(temporal)==0)
      {
         temporal =temporal-48;
         nums[cont_letras] = temporal;
         printf ("%d",nums[cont_letras]);
         cont_letras++;
      }
      else
      {
         cont_letras = 0;
         printf ("Error");
      }
   }
}


void configurar(void)                  //configuraciones
{
   enable_interrupts(INT_TIMER0);         //habilitar el timer0
   enable_interrupts(INT_TIMER1);         //habilitar el timer1
   enable_interrupts(INT_RDA);            //habilitar para comunicación serie
   enable_interrupts(GLOBAL);             //habilitar el bit de it global

   set_tris_d(0x00);
   set_tris_b(0x00);
}


void main()
{
   cont_seg = 0;
   estado_leds = 0;
   cont_letras = 0;
   var_in_rand = 0;
   cont_time = 0;
   canal_ad = 0;
   configurar();
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
   set_timer0(81);
   while(var_in_rand == 0)
   {
      while(cont_letras < 7){}
      cant_var = _mul(nums[0],1000) + _mul(nums[1],100) + _mul(nums[2],10) + nums[3];
      time = _mul(nums[4],100) + _mul(nums[5],10) + nums[6];
      var_in_rand = 1;
      if(time>300 || time<1)
      {
         printf (" Tiempo fuera de rango. ");
         cont_letras = 0;
         var_in_rand = 0;
      }
     else
      if(cant_var>2000)
      {
         printf (" Cantidad de muestras fuera de rango. ");
         cont_letras = 0;
         var_in_rand = 0;
      }
   }
   clear_interrupt(int_rda);
   estado_leds = 1;
   init_ext_eeprom();
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   set_timer1(3063);
   while(1){}


}

Desconectado Alcaparrones

  • PIC10
  • *
  • Mensajes: 17
Re: Duda sobre I2C
« Respuesta #1 en: 01 de Mayo de 2011, 07:21:34 »
Buenas

A ver si te puedo echar una manita. No he leido el código entero, lo siento, pero supongo que para empezar te compila.

He visto que llamas a la función configurar(), donde hablitas el timer0 que a su vez usa la función write_ext_eeprom() antes de llamar a init_ext_eeprom(), debes situar este init antes de configurar(). Por otro lado no usas read_ext_eeprom(), supongo que aún no lo has implementado.

Por lo demás, creo que el programa es demasiado "ambicioso" para no saber si haces bien la lectura-escritura de datos. Antes que un program tan complejo yo haría uno más modesto usando solo el rs232 para visualizar datos en vez de un 7 segmentos y comandos por rs232 para desencadenar los eventos de escritura-lectura en vez de timers, para asegurarte con calma que todo va bien. Usar un simulador para esto te ahorrará muchísimos quebraderos de cabeza delante de la protoplaca.

Y otra cosa, la herramienta "buscar" puede ahorrarte más de un quebradero de cabeza... por ejemplo: http://todopic.mforos.com/46840/3170676-problema-al-leer-una-24lc256-con-ccs-por-hardware/

Un saludo y suerte, al final todo se consigue!  8)

Desconectado yeestrada

  • PIC10
  • *
  • Mensajes: 15
Re: Duda sobre I2C
« Respuesta #2 en: 02 de Mayo de 2011, 12:10:39 »
Hola, te agradezco la ayuda, aunque ese codigo es viejo, el timer que activo es el timer0 que se encarga de actualizar el 7segmentos, ya tengo un codigo mejo implementado, pero aun solo me muestra la primera lectura, pues el resto solo me muestra ff, no tengo ni idea de por que....


#include <16F877A.h>                ///   libreria para el manejo del pic16f877a
#device ADC=10 ICD=TRUE
#include <stdlib.h>

#define EEPROM_SDA PIN_c4
#define EEPROM_SCL PIN_c3

#include "24256.c"
#include "external_eeprom.c"
#priority rda,ad,timer1,timer0
#use delay(clock=20000000)          ///   declara  la frecuencia del cristal 20mhz
#use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)

#FUSES NOWDT                        //No Watch Dog Timer
#FUSES HS                           //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOBROWNOUT                   //No brownout reset
#FUSES NOLVP                        //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use fast_io(A)
#use fast_io(B)
#use fast_io(C)                     ///   con esta instruccion evitamos que
#use fast_io(D)                     ///   se este configurando cada vez que usamos
#use fast_io(E)                     ///   alguna instruccion de entrada o salida

#byte porta = 5
#byte portb = 6
#byte portc = 7                     /// se definen direcciones de memoria
#byte portd = 8
#byte porte = 9

   int nums[7];
   int temporal;
   int cont_letras;                 //variable para contar los 8 numeros que se puede entrar por Tx serie
   int16 time;                      //hasta 300 segundos entre recuperaciones de muestras
   int16 cant_var;                  //hasta 2000 muestras que es necesario recojer
   int cont_seg;
   int16 cont_time;
   int16 cont_var;
   int estado_leds;
   int var_in_rand;
   int16 lectura_ad;
   int canal_ad;
   int tecla_activa;

int Tabla(int a)                    //tabla para visualizar numeros por el 7segmentos
{
  switch(a)
  {
      CASE 0:RETURN 0b00111111;
      CASE 1:RETURN 0B00000110;
      CASE 2:RETURN 0B01011011;
      CASE 3:RETURN 0B01001111;
      CASE 4:RETURN 0B01100110;
      CASE 5:RETURN 0B01101101;
      CASE 6:RETURN 0B01111101;
      CASE 7:RETURN 0B00000111;
      CASE 8:RETURN 0B01111111;
      CASE 9:RETURN 0B01100111;
  }
}

int Is_num(int a)
{
   if(a>=48 && a<=57)
    return 0;                        //si es 0 es un numero sino es otro
   return 1;
}

void actualiza_led(int i)
{
   switch(i)
   {
   case 0: portb= 0B11111110;         //PC
           portd= 0B01110011;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B00111001;
           break;
   case 1: portb= 0B11111110;         //Ad
           portd= 0B01110111;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B01011110;
           break;
   case 2: portb= 0B11111110;         //Sd
           portd= 0B01101101;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B01011110;
           break;
   }
}


#use delay(clock=20000000)

void LeerAD(int canal)
{
   lectura_ad = 0;
   set_adc_channel(canal);
   lectura_ad = read_adc();
}



#int_TIMER0                            //directiva para it del timer0
void TIMER0_isr()
{
    actualiza_led(estado_leds);
    set_timer0(81);
}

#use delay(clock=20000000)

#int_TIMER1                            //directiva para it del timer0
void TIMER1_isr()
{
  if(cont_seg > 9)
  {
    cont_seg = 0;
    if(cont_time < time)
     cont_time++;
    else
     temporal =1;
   }
   cont_seg++;
   set_timer1(3063);
}

#int_rda
void rda_isr()
{
   disable_interrupts(int_rda);
   tecla_activa=1;
}


void configurar(void)                     //configuraciones
{
   enable_interrupts(INT_TIMER0);         //habilitar el timer0
   enable_interrupts(INT_TIMER1);         //habilitar el timer1
   enable_interrupts(INT_RDA);            //habilitar para comunicación serie
   enable_interrupts(GLOBAL);             //habilitar el bit de it global
   setup_adc_ports( ALL_ANALOG );
   setup_adc( ADC_CLOCK_INTERNAL );
   set_tris_d(0x00);
   set_tris_b(0x00);
}

#use delay(clock=20000000)

void main()
{
while(1)
{
      cont_seg = 0;
      estado_leds = 0;
      cont_letras = 0;
      var_in_rand = 0;
      cont_time = 1;
      tecla_activa = 0;
      canal_ad = 0;
      cont_var = 0;
      configurar();
      setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
      set_timer0(81);

      while(var_in_rand == 0)
      {
         while(cont_letras < 7)
         {
            if(tecla_activa ==1)
            {
               temporal = getc();
               if(Is_num(temporal)==0)
               {
                  temporal =temporal-48;
                  nums[cont_letras] = temporal;
                  printf ("%d",nums[cont_letras]);
                  cont_letras++;
               }
               else
               {
                  cont_letras = 0;
                  printf ("Error");
               }
               
               enable_interrupts(int_rda);
               tecla_activa = 0;
               
   }

         }
         cant_var = _mul(nums[0],1000) + _mul(nums[1],100) + _mul(nums[2],10) + nums[3];
         time = _mul(nums[4],100) + _mul(nums[5],10) + nums[6];
         var_in_rand = 1;
         if(time>300 || time<1)
         {
            printf (" Tiempo fuera de rango. ");
            cont_letras = 0;
            var_in_rand = 0;
         }
      else
         if(cant_var>2000)
         {
            printf (" Cantidad de muestras fuera de rango. ");
            cont_letras = 0;
            var_in_rand = 0;
         }
      }
      estado_leds = 1;
      setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
      set_timer1(3063);
      init_ext_eeprom();
      while(cont_var<cant_var)
      {
         if(temporal ==1)
         {
            disable_interrupts(int_TIMER1);
            temporal =0;
            cont_time = 1;
            for(canal_ad=0;canal_ad<8;canal_ad++)
            {
               LeerAD(canal_ad);
               write_int16_ext_eeprom(_mul(cont_var+canal_ad,2), lectura_ad);
               delay_ms(20);
            }
            cont_var++;
            enable_interrupts(INT_TIMER1);
         }
      }
      disable_interrupts(int_TIMER1);
      lectura_ad=0;
      estado_leds = 2;
      printf(" Lecturas: ");
      for(cont_var=0; cont_var<_mul(cant_var,16); cont_var+=2)
      {
      lectura_ad = read_int16_ext_eeprom(cont_var);
      printf("%2x ",lectura_ad);
      delay_ms(20);
      }
      printf(" FIN");
   }
}

Desconectado Palomino86

  • PIC16
  • ***
  • Mensajes: 180
Re: Duda sobre I2C
« Respuesta #3 en: 03 de Mayo de 2011, 18:55:46 »
Te dejo una libreria que quizas te sirva, esta hecha en c18 pero es para la misma memoria que estas utilizando. Pruebala haber que tal te funciona


Saludos
Lo que no me destruye, me fortalece