Autor Tema: escribiendo en la memoria de programa  (Leído 452 veces)

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

Desconectado micronet3

  • PIC18
  • ****
  • Mensajes: 276
escribiendo en la memoria de programa
« en: 18 de Enero de 2019, 18:04:21 »
saludos
estoy intentando grabar en la memoria de programa de un pic 18f, pero hasta ahora no puedo escribir
revisando el datashet me sale dos variables o constantes

COUNTER que se carga con el valor de blocksize
y COUNTER2 que se carga con el valor de d'64'/blocksize

a lo que yo interpreto que blocksize es la cantidad de bytes a guardar  y counter en cuantos bloques se va a guardar

les adjunto la imagen a ver que les parece
saludos

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 7294
Re:escribiendo en la memoria de programa
« Respuesta #1 en: 19 de Enero de 2019, 09:07:07 »
No se ve donde se utiliza esos 2 contadores... o se apara QUE los usa...

Para grabar la FLASH no se puede hacer de 1 byte a la ves (la lectura si)...  Sino que debe realizarse en bloques de 64 bytes, es decir SI o SI vas a tener que escribir 64 bytes.
Me explico un poco mas... es posible escribir 1 byte o dos.. Pero igual vas a tener que escribir los otros 64 bytes. Ya que vos escribis con el TABLE WRITE sobre 64 registros "temporales" y luego le realmente grabas la FLASH.

Sin ver el panorama completo, y lo que me mostras en la imagen, Solo puedo suponer que tienen esta utilidad:
El BLOCKSIZE es una constante (EQU ) que define la cantidad de bits a escribir/leer. Esto se deposita en CONTADOR...
Finalmente en CONTADOR2 se deposita la cantidad de bloques de 64 bytes a escribir .


Y lo peor aun... Antes tuviste que borrar 1K de memoria FLASH.. Así que si queres solo modificar un pedazo, tenes que:
- Copiar ese 1K a la RAM
- Borrarlo
- Modificar esa memoria
- Volver a grabar.

Desconectado micronet3

  • PIC18
  • ****
  • Mensajes: 276
Re:escribiendo en la memoria de programa
« Respuesta #2 en: 19 de Enero de 2019, 12:14:11 »
te adjunto la funcion para la escritura de datos en la memoria de programa
void escribiendo_memoria(int *pt,int32 dir){
  char COUNTER;
  char COUNTER_HIGH;
  int32 addr;
   addr=dir-1;
   //borrando la memoria flash
   TBLPTRL= addr & 0xff;
   TBLPTRH= (addr>>8)& 0xff;
   TBLPTRU= (addr>>16)& 0Xff;
 
  #asm
   bsf EECON1,7 //eepgd
   bcf EECON1,6 //cfgs
   bsf EECON1,2 //wren
   bsf EECON1,4 //FREE
   bcf INTCON,7 //GIE
   movlw 0X55
   movwf EECON2
   movlw 0XAA
   movwf EECON2
   bsf EECON1,1
   bsf INTCON,7
   bcf EECON1,4
   TBLRD*-
   
   #endasm
   addr=dir-1;
   TBLPTRL= addr & 0xff;
   TBLPTRH= (addr>>8)& 0xff;
   TBLPTRU= (addr>>16) & 0Xff;
 
   FSR0L = PT & 0xFF;
   FSR0H = ((PT>>8) & 0xFF);
   
   #asm
   MOVLW 8
   MOVWF COUNTER_HIGH
   
PROGRAM_LOOP:
   MOVLW 8
   MOVWF COUNTER
WRITE_WORD_HREGS:
   MOVF  POSTINC0,W
   MOVWF TABLAT
   TBLWT+*
   DECFSZ COUNTER
   BRA  WRITE_WORD_HREGS
PROGRAM_MEMORY:
   bcf INTCON,7 //GIE
   BSF   EECON1,7
   BCF   EECON1,6
   bsf EECON1,2 //WREN
   
 
   MOVLW 0X55
   MOVWF EECON2
   MOVLW 0XAA
   MOVWF EECON2
   BSF   EECON1,1
   BSF   INTCON,7
   DECFSZ   COUNTER_HIGH
   BRA   PROGRAM_LOOP
   BCF   EECON1,2
  #endasm
 // EECON1=COPIA_EECON1;
}
esta funcion lo estoy comprobando a ver si trabaja o no
lo que veo es que porque deberia borrar 1k?, no seria 64bytes?

Desconectado micronet3

  • PIC18
  • ****
  • Mensajes: 276
