Autor Tema: Guardar un dato leido por un adc en la eeprom de un 16f876a  (Leído 2503 veces)

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

Desconectado arielmdq

  • PIC16
  • ***
  • Mensajes: 166
Guardar un dato leido por un adc en la eeprom de un 16f876a
« en: 21 de Mayo de 2014, 21:03:05 »
Hola que tal amigos del foro !!! estoy haciendo un programita de prueba en ccs ,muy sencillo , el cual consiste en leer un canal analogico digital (en el cual tengo puesto un potenciometro), y en el momento que yo quiera pulso un boton y guardo el valor leido en la memoria eeprom del pic 16f876a . El problema que tengo es que en la simulacion en proteus, me funciona perfecto, pero cuando lo grabo en el pic solo me lee el valor del adc, pero no me almacena el dato en la memoria ni me lo muestra cuando lo pido.Les adjunto el codigo a ver si me pueden ayudar a encontrar el problema .Saludos !!!! :)
Código: C
  1. #include <16f876a.h>
  2. #device adc =10
  3. #use delay (clock=4M)
  4. #fuses XT,NOWDT,NOPROTECT,NOLVP
  5. #include <lcd.c>
  6. #include <internal_eeprom.c>
  7. #use fast_io(B)
  8. #use fast_io(c)
  9. #use fast_io(a)
  10.  
  11. int16 cursor=0,dato=0;
  12.  
  13.    void main ()
  14.   {
  15.    set_tris_c(0b00011111);
  16.   output_c(0b00000000);
  17. //****************ADC**************************
  18.    setup_adc_ports(AN0_AN1_AN3);//* entradas analogicas*//
  19.    setup_adc (ADC_CLOCK_INTERNAL);
  20.    setup_COUNTERS(RTCC_internal.rtcc_div_8);
  21. //********************************************************
  22.    lcd_init ();
  23.    
  24.    WHILE (1) {
  25.  
  26.       set_adc_channel (0);
  27.       delay_us (20);
  28.       cursor = read_adc ();
  29.  //************************************************************
  30.  
  31.     if (input(pin_c1)==1)
  32.    {    
  33.     lcd_gotoxy(1,1);
  34.    printf(lcd_putc,"Cursor    %lu \n                 " ,cursor);
  35.    }
  36.      
  37.     if (input(pin_c0)==1)
  38.    {
  39.    write_int16_eeprom(0x10,(int16) cursor);// escribe en la memoria
  40.    delay_ms(15);
  41.    }
  42.      if (input(pin_c2)==1)
  43.    {
  44.    dato=read_int16_eeprom(0x10);
  45.    delay_ms(15);
  46.    lcd_gotoxy(1,1);
  47.    printf(lcd_putc,"Dato guardado\n       %lu  ",dato );
  48.    
  49.    }
  50.    }
  51.  
  52.   }
El tiempo es una ilusión ,solo existe el presente................

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Guardar un dato leido por un adc en la eeprom de un 16f876a
« Respuesta #1 en: 21 de Mayo de 2014, 21:09:16 »
¿cómo es el circuito asociado en las entradas C0, C1 y C2?

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re: Guardar un dato leido por un adc en la eeprom de un 16f876a
« Respuesta #2 en: 21 de Mayo de 2014, 22:30:17 »
Hola, algo que siempre recuerdo de mis clases de programacion en la facu es el famoso dicho : "divide y venceras", en este caso seria: "prueba las rutinas por separado".

Desconectado arielmdq

  • PIC16
  • ***
  • Mensajes: 166
