Muchas gracias, pero que gran aporte la verdad. Muy bueno. Estas rutinas siempre son necesarias y útiles pero no son fáciles de hacer ni conseguir.
| RAM: section ($100) fshcode: rmb 64 ; ram, no pagina zero * * flash a grabar * addeep equ $C000 ; fstab equ $1825 fcmd equ $1826 srs equ $1800 ; depende del micro ya esta definido en el inc * * $87,$C6,$18,$25,$A5,$10,$27,$08,$C6,$18,$25,$AA,$10,$C7,$18,$25 ; * * $9E,$E6,$01,$F7,$A6,$20,$C7,$18,$26,$45,$18,$25,$F6,$AA,$80,$F7 ; * * $9D,$9D,$9D,$9D,$45,$18,$25,$F6,$F7,$F6,$A5,$30,$27,$04,$A6,$FF ; * * $20,$07,$A6,$FF,$C7,$18,$00,$C6,$18,$25,$A5,$40,$27,$F4,$8A,$81 ; * * * rutina de grabar un byte en $F000, $5A * wrikm: sei ; no irq * ldhx #$C000 ; sthx fshadd ; lda #$C3 ; sta fshdat ; lda #$40 ; sta fshcmd ; jsr fwrite ; erase * ldhx #$C000 ; sthx fshadd ; lda #$C3 ; sta fshdat ; lda #$20 ; sta fshcmd ; jsr fwrite ; write * clrh ; cli ; rts ; * * ingresa hx=dir * a=dato * 21,x en ram es $20 graba $40 borra * * ingresa: * fshadd=direccion a grabar/borrar (1bloque) * fshdat=dato a grabar * fshcmd=comando $20 graba, $40 borra * fshcode=lugar en ram donde se ejecuta * fwrite: ldhx #(f_wr_fin - f_wr_com) ;numero de bytes a copiar, H=0 ;copia funcion de GRABACION a RAM fwr010: lda (f_wr_com-1),x ; sta (fshcode-1),x ;(-1 porque X= ultimo..1) dbnzx fwr010 ; * sta srs ;resetea COP * lda fshcmd ; sta fshcode+21 ; ldhx fshadd ;carga address del bloque a grabar/borrar lda fshdat ; jmp fshcode ;ejecuta codigo en RAM, sale por RTS * * rutina de write/erase * f_wr_com: * write: psha ; lda fstat ; bit #$10 ; 0001 0000 FACCERR beq wri010 ; lda fstat ; ora #$10 ; IF FACCERR=1, clear it sta fstat ; wri010: lda 1,sp ; tomo dato a grabar sta ,x ; grabo donde quiero lda #$20 ; sta fcmd ; comando $20 ldhx #$1825 ; lda ,x ; ora #$80 ; FCBEF=1 sta ,x ; nop ; nop ; nop ; nop ; ldhx #fstat ; lda ,x ; sta ,x ; lda ,x ; bit #$30 ; FPVIOL y FACCERR beq wri020 ; (04) lda #$FF ; 2 bra wri030 ; 2 (07) wri020: lda #$FF ; 2 sta srs ; 3 watchdog lda fstat ; bit #$40 ; beq wri020 ; $F4 wri030: pulh ; rts ; * f_wr_fin: |
tu codigo"
Excelente !!!, yo hace unos años que estoy alejado de estos micros. Sugerencia, no copies el código directamente, encerralos en estos tags, queda mas lindo.Código: [Seleccionar]*
* -------------------------------------------------------
*
* comparo datos entre EEPROM y RAM
*
* flash: addeep
* ram: cuenta+0,1 ...
* sale a=$00 OK
* a=$FF mal
*
* -------------------------------------------------------
*
cmpkm:
ldx #ctebre ; cantidad de datos
cmk010:
sta srs ;
lda addeep,x ;
cmp cuenta,x ;
bne cmk080 ;
decx ;
bpl cmk010 ;
*
* comparo ok!
*
clra ;
bra cmk090 ;
cmk080:
clra ;
coma ;
cmk090:
rts ;
*
* -------------------------------------------------------
*
* rutina de escritura en FLASH de datos en cuenta+0,1 ...
* intento cterei veces grabacion
* sale:
* a=$00 todo bien
* a=$FF mal
*
* -------------------------------------------------------
*
wrikm:
mov #cterei,ayurei ;
wkm010:
jsr wrieep ;
jsr cmpkm ;
tsta ;
beq wkm100 ;
*
dbnz ayurei,wkm010 ;
wkm090:
lda #$FF ;
wkm100:
clrh ;
bclr 4,flag0 ; ya grabe
*
rts ;
*
* -------------------------------------------------------
*
* rutina de grbacion datos en EEPROM
*
* ingresa:
* fshadd=direccion a grabar/borrar (1bloque)
* fshdat=dato a grabar
* fshcmd=comando $20 graba, $40 borra (21,x)
* fshcode=lugar en ram donde se ejecuta
*
* anulo irq's
*
* -------------------------------------------------------
*
wrieep:
clr ayucnt ;
sei ; no timer
bset 1,irqsc ; no irq ext
*
ldhx #$C000 ;
sthx fshadd ;
lda #$FF ;
sta fshdat ;
lda #cmdera ; cmd erase
sta fshcmd ;
jsr fwrite ; erase
wrp010:
clrh ;
ldx ayucnt ;
lda cuenta,x ;
sta fshdat ; data
lda #cmdwri ;
sta fshcmd ; write
jsr fwrite ;
*
inc fshadd+1 ; add=+1
inc ayucnt ;
lda ayucnt ;
sta srs ;
cmp #ctebre+1 ;
bne wrp010 ;
*
clrh ;
cli ;
bclr 1,irqsc ; si irq ext
*
rts ;
*
* db $87,$C6,$18,$25,$A5,$10,$27,$08,$C6,$18,$25,$AA,$10,$C7,$18,$25 ;
*
* db $9E,$E6,$01,$F7,$A6,$20,$C7,$18,$26,$45,$18,$25,$F6,$AA,$80,$F7 ;
*
* db $9D,$9D,$9D,$9D,$45,$18,$25,$F6,$F7,$F6,$A5,$30,$27,$04,$A6,$FF ;
*
* db $20,$07,$A6,$FF,$C7,$18,$00,$C6,$18,$25,$A5,$40,$27,$F4,$8A,$81 ;
*
*
* ingresa hx=dir
* a=dato
* 21,x en ram es $20 graba $40 borra
*
* ingresa:
* fshadd=direccion a grabar/borrar (1bloque)
* fshdat=dato a grabar
* fshcmd=comando $20 graba, $40 borra
* fshcode=lugar en ram donde se ejecuta
*
fwrite:
ldhx #(f_wr_fin - f_wr_com) ;numero de bytes a copiar, H=0
;copia funcion de GRABACION a RAM
fwr010:
lda (f_wr_com-1),x ;
sta (fshcode-1),x ;(-1 porque X= ultimo..1)
dbnzx fwr010 ;
*
sta srs ;resetea COP
*
lda fshcmd ;
sta fshcode+21 ;
ldhx fshadd ;carga address del bloque a grabar/borrar
lda fshdat ;
jmp fshcode ;ejecuta codigo en RAM, sale por RTS
*
* rutina de write/erase
*
f_wr_com:
*
write:
psha ;
lda fstat ;
bit #$10 ; 0001 0000 FACCERR
beq wri010 ;
lda fstat ;
ora #$10 ; IF FACCERR=1, clear it
sta fstat ;
wri010:
lda 1,sp ; tomo dato a grabar
sta ,x ; grabo donde quiero
lda #$20 ;
sta fcmd ; comando $20
ldhx #$1825 ;
lda ,x ;
ora #$80 ; FCBEF=1
sta ,x ;
nop ;
nop ;
nop ;
nop ;
ldhx #fstat ;
lda ,x ;
sta ,x ;
lda ,x ;
bit #$30 ; FPVIOL y FACCERR
beq wri020 ;
lda #$FF ;
bra wri030 ;
wri020:
lda #$FF ;
sta srs ; watchdog
lda fstat ;
bit #$40 ;
beq wri020 ; $F4
wri030:
pulh ;
rts ;
*
f_wr_fin:
bueno a pedido, cambie el formato, gracias nuevamente RICHI777
ahora agregue las rutinas de comparacion y grabado de n bytes, super completa. funciona ok.
yo suelo grabar entre 1 y 32 datos de configuracion o cuando se corta la energia.
Excelente !!!, yo hace unos años que estoy alejado de estos micros. Sugerencia, no copies el código directamente, encerralos en estos tags, queda mas lindo.Código: [Seleccionar]*
* -------------------------------------------------------
*
* comparo datos entre EEPROM y RAM
*
* flash: addeep
* ram: cuenta+0,1 ...
* sale a=$00 OK
* a=$FF mal
*
* -------------------------------------------------------
*
cmpkm:
ldx #ctebre ; cantidad de datos
cmk010:
sta srs ;
lda addeep,x ;
cmp cuenta,x ;
bne cmk080 ;
decx ;
bpl cmk010 ;
*
* comparo ok!
*
clra ;
bra cmk090 ;
cmk080:
clra ;
coma ;
cmk090:
rts ;
*
* -------------------------------------------------------
*
* rutina de escritura en FLASH de datos en cuenta+0,1 ...
* intento cterei veces grabacion
* sale:
* a=$00 todo bien
* a=$FF mal
*
* -------------------------------------------------------
*
wrikm:
mov #cterei,ayurei ;
wkm010:
jsr wrieep ;
jsr cmpkm ;
tsta ;
beq wkm100 ;
*
dbnz ayurei,wkm010 ;
wkm090:
lda #$FF ;
wkm100:
clrh ;
bclr 4,flag0 ; ya grabe
*
rts ;
*
* -------------------------------------------------------
*
* rutina de grbacion datos en EEPROM
*
* ingresa:
* fshadd=direccion a grabar/borrar (1bloque)
* fshdat=dato a grabar
* fshcmd=comando $20 graba, $40 borra (21,x)
* fshcode=lugar en ram donde se ejecuta
*
* anulo irq's
*
* -------------------------------------------------------
*
wrieep:
clr ayucnt ;
sei ; no timer
bset 1,irqsc ; no irq ext
*
ldhx #$C000 ;
sthx fshadd ;
lda #$FF ;
sta fshdat ;
lda #cmdera ; cmd erase
sta fshcmd ;
jsr fwrite ; erase
wrp010:
clrh ;
ldx ayucnt ;
lda cuenta,x ;
sta fshdat ; data
lda #cmdwri ;
sta fshcmd ; write
jsr fwrite ;
*
inc fshadd+1 ; add=+1
inc ayucnt ;
lda ayucnt ;
sta srs ;
cmp #ctebre+1 ;
bne wrp010 ;
*
clrh ;
cli ;
bclr 1,irqsc ; si irq ext
*
rts ;
*
* db $87,$C6,$18,$25,$A5,$10,$27,$08,$C6,$18,$25,$AA,$10,$C7,$18,$25 ;
*
* db $9E,$E6,$01,$F7,$A6,$20,$C7,$18,$26,$45,$18,$25,$F6,$AA,$80,$F7 ;
*
* db $9D,$9D,$9D,$9D,$45,$18,$25,$F6,$F7,$F6,$A5,$30,$27,$04,$A6,$FF ;
*
* db $20,$07,$A6,$FF,$C7,$18,$00,$C6,$18,$25,$A5,$40,$27,$F4,$8A,$81 ;
*
*
* ingresa hx=dir
* a=dato
* 21,x en ram es $20 graba $40 borra
*
* ingresa:
* fshadd=direccion a grabar/borrar (1bloque)
* fshdat=dato a grabar
* fshcmd=comando $20 graba, $40 borra
* fshcode=lugar en ram donde se ejecuta
*
fwrite:
ldhx #(f_wr_fin - f_wr_com) ;numero de bytes a copiar, H=0
;copia funcion de GRABACION a RAM
fwr010:
lda (f_wr_com-1),x ;
sta (fshcode-1),x ;(-1 porque X= ultimo..1)
dbnzx fwr010 ;
*
sta srs ;resetea COP
*
lda fshcmd ;
sta fshcode+21 ;
ldhx fshadd ;carga address del bloque a grabar/borrar
lda fshdat ;
jmp fshcode ;ejecuta codigo en RAM, sale por RTS
*
* rutina de write/erase
*
f_wr_com:
*
write:
psha ;
lda fstat ;
bit #$10 ; 0001 0000 FACCERR
beq wri010 ;
lda fstat ;
ora #$10 ; IF FACCERR=1, clear it
sta fstat ;
wri010:
lda 1,sp ; tomo dato a grabar
sta ,x ; grabo donde quiero
lda #$20 ;
sta fcmd ; comando $20
ldhx #$1825 ;
lda ,x ;
ora #$80 ; FCBEF=1
sta ,x ;
nop ;
nop ;
nop ;
nop ;
ldhx #fstat ;
lda ,x ;
sta ,x ;
lda ,x ;
bit #$30 ; FPVIOL y FACCERR
beq wri020 ;
lda #$FF ;
bra wri030 ;
wri020:
lda #$FF ;
sta srs ; watchdog
lda fstat ;
bit #$40 ;
beq wri020 ; $F4
wri030:
pulh ;
rts ;
*
f_wr_fin:
Buenos días gente, les consulto estas rutinas funcionan ok tanto con oscilador interno como cristal??? ya que las estoy probando y no puedo hacer que graben con un micro MC9S08SH8.
saludos
Before any program or erase command can be accepted, the FLASH clock divider register (FCDIV) must be written to set the internal clock for the FLASH module to a frequency (fFCLK) between 150 kHz and 200 kHz (see Section 4.7.1, “FLASH Clock Divider Register (FCDIV)”)