Autor Tema: Precedencia de operadores a través de punteros - un error aprovechable  (Leído 2596 veces)

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

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
por raro que suene y sin querer queriendo, escribí un código que hace exactamente lo que quería.

Se trata de almacenar numeros de 2 bytes de longitud en la memoria Eeprom de un 16F877.

La función write_eeprom del ccs guarda los datos de 1 byte por vez, analicemos este código:

Código: C
  1. int16 lPepe[2];
  2. ...
  3. #zero_ram
  4. void main(){
  5.    disable_interrupts(GLOBAL);
  6.    lPepe[0]=0xBECA;
  7.    lPepe[1]=0x1984;
  8.    vGrabar_Trama_Eeprom(lPepe);
  9.    bLeer_Trama_Eeprom(1);
  10. }
  11.  
  12. void vGrabar_Trama_Eeprom(int8 *tiempos){
  13.    int8 iConta;
  14.    for(iConta=1;iConta<5;iConta++){
  15.       write_eeprom(iConta, *tiempos++);
  16.    }
  17. }
  18. ...

a primera vista pareciera que el puntero hace un casteo de datos con lPepe, pero no es así.

tiempos es un puntero que guarda la dirección de lPepe, supongamos que lPepe se guarda en la posición 0x20 de la RAM

entonces:

 lPepe[0] está en la dirección 0x20
 lPepe[1] está en la dirección 0x22

 al llamar
 
 vGrabar_Trama_Eeprom(lPepe);
 
 estamos haciendo tiempos apunte a 0x20
 
 ahora al escribir *tiempos++ dentro de write_eeprom en el bucle for, estamos haciendo:
 
 0x20 + 1
 0x20 + 2
 0x20 + 3
 0x20 + 4
 
esto desde el punto de vista de punteros está mal porque estamos truncando el contenido de la dirección exactamente a la mitad.

recuerden que el puntero se incrementa en el ancho del tipo de datos, esto es el puntero debe ser del mismo tipo de datos que el array. Lo correcto es hacer *(tiempos++) -la suma viene primero antes que el puntero-

pero este es un caso especial en donde la excepción a la regla es benéfica, porque el hecho de que se trunque el dato a la mitad sirve justamente para guardar un dato de 2 byte a través de un direccionamiento de 1 byte

¡Estupendijirijillo!



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

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7918
Re: Precedencia de operadores a través de punteros - un error aprovechable
« Respuesta #1 en: 01 de Septiembre de 2009, 08:47:36 »
Pero es que no hace nada raro!!
Cada uno de los dos INT16 llamados IPepe, ocupa dos bytes consecutivos en RAM, lo unico que no sabes es donde los ubica el compilador hasta despues de compilar (salvo que indiques especificamente la direccion inicial del primer INT16).
Luego como el puntero tiene pasado la direccion del primer byte, graba los 4 bytes consecutivos, lo que hace que escriba como tu quieres.

El unico problema que veo es cuando cambies de un 877 a un PIC de la linea 18F donde el direccionamiento es de 16bits, pero habria que probarlo... :mrgreen:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Precedencia de operadores a través de punteros - un error aprovechable
« Respuesta #2 en: 01 de Septiembre de 2009, 21:30:22 »
jeje ya dejó de ser raro, son uno de esos códigos que generar ciertas ??? al mirarlo con otra cara

mudarlo a los 18F, definitivamente nop  :)

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