Re: Guardar un dato leido por un adc en la eeprom de un 16f876a
« Respuesta #3 en: 22 de Mayo de 2014, 08:21:13 »
Hola amigos , antes que nada gracias por responder , les cuento como es el circuito, en el pin C0 tengo un pulsador y en el pin C1,C2 tengo un dip switch que voy seleccionando de acuerdo con lo que quiero hacer, osea si C1 es =1 leo el valor del cursor , si C2 es =1 veo el dato guardado y con C0 que es el pulsador grabo el dato en la memoria .
Con respecto a "divide y venceras " es lo que empece a hacer, esta es la parte de un programa mas grande, que decidi hacerla aparte hasta que resuelva como se hace. Por que sera que en la simulacion funciona bien y fisicamente no ? Adjunto la libreria que estoy usando a ver si alguien me puede guiar un poco.Muchas gracias !!!
Código: C
  1. ////////////////////////////////////////////////////////////////////////////////
  2. ////                          internal_eeprom.c                             ////
  3. ////                                                                        ////
  4. ////       Utilities to write various data types to internal eeprom         ////
  5. ////////////////////////////////////////////////////////////////////////////////
  6. ////                                                                        ////
  7. ////   void write_int1_eeprom(address, int8 bitPosition, int1 data)         ////
  8. ////     Call to write one bit of data                                      ////
  9. ////                                                                        ////
  10. ////   int1 read_int1_eeprom(address, int8 bitPosition)                     ////
  11. ////     Call to read one bit of data                                       ////
  12. ////                                                                        ////
  13. ////                                                                        ////
  14. ////   void write_int16_eeprom(address, int16 data)                         ////
  15. ////     Call to write a 16 bit integer                                     ////
  16. ////                                                                        ////
  17. ////   void read_int16_eeprom(address, int16 data)                         ////
  18. ////     Call to read a 16 bit integer                                      ////
  19. ////                                                                        ////
  20. ////                                                                        ////
  21. ////   void write_int32_eeprom(address, int32 data)                         ////
  22. ////     Call to write a 32 bit integer                                     ////
  23. ////                                                                        ////
  24. ////   int16 read_int32_eeprom(address)                                     ////
  25. ////     Call to read a 32 bit integer                                      ////
  26. ////                                                                        ////
  27. ////                                                                        ////
  28. ////   void write_float_eeprom(address, float data)                         ////
  29. ////     Call to write a floating point number                              ////
  30. ////                                                                        ////
  31. ////   float read_float_eeprom(address)                                     ////
  32. ////     Call to read a floating point number                               ////
  33. ////                                                                        ////
  34. ////////////////////////////////////////////////////////////////////////////////
  35. ////        (C) Copyright 1996, 2004 Custom Computer Services               ////
  36. //// This source code may only be used by licensed users of the CCS C       ////
  37. //// compiler.  This source code may only be distributed to other licensed  ////
  38. //// users of the CCS C compiler.  No other use, reproduction or            ////
  39. //// distribution is permitted without written permission. Derivative       ////
  40. //// programs created using this software in object code form are not       ////
  41. //// restricted in any way.                                                 ////
  42. ////////////////////////////////////////////////////////////////////////////////
  43.  
  44.  
  45. #ifndef INTERNAL_EEPROM_UTILITIES
  46. #define INTERNAL_EEPROM_UTILITIES
  47.  
  48. // Used to adjust the address range
  49. #ifndef INT_EEPROM_ADDRESS
  50. #define INT_EEPROM_ADDRESS  int8
  51. #endif
  52.  
  53. ////////////////////////////////////////////////////////////////////////////////
  54. //// Internal EEPROM Functions
  55. ////////////////////////////////////////////////////////////////////////////////
  56.  
  57. // Purpose:    Write one bit to internal eeprom
  58. // Inputs:     1) An eeprom address
  59. //             2) The bit position (LSB == 0)
  60. //             3) The bit to write
  61. // Outputs:    None
  62. void write_int1_eeprom(INT_EEPROM_ADDRESS address, int8 bitPosition, int1 data)
  63. {
  64.    int8 stored_data;
  65.  
  66.    stored_data = read_eeprom(address);
  67.  
  68.    if(data)
  69.    {
  70.       bit_set(stored_data, bitPosition);
  71.    }
  72.    else
  73.    {
  74.       bit_clear(stored_data, bitPosition);
  75.    }
  76.  
  77.    write_eeprom(address, stored_data);
  78. }
  79.  
  80.  
  81. // Purpose:    Read one bit from internal eeprom
  82. // Inputs:     1) An eeprom address
  83. //             2) The bit position (LSB == 0)
  84. // Outputs:    The bit read from internal eeprom
  85. int1 read_int1_eeprom(INT_EEPROM_ADDRESS address, int8 bitPosition)
  86. {
  87.    return bit_test(read_eeprom(address), bitPosition);
  88. }
  89.  
  90.  
  91. // Purpose:    Write a 16 bit number to internal eeprom
  92. // Inputs:     1) An eeprom address
  93. //             2) The 16 bit number to write to internal eeprom
  94. // Outputs:    None
  95. void write_int16_eeprom(INT_EEPROM_ADDRESS address, int16 data)
  96. {
  97.    int8 i;
  98.  
  99.    for(i = 0; i < 2; ++i)
  100.    {
  101.      write_eeprom(address + i, *((int8 *)(&data) + i));
  102.    }
  103. }
  104.  
  105.  
  106. // Purpose:    Read a 16 bit number from internal eeprom
  107. // Inputs:     An eeprom address
  108. // Outputs:    The 16 bit number read from internal eeprom
  109. int16 read_int16_eeprom(INT_EEPROM_ADDRESS address)
  110. {
  111.    int8  i;
  112.    int16 data;
  113.  
  114.    for(i = 0; i < 2; ++i)
  115.    {
  116.      *((int8 *)(&data) + i) = read_eeprom(address + i);
  117.    }
  118.  
  119.    return(data);
  120. }
  121.  
  122.  
  123. // Purpose:    Write a 32 bit integer to internal eeprom
  124. // Inputs:     1) An eeprom address
  125. //             2) The 32 bit number to write to internal eeprom
  126. // Outputs:    None
  127. void write_int32_eeprom(INT_EEPROM_ADDRESS address, int32 data)
  128. {
  129.    int8 i;
  130.  
  131.    for(i = 0; i < 4; ++i)
  132.    {
  133.      write_eeprom(address + i, *((int8 *)(&data) + i));
  134.    }
  135. }
  136.  
  137.  
  138. // Purpose:    Read a 32 bit integer from internal eeprom
  139. // Inputs:     An eeprom address
  140. // Outputs:    The 32 bit integer read from internal eeprom
  141. int32 read_int32_eeprom(INT_EEPROM_ADDRESS address)
  142. {
  143.    int8  i;
  144.    int32 data;
  145.  
  146.    for(i = 0; i < 4; ++i)
  147.    {
  148.      *((int8 *)(&data) + i) = read_eeprom(address + i);
  149.    }
  150.  
  151.    return data;
  152. }
  153.  
  154.  
  155. // Purpose:    Write a floating point number to internal eeprom
  156. // Inputs:     1) An eeprom address. Four eeprom locations will be used.
  157. //             2) The floating point number to write to internal eeprom
  158. // Outputs:    None
  159. void write_float_eeprom(INT_EEPROM_ADDRESS address, float data)
  160. {
  161.    int8 i;
  162.  
  163.    for(i = 0; i < 4; ++i)
  164.    {
  165.      write_eeprom(address + i, *((int8 *)(&data) + i));
  166.    }
  167. }
  168.  
  169.  
  170. // Purpose:    Read a floating point number from internal eeprom
  171. // Inputs:     An eeprom address
  172. // Outputs:    The floating point number read from the internal eeprom
  173. float read_float_eeprom(INT_EEPROM_ADDRESS address)
  174. {
  175.    int8 i;
  176.    float data;
  177.  
  178.    for(i = 0; i < 4; ++i)
  179.    {
  180.      *((int8 *)(&data) + i) = read_eeprom(address + i);
  181.    }
  182.  
  183.    return data;
  184. }
  185.  
  186. #endif