Re:escribiendo en la memoria de programa
« Respuesta #3 en: 19 de Enero de 2019, 12:39:37 »
ya trabaja estimado killerjc, 
a counter_high le di el valor de 2
y a counter le di el valor de 32 y graba correctamente los datos en la memoria de programa

un saludo

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 7294
Re:escribiendo en la memoria de programa
« Respuesta #4 en: 19 de Enero de 2019, 14:05:40 »
Podrias usar la libreria de perifericos de XC8, ahi tenes estas funciones:

ReadFlash
EraseFlash
WriteBlockFlash
WriteBytesFlash

Sobre los 1024 bytes a borrar, es porque el datasheet del PIC que vi decia eso xD, asumi que todos los PIC18 iban a ser igual, pero veo que algunos poseen bloques de 64 bytes para borrar, asi como 16/32/64 bytes para escribir.

Desconectado micronet3

  • PIC18
  • ****
  • Mensajes: 276
Re:escribiendo en la memoria de programa
« Respuesta #5 en: 19 de Enero de 2019, 18:45:53 »
ya he comenzado a programar en el xc8, pero generalmente programo en ccs, el ccs tambien tiene funciones pero no he logrado hacerles funcionar, asi que hize uso de las instrucciones en assembler que hay en el datasheet y permite grabar datos en la memoria de programa

un saludo

Desconectado remi04

  • PIC16
  • ***
  • Mensajes: 218
Re:escribiendo en la memoria de programa
« Respuesta #6 en: 23 de Enero de 2019, 16:48:04 »
En ccs  puedes cargar en una variable de entorno los valores de write_size y de erase_size de tu micro de la siguiente forma:

#define ERASE_SIZE getenv("FLASH_ERASE_SIZE")
#define WRITE_SIZE getenv("FLASH_WRITE_SIZE")

Con eso ya conoces el tamaño del bloque de escritura y además conoces el tamaño del bloque que se va a borrar de la flash cada vez que escribas si elijes una dirección múltiplo de WRITE SIZE.

 Por ejemplo, en mi caso, un 18f26k20 tiene un Write_size de 32 bytes y un erase_size de 64 bytes, eso significa que si yo elijo la dirección de memoria 0 y empiezo a escribir un bloque de 32 bytes desde ahí, lo primero que sucede es que la función borra automáticamente un bloque erase_size, que en mi caso serían 64 bytes y luego graba los 32 bytes del bloque dejando entonces 32 grabados y 64 eliminados.

  si elijo la posición 32 para grabar a partir de ahí se van a grabar 8 bytes (del 32 al 39) ambos inclusives, y se borra "erase_size" (64 en mi caso), es decir,  los bytes del 32 al 39 contendrá los nuevos datos, y del 40 al 95 inclusive serán limpiados

 Ahora, si elijo una dirección fuera de write_size, por ejemplo, addres = 3, se escriben los bytes PERO NO se borra nada por que no es una dirección multiplo de Write_Size. 

 
 Puede ser un poco lioso pero es fácil de entender.


 Ahora usas la función:
 write_program_memory(addr, data, count);

  Donde addr es la dirección donde vas a empezar a escribir,
 
  "data" es un puntero a un array o a un solo byte que contiene el/los dato/s que quieres grabar en la flash

y "count" es un entero de 8 bits para los pic 16, o de 16 bits para los pic18, y es el numero de bytes que quieres grabar. 

   

por ejemplo, si escribes:

write_program_memory(64, data, 5);              //Como 64 es multiplo de Write_size se borra un bloque erase_size que en mi caso son 64 bytes, desde la posicion 64 a la 128 se borra todo su contenido, y ahora se graban los 5 primeros bytes del array "data" en los 5 primeros bytes del bloque direccionado, es decir, las posiciones 64,65,66,y 67 serán grabadas y el resto hasta 128 se habrán puesto a 0xFF.

Si escribo:

write_program_memory(65,data,20);         // se graban los primeros 20 bytes del array "data" en los 20 bytes siguientes a la addres elegida, en este caso 65,66,67,68...........84. Pero el resto del bloque queda sin eliminar por que 65 no es multiplo de Write_size

  Grabar en direcciones fuera de multiplo es algo que hay que asegurarse bien de lo que se está haciendo por que el resto del bloque queda ahí grabado y si por ejemplo es un bootloader esto sería catastrófico y hay que tener en cuenta y controlar cuando la funcion borra el bloque erase_size y cuando no lo hace y lo tenemos que hacer manualmente...


 Es un poco liosa de usar esta función en CCS por eso a mucha gente no le funciona.

 Saludos.






« Última modificación: 23 de Enero de 2019, 17:21:40 por remi04 »