Autor Tema: Problemas escritura memoria Programa!!  (Leído 2844 veces)

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

Desconectado BAFAN

  • PIC10
  • *
  • Mensajes: 19
Problemas escritura memoria Programa!!
« en: 09 de Enero de 2006, 04:22:00 »
Buenas.. miren tengo un Pic18f4550 y estoy utilizando la sentencia write_program_eeprom, y me he dado cuenta d dos cosas, primera que la separacion entre dos posiciones es d 2bytes  y que si escribo dos veces sobre la misma posicion la segunda vez escribe mal y no se pq.... si alguien me puede explicar mas cosas sobre esta instruccion se lo agradeceria pq tengo un kebradero d cabeza impresionante... dado q kiero escribir mas d una vez...
Gracias d antemano!! Giño

Desconectado BAFAN

  • PIC10
  • *
  • Mensajes: 19
RE: Problemas escritura memoria Programa!!
« Respuesta #1 en: 09 de Enero de 2006, 04:38:00 »
Ya me he solucionao el problema hay q borrar cada vez q hay q escribir... usando la instruccion ERASE_PROGRAM_EEPROM (address) , y parece q ya va todo sobre ruedas.. jeje Rebotado

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Problemas escritura memoria Programa!!
« Respuesta #2 en: 13 de Mayo de 2010, 18:28:07 »
Esto de la escritura en flash eeprom requiere de atención y cuidado.

Cuando se usa write_program_eeprom() por primera vez al recién grabar el pic, el dato se guarda correctamente, pero la segunda vez ya no. Como comentó Bafan, es necesario borrar la flash eeprom para volverla a grabar.

Para eso existe erase_program_eeprom() pero tiene la peculiaridad de que no borra una sola localidad, borra todo un bloque. Este bloque depende del modelo de pic que se esté usando. Puede ser de 64 bytes por ejemplo. Así que si queremos grabar un sólo byte hay que respaldar todos los demás que deben quedar intactos y luego borrarlos. Una vez borrados se graba el byte nuevo y los bytes viejos todo un bloque.

Lo ideal es usar write_program_memory() ya que borra y graba bloques en una sola instrucción. También es recomendable grabar datos con tamaño idéntico a un bloque.

La dirección en la que comienza el bloque debe ser múltiplo del tamaño del bloque. Por ejemplo, si el bloque mide 64 bytes, no es recomendable iniciar una grabación en 0x3F (63), es mejor iniciar en 0x40 (64).

En sí, esto es un resumen de lo que la ayuda de CCS explica. Existen varios temas al respecto en el foro y todo esto es una síntesis de ellos.

Código: [Seleccionar]
The flash program memory is readable and writable in some chips and is just readable in some. These options lets the user read and write to the flash program memory. These functions are only available in flash chips.

 

Relevant Functions:
  
 
read_program_eeprom

(address)
 Reads the program memory location(16 bit or 32 bit depending on the device).

 
 
write_program_eeprom

(address, value)
  Writes value to program memory location address.

 
 
erase_program_eeprom

(address)
 Erases FLASH_ERASE_SIZE bytes in program memory.

 
 
write_program_memory

address,dataptr,count)
 Writes count bytes to program memory from dataptr to address. When address is a mutiple of FLASH_ERASE_SIZE an erase is also performed.

 
 
read_program_memory

(address,dataptr,count)

 
 Read count bytes from program memory at address to dataptr.
 
Relevant Preprocessor:
  
 
#ROM address={list}
 Can be used to put program memory data into the hex file.

 
 
#DEVICE(WRITE_EEPROM=ASYNC)
 Can be used with #DEVICE to prevent the write function from hanging. When this is used make sure the eeprom is not written both inside and outside the ISR.

 
 
Relevant Interrupts:
  
 
INT_EEPROM
 Interrupt fires when eeprom write is complete.

 
 
Relevant Include Files:
  
 
None, all functions built-in

 
  
 
Relevant getenv() parameters
  
 
PROGRAM_MEMORY
 Size of program memory
 
READ_PROGRAM
 Returns 1 if program memory can be read
 
FLASH_WRITE_SIZE
 Smallest number of bytes written in flash
 
FLASH_ERASE_SIZE
 Smallest number of bytes erased in flash

 
 
Example Code:
  
 
For 18F452 where the write size is 8 bytes and erase size is 64 bytes
 
#rom 0xa00={1,2,3,4,5}
  //inserts this data into the hex file.
 
erase_program_eeprom(0x1000);
 //erases 64 bytes strting at 0x1000
 
write_program_eeprom(0x1000,0x1234);
 //writes 0x1234 to 0x1000
 
value=read_program_eeprom(0x1000);
 //reads 0x1000 returns 0x1234
 
write_program_memory(0x1000,data,8);
 //erases 64 bytes starting at 0x1000 as 0x1000 is a multiple
 
 
 //of 64 and writes 8 bytes from data to 0x1000
 
read_program_memory(0x1000,value,8);
 //reads 8 bytes to value from 0x1000
 
erase_program_eeprom(0x1000);
 //erases 64 bytes starting at 0x1000
 
write_program_memory(0x1010,data,8);
  //writes 8 bytes from data to 0x1000
 
 read_program_memory(0x1000,value,8);
 //reads 8 bytes to value from 0x1000

 
 
For chips where getenv("FLASH_ERASE_SIZE") > getenv("FLASH_WRITE_SIZE")
 
     WRITE_PROGRAM_EEPROM -
 Writes 2 bytes,does not erase (use ERASE_PROGRAM_EEPROM)
 
     WRITE_PROGRAM_MEMORY -            
 Writes any number of bytes,will erase a block whenever the first (lowest) byte in a block is written to.  If the first address is not the start of a block that block is not erased.
 
     ERASE_PROGRAM_EEPROM -
 Will erase a block.  The lowest address bits are not used.

 
 
For chips where getenv("FLASH_ERASE_SIZE") = getenv("FLASH_WRITE_SIZE")
 
WRITE_PROGRAM_EEPROM -
 Writes 2 bytes, no erase is needed.
 
 WRITE_PROGRAM_MEMORY -
 Writes any number of bytes, bytes outside the range of the write block are not changed.  No erase is needed.
 
ERASE_PROGRAM_EEPROM -
 Not available.

 

« Última modificación: 13 de Mayo de 2010, 18:36:08 por migsantiago »

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Problemas escritura memoria Programa!!
« Respuesta #3 en: 13 de Mayo de 2010, 19:02:03 »
Un ejemplo para que no se me olvide lo que quise decir arriba.

Se guardarán 2 arreglos de 60 bytes en la flash eeprom, 120 bytes totales.

El número 60 no es múltiplo de 64, por lo que mejor reservamos espacio de 2 arreglos de 64 bytes. Son 128 bytes en total, pero cada 2 localidades guardan 1 solo byte por lo que hay que reservar el doble de espacio, 256 localidades.

Código: [Seleccionar]
//Reserva espacio en la FLASH EEPROM para almacenar los 120bytes del programa 3
#ORG 0x1C00, 0x1CFF {} //256 bytes a reservar por asunto de tamaño de bloques

Una vez que CCS dejará intacta tal zona de la FLASH EEPROM sólo basta rellenarla a placer. El buffer 1 estará guardado desde la dirección 0x1C00 y el 2 desde la dirección 0x1C80.

Código: [Seleccionar]
     write_program_memory(0x1C00, buffer1, 60); //buffer1 es un int8[]
      write_program_memory(0x1C80, buffer2, 60); //buffer2 es un int8[]

Se desperdician 4 bytes por operación pero de tal forma no se traslapan los arreglos y no se pierden bytes. Una vez guardados se recuperan fácilmente.

Código: [Seleccionar]
     read_program_memory(0x1C00, buffer1, 60);
      read_program_memory(0x1C80, buffer2, 60);

Ahora sí, a ahorrar 24LCXX se ha dicho  :D

Lo anterior funciona OK en un PIC18F2550.
« Última modificación: 13 de Mayo de 2010, 19:29:02 por migsantiago »

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Problemas escritura memoria Programa!!
« Respuesta #4 en: 14 de Mayo de 2010, 01:49:53 »
Interesante explicación, Santiago. Gracias

Desconectado turantus

  • PIC10
  • *
  • Mensajes: 1
Re: Problemas escritura memoria Programa!!
« Respuesta #5 en: 07 de Julio de 2010, 14:39:48 »
Hola, me ha sido muy útil la explicación, muchas gracias Santiago.

Estoy haciendo pruebas antes de implementarlo en mi proyecto. Y me he encontrado con un problemilla.

Para leer y escribir la flash utilizo los program_memory:

write_program_memory(direccion, buffer1,10);                 //buffer1 es un char[10]
read_program_memory(direccion, LECTURAbuffer,10);

Escribo en 9 bloques, desperdiciando mucho espacio, porque prefiero tenerlos separados.

0x8000=1E1E2E3E4
0x8080=2E1E2E3E4
0x8100=3E1E2E3E4
0x8180=4E1E2E3E4
0x8200=5E1E2E3E4
0x8280=6E1E2E3E4
0x8300=7E1E2E3E4
0x8380=8E1E2E3E4
0x8400=9E1E2E3E4


Todo se escribe y se lee sin problemas. 


Cuando reseteo el Pic y vuelve a correr el programa, al hacer la primera lectura todos los datos están en su sitio.
Pero al escribir de nuevo en 0x8000, me borra todos los siguientes bloques, dejando solamente el 0x8400.

¿No debería borrar solo el bloque que le mando escribir ?

Bueno espero haberme explicado en condiciones. 

Un saludo a todos y muchas gracias por este foro!

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Problemas escritura memoria Programa!!
« Respuesta #6 en: 07 de Julio de 2010, 14:46:28 »
Hola, yo checaría que todos los configuration bits (fuse) estén permitiendo la escritura/lectura de las secciones de PROGRAM ROM que elegiste. Después checaría la subrutina de código que estás usando, puede que por un errorcillo en el código se esté grabando una sección más de ROM (un ciclo for talvez).

A raíz de más práctica con estas funciones detecté que no hace falta apartar el doble de espacio para 1 byte, en una sóla dirección ROM se pueden grabar 2 bytes. Pero de todas formas el código debe funcionar.