El tiempo es una ilusión ,solo existe el presente................

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Guardar un dato leido por un adc en la eeprom de un 16f876a
« Respuesta #4 en: 22 de Mayo de 2014, 15:30:07 »
Hola amigos , antes que nada gracias por responder , les cuento como es el circuito, en el pin C0 tengo un pulsador y en el pin C1,C2 tengo un dip switch que voy seleccionando de acuerdo con lo que quiero hacer, osea si C1 es =1 leo el valor del cursor , si C2 es =1 veo el dato guardado y con C0 que es el pulsador grabo el dato en la memoria .
..

solo eso? no tienes implementado un circuito antiretardo para los switches?
« Última modificación: 22 de Mayo de 2014, 15:35:44 por PalitroqueZ »
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado arielmdq

  • PIC16
  • ***
  • Mensajes: 166
Re: Guardar un dato leido por un adc en la eeprom de un 16f876a
« Respuesta #5 en: 22 de Mayo de 2014, 17:33:48 »
Circuito antiretardo ??  No . no sabia eso , me podes explicar un poco o darme un ejemplo de como seria por favor  , te lo agradeceria muchisimo .
El tiempo es una ilusión ,solo existe el presente................

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Guardar un dato leido por un adc en la eeprom de un 16f876a
« Respuesta #6 en: 22 de Mayo de 2014, 20:05:35 »
Hola arielmdq

cometí un error al escribir antiretardo, cuando quería decir antirebote

es antirebote a lo que me refería  :D

un circuito antirebote se utiliza para minimizar los transitorios ocasionados por oscilaciones de muy corto tiempo, tanto que el pic podría ser mas rapido y leer varias de estas oscilaciones como cambios de estado en el switch o pulsador.

para evitar este "problema mecanico" se utilizan los retardos antirebotes por hardware o por software.

los de hardware utilizan un condensador y una resistencia, y los que se hacen por software, realizan varias preguntas en la entrada con retardos de por medio para garantizar la condición de la pulsación.

si colocaste los switches directamente en la entrada, es probable que el pic lea las oscilaciones y ejecute las 2 condiciones de entrada para C0,C1 y C2 de forma "aleatoria"

una forma de implementar un retardo antirebotes por software sería:

#define switche1 PIN_A1
...
   if(switche1){
      delay_ms(iRetardoAntirebote); // ~10-20ms
      if(switche1){
         ...
      }
   }


La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado arielmdq

  • PIC16
  • ***
  • Mensajes: 166
Re: Guardar un dato leido por un adc en la eeprom de un 16f876a
« Respuesta #7 en: 23 de Mayo de 2014, 08:19:33 »
Aaaa ahora si , ja ja , aunque soy principiante, si lo conocia , pero no se los puse ja ja .Te agradezco mucho tu respuesta , lo voy a hacer y despues te cuento .
Saludos !!! ;-)
El tiempo es una ilusión ,solo existe el presente................


 

anything