TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Automata78 en 12 de Julio de 2006, 23:16:02

Título: Necesito leer la EEPROM del PIC y guardar en un INT16, como lo hago ?
Publicado por: Automata78 en 12 de Julio de 2006, 23:16:02
   Hola a todos !!
   Les cuento que en mi programa trabajo con variables enteras de 16 bits "int16", y en la inicializacion de mi programa necesito cargarles unos valores que deberian estar almacenados en la eeprom del PIC.
   El problema con el que me encuentro es que la eeprom  almacena un byte por direccion y no una "palabra" de 16 bits asociada a una direccion !
   Como deberia traducir de dos direcciones contiguas de la eeprom ( ej. Var_H y Var_L ) para que esta puedan ser almacenadas en una sola variable del tipo INT16 ?

   Espero haber sido claro, desde ya muchas gracias por sus comentarios !
Título: Re: Necesito leer la EEPROM del PIC y guardar en un INT16, como lo hago ?
Publicado por: maunix en 12 de Julio de 2006, 23:22:49
Puedes definir una union

Código: C
  1. typedef union Tinteger16 {
  2.    struct {
  3.       unsigned int8 byteLow;
  4.       unsigned int8 byteHigh;
  5.    };
  6.    unsigned int16 value;
  7. };

Luego lees cada byte, deberás saber que posición ocupa el ByteLow en la EEPROM y que posición el ByteHigh.  Entonces tu lees el byte Low y lo guardas en el struct en la posición Low,  luego el High y lo guardas en byteHigh y para leer la variable como un solo entero de 16 bits pues tomas el valor de value de la estructura.

Ej.

Código: C
  1. union Tinteger16 mivariable;
  2. unsigned int16 miinteger16;
  3.  
  4. mivariable.bytelow = 0x20;
  5. mivariable.byteHigh = 0x40;
  6. miinteger16 = mivariable.value;

Las codificaciones pueden variar de acuerdo a cada compilador, pero la idea es esa.

Saludos
Título: Re: Necesito leer la EEPROM del PIC y guardar en un INT16, como lo hago ?
Publicado por: RedPic en 13 de Julio de 2006, 09:37:46
Me ha gustado tu pregunta ...  :P

asi que voy a intentar contestartela, a mi modo ...  :mrgreen:

Empezemos por el principio: read_eeprom(address) y write_eeprom(address, byte) trabajan con int8, un byte de 8 bits. Para leer y escribir int16, dos bytes de 8 bits cada uno, hay que fabricarse unas funciones "puente" de este estilo:

Código: C
  1. void write_eeprom_16bits(int address, long* val){
  2.    int pLow, pHigh;
  3.    pLow  = val;
  4.    pHigh = val>>8;
  5.    write_eeprom(address,pHigh);
  6.    delay_ms(12);
  7.    ++address;
  8.    write_eeprom(address,plow);
  9.    delay_ms(12);
  10. }
  11.  
  12. long read_eeprom_16bits(int address){
  13.    int  pLow, pHigh;
  14.    long result;
  15.    pHigh  = read_eeprom(address);
  16.    ++address;
  17.    pLow  = read_eeprom(address);
  18.    result=(pHigh<<8);
  19.    result+=pLow;
  20.    return result;  
  21. }

Con ellas he escrito un programa de Test que en el reset guarda un valor de 16 bits en la variable x, llama a la función write_eeprom_16bits y se queda a la espera "escuchando" la RS232 ...

al recibír la tecla 'r' realiza la funciona inversa, lee sobre la variable y, también de 16 bits, desde la misma dirección en la que antes escribimos con read_eeprom_16bits y monitoriza el resultado.

Todo este recorrido esta salpicado de printf's para poder ver todo el proceso paso a paso:

(http://picmania.garcia-cuervo.com/images/PICC_EEPROM_16Bits_Dump.JPG)

El programa completo tal como quedó para poder monitorizar todos los pasos es:

Código: C
  1. // eeprom_16bits plus rs232
  2. #include <18f4550.h>
  3. #fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN, NOLVP
  4. #use delay(clock=20000000)
  5. #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
  6.  
  7. char Keypress = 0x00;
  8. char Command  = 0x00;
  9.  
  10. long x,y;
  11.  
  12. #int_rda
  13. void serial_isr() {
  14.  
  15.    Keypress=0x00;
  16.    if(kbhit()){
  17.       Keypress=getc();
  18.       if(Keypress!=0x00){
  19.          if(Keypress=='r'){
  20.             Command=Keypress;            
  21.          }    
  22.          putchar(keypress);
  23.          keypress=0x00;
  24.       }
  25.    }
  26. }
  27.  
  28. void write_eeprom_16bits(int address, long* val){
  29.  
  30.    int pLow, pHigh;
  31.    printf("write_eeprom_16bits( address=%u, val=%lx)\r\n",address,val);
  32.    pLow  = val;
  33.    pHigh = val>>8;
  34.    printf("write_eeprom( address=%u, val=%x)\r\n",address,pHigh);
  35.    write_eeprom(address,pHigh);
  36.    delay_ms(12);
  37.    ++address;
  38.    printf("write_eeprom( address=%u, val=%x)\r\n",address,pLow);
  39.    write_eeprom(address,plow);
  40.    delay_ms(12);
  41. }
  42.  
  43. long read_eeprom_16bits(int address){
  44.  
  45.    int  pLow, pHigh;
  46.    long result;
  47.    printf("read_eeprom_16bits( address=%u)\r\n",address);
  48.    pHigh  = read_eeprom(address);
  49.    printf("read_eeprom( address=%u) = %x\r\n",address,pHigh);
  50.    ++address;
  51.    pLow  = read_eeprom(address);
  52.    printf("read_eeprom( address=%u) = %x\r\n",address,pLow);
  53.    result=(pHigh<<8);
  54.    result+=pLow;
  55.    return result;  
  56. }
  57.  
  58.  
  59. void main(){
  60.  
  61.    disable_interrupts(global);
  62.  
  63.    setup_adc_ports(NO_ANALOGS);
  64.    setup_adc(ADC_OFF);
  65.    setup_spi(FALSE);
  66.    setup_psp(PSP_DISABLED);
  67.    setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
  68.    setup_timer_0(RTCC_OFF);
  69.    setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  70.    setup_timer_2(T2_DISABLED,0,1);
  71.    setup_timer_3(T3_DISABLED);
  72.    setup_comparator(NC_NC_NC_NC);
  73.    setup_vref(FALSE);
  74.    port_b_pullups(FALSE);
  75.    set_tris_e(0b00010000);
  76.    set_tris_c(0b10000000);
  77.    
  78.    delay_ms(1000);
  79.  
  80.    output_High(PIN_E0);
  81.    output_High(PIN_E1);
  82.    output_High(PIN_E2);
  83.    printf("\r\n");
  84.    printf("18F4550 in RRBOARAD2\r\n");
  85.    printf("Test EEPROM with 18 bits\r\n\n");
  86.    delay_ms(500);
  87.    output_Low(PIN_E0);
  88.    output_Low(PIN_E1);
  89.    output_Low(PIN_E2);
  90.  
  91.    Command=0x00;
  92.    enable_interrupts(int_rda);
  93.    enable_interrupts(global);
  94.  
  95.    x=0x1f2f;
  96.    y=0;
  97.    
  98.    printf("initial 16 bits x = %lx (%lu), y = %lx (%lu)\r\n",x,x,y,y);
  99.    write_eeprom_16bits(0,x);
  100.    printf("\r\n");
  101.  
  102.    while(TRUE) {
  103.       if(Command=='r'){
  104.          Command=0x00;
  105.          printf("\r\n\n");
  106.          y=read_eeprom_16bits(0);
  107.          printf("final 16 bits x = %lx (%lu), y = %lx (%lu)\r\n",x,x,y,y);
  108.       }
  109.    }
  110. }

Título: Re: Necesito leer la EEPROM del PIC y guardar en un INT16, como lo hago ?
Publicado por: piriots en 14 de Julio de 2006, 07:48:46
El ccs ya incorpora estas funciones en una libreria llamada internal_eeprom.c

Código: [Seleccionar]
void write_int1_eeprom(address, int8 bitPosition, int1 data)         ////
////     Call to write one bit of data                                      ////
////                                                                        ////
////   int1 read_int1_eeprom(address, int8 bitPosition)                     ////
////     Call to read one bit of data                                       ////
////                                                                        ////
////                                                                        ////
////   void write_int16_eeprom(address, int16 data)                         ////
////     Call to write a 16 bit integer                                     ////
////                                                                        ////
////   void write_int16_eeprom(address, int16 data)                         ////
////     Call to read a 16 bit integer                                      ////
////                                                                        ////
////                                                                        ////
////   void write_int32_eeprom(address, int32 data)                         ////
////     Call to write a 32 bit integer                                     ////
////                                                                        ////
////   int16 read_int32_eeprom(address)                                     ////
////     Call to read a 32 bit integer                                      ////
////                                                                        ////
////                                                                        ////
////   void write_float_eeprom(address, float data)                         ////
////     Call to write a floating point number                              ////
////                                                                        ////
////   float read_float_eeprom(address)                                     ////
////     Call to read a floating point number

Título: Re: Necesito leer la EEPROM del PIC y guardar en un INT16, como lo hago ?
Publicado por: jfh900 en 16 de Julio de 2006, 09:27:08
Para unir y separar dos bytes con el CCS se pueden utilizar las funciones make8 y make16. Supongo que las funciones estaran optimizadas, para realizar estas labores.

Un saludo.
Título: Re: Necesito leer la EEPROM del PIC y guardar en un INT16, como lo hago ?
Publicado por: Automata78 en 16 de Julio de 2006, 22:50:54
Hola muchacho !!!
  Les cuento que nunca imagine que existian tantas variantes je je . para realizar esta tarea, me viene barbaro sus ideas !!
  Voy a implementarlas para ver como trabajan !
  Muchas gracias !!!!!
  Voy a estudiar "struct" que nunca lo utilice.

  Nos estamos escribiendo !!!   gracias ! :o