Read & Write to Flash [PIC16F1705]
Re: Read & Write to Flash [PIC16F1705]
Du pratade om att det skulle ta 8-10ms, hela proceduren. Samt att den var beroende av använda respektive tomma byte.
Posta väldigt gärna koden, det är alltid bra att ha exempel att utgå från.
Posta väldigt gärna koden, det är alltid bra att ha exempel att utgå från.
Re: Read & Write to Flash [PIC16F1705]
> Du pratade om att det skulle ta 8-10ms, hela proceduren.
Som sagt, jag vet fortfarande inte vad du syftar på, om det var i denna
tråden eller någon annan tråd. Men som sagt, *skrivningen* tar ca 2.5 ms.
Sedan tillkommer kopiering av data, raderingen (som väl också tar ca 2.4 ms)
o.s.v. Så totalt kanske det är den tid du nämner.
Sedan så har jag för mig att det var en annan modell vi tittade på innan, men det
kanske jag minns fel. Tiderna kan variera något mellan modeller.
> Samt att den var beroende av använda respektive tomma byte.
"Tomma" eller "tömma"? Man ja, raderingen tar också tid. Däremot spelar
det inget roll vad innehållet är.
Jag vet inte om detta är så mycket att "utgå" från, men om det är till hjälp så...
Det som är speciellt är hur "out_buff" allokeras, det är unikt för de nya 16F1xxx.
Koden är skriven så att, efter att main har initierat allt, så körs allting i ISR koden.
"copy_buff_loop" visar en kopiering från flash till RAM, också unikt för 16F1xxx.
"roll_loop" är för att "rulla" texten en pixel innan nästa uppdatering.
Displayen scannas 112 gånger innan texten shiftas ("roll_speed").
Som sagt, jag vet fortfarande inte vad du syftar på, om det var i denna
tråden eller någon annan tråd. Men som sagt, *skrivningen* tar ca 2.5 ms.
Sedan tillkommer kopiering av data, raderingen (som väl också tar ca 2.4 ms)
o.s.v. Så totalt kanske det är den tid du nämner.
Sedan så har jag för mig att det var en annan modell vi tittade på innan, men det
kanske jag minns fel. Tiderna kan variera något mellan modeller.
> Samt att den var beroende av använda respektive tomma byte.
"Tomma" eller "tömma"? Man ja, raderingen tar också tid. Däremot spelar
det inget roll vad innehållet är.
Jag vet inte om detta är så mycket att "utgå" från, men om det är till hjälp så...
Det som är speciellt är hur "out_buff" allokeras, det är unikt för de nya 16F1xxx.
Koden är skriven så att, efter att main har initierat allt, så körs allting i ISR koden.
"copy_buff_loop" visar en kopiering från flash till RAM, också unikt för 16F1xxx.
"roll_loop" är för att "rulla" texten en pixel innan nästa uppdatering.
Displayen scannas 112 gånger innan texten shiftas ("roll_speed").
Kod: Markera allt
;**********************************************************************
; Enkelt test av CDS 8x64 röd/grön LED matrix.
; För PIC16F1938
;
;**********************************************************************
; *
; Filename: CDS.asm
; Date: 2012-08-04
; File Version: 1.0
;
; Author: Jan-Erik Söderholm
; Company: Jan-Erik Söderholm Consulting AB
;
;**********************************************************************
;
; Files required: P16F1938.INC
;
;**********************************************************************
;
; Använder intosc på 32 Mhz (HFINTOSC + PLL).
;
; ROW SEL 0 : RA0
; ROW SEL 1 : RA1
; ROW SEL 2 : RA2
; ROW EN : RA3
; COL CLK : RB0
; COL DATA LATCH : RB1
; COL EN OUTPUT : RB2
; COL SER DATA : RB3
;**********************************************************************
list p=16f1938 ; list directive to define processor
#include <p16f1938.inc> ; processor specific variable definitions
__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_ON & _IESO_OFF & _FCMEN_OFF
__CONFIG _CONFIG2, _WRT_OFF & _VCAPEN_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_19 & _LVP_OFF
;**********************************************************************
errorlevel -302
;
#define ROW_SEL_PORT LATA
#define ROW_EN LATA, 3
#define COL_CLOCK LATB, 0
#define COL_LATCH LATB, 1
#define COL_EN LATB, 2
#define COL_DATA LATB, 3
;
roll_speed equ d'112'
row_init equ d'8'
VAR1 UDATA_SHR
loop_cnt RES 1
ROW_COUNTER res 1
row_tmp res 1
roll_timer res 1
roll_tmp1 res 1
roll_tmp2 res 1
; Allocate display buffer.
; 384 positioner för röd/grön data
LINEAR0 UDATA
out_buff RES d'384'
;**********************************************************************
; RESET VECTOR
;**********************************************************************
RESET_VECT CODE 0x0000 ; processor reset vector
PAGESEL START
GOTO START
nop
nop
;**********************************************************************
; INTERRUPT SERVICE ROUTINE
;**********************************************************************
ISR CODE 0x0004 ; interrupt vector location
; Disable display
banksel lata
bcf row_en
bcf col_en
movlw d'128'
dis_del
decfsz wreg, f
goto dis_del
; Update ROW SEL 0-2 for next row
decf row_counter, f
banksel ROW_SEL_PORT
movf ROW_SEL_PORT, w
andlw b'11111000'
iorwf row_counter, w
movwf ROW_SEL_PORT
; Load next 128 pixel bits
movlw high out_buff
movwf fsr0h
movlw low out_buff
movwf fsr0l
movlw d'128'
movwf loop_cnt
movf row_counter, w ; (7 ... 1)
lslf wreg, f ; (now 14, 12, 10 ... 2, 0)
lslf wreg, f ; (now 28, 24, 20 ... 4, 0)
pixel_loop
bcf COL_DATA
brw ; Add WREG to PC!
; Pixel 0
btfsc indf0, 0
bsf COL_DATA
goto cont_pix_loop
nop
; Pixel 1
btfsc indf0, 1
bsf COL_DATA
goto cont_pix_loop
nop
; Pixel 2
btfsc indf0, 2
bsf COL_DATA
goto cont_pix_loop
nop
; Pixel 3
btfsc indf0, 3
bsf COL_DATA
goto cont_pix_loop
nop
; Pixel 4
btfsc indf0, 4
bsf COL_DATA
goto cont_pix_loop
nop
; Pixel 5
btfsc indf0, 5
bsf COL_DATA
goto cont_pix_loop
nop
; Pixel 6
btfsc indf0, 6
bsf COL_DATA
goto cont_pix_loop
nop
; Pixel 7
btfsc indf0, 7
bsf COL_DATA
goto cont_pix_loop
nop
cont_pix_loop
; Toggle COL_CLOCK
bsf COL_CLOCK
nop
bcf COL_CLOCK
addfsr 0, 1
decfsz loop_cnt, f ; All pixels?
goto pixel_loop ; No, continue.
; Toggle COL_LATCH
bsf COL_LATCH
nop
bcf COL_LATCH
; Roll buffer one pos to left if needed.
decfsz roll_timer, f
goto no_roll
; Rotate 384 byte buffer 2 steps to the left.
; Load FSR0 with start adress of buffer.
movlw high out_buff
movwf fsr0h
movlw low out_buff
movwf fsr0l
; Number of loops.
; 5 bytes are moved each loop, 76x5 = 380.
; 2 bytes are saved for later restore = 382.
; 2 bytes are moved outside of the loop = 384.
movlw d'76'
movwf loop_cnt
; Save the first two positions for later restore.
moviw [fsr0] ; First pos...
movwf roll_tmp1
moviw 1[fsr0] ; Second pos...
movwf roll_tmp2
; Move two positions to get an "even" loop.
moviw 2[fsr0] ; Move FSR0+2 => W
movwi fsr0++ ; Move W => FSR0 and incr FSR0
moviw 2[fsr0]
movwi fsr0++
; Now loop through the rest of the buffer.
; Move 5 bytes each time to save on looping logic.
roll_loop
moviw 2[fsr0]
movwi fsr0++
moviw 2[fsr0]
movwi fsr0++
moviw 2[fsr0]
movwi fsr0++
moviw 2[fsr0]
movwi fsr0++
moviw 2[fsr0]
movwi fsr0++
decfsz loop_cnt, f ; All of buffer?
goto roll_loop ; No, continue.
movf roll_tmp1, w ; Restore the two saved bytes
movwi [fsr0] ; At the end of buffer
movf roll_tmp2, w
movwi 1[fsr0]
movlw roll_speed
movwf roll_timer
; End Roll buffer...
no_roll
; Check row_counter and reset if neeed
movf row_counter, f
btfss status, z
goto cont_1
movlw row_init
movwf row_counter
cont_1
; Re-enable display
banksel lata
bsf row_en
bsf col_en
; End of ISR...
banksel intcon
bcf intcon, tmr0if
RETFIE ; return from interrupt
;**********************************************************************
; MAIN PROGRAM
;**********************************************************************
START
;**********************************************************************
; PLACE USER PROGRAM HERE
;**********************************************************************
banksel ansela
clrf ansela
clrf anselb
banksel trisa
clrf trisa
clrf trisb
banksel lata
clrf lata
clrf latb
banksel lcdcon
bcf lcdcon, lcden
; 32 Mhz...
banksel osccon
bsf osccon, spllen
bsf osccon, ircf3
bsf osccon, ircf2
bsf osccon, ircf1
bcf osccon, ircf0
; Copy buffer data from flash to GPR.
movlw high out_buff
movwf fsr0h
movlw low out_buff
movwf fsr0l
movlw high txt_tab3
movwf fsr1h
movlw low txt_tab3
movwf fsr1l
movlw d'192'
movwf loop_cnt
copy_buff_loop
moviw indf1++
nop
movwi indf0++
moviw indf1++
nop
movwi indf0++
decfsz loop_cnt, f
goto copy_buff_loop
; Initiera row_counter
movlw row_init
movwf row_counter
; Initiera roll_timer
movlw roll_speed
movwf roll_timer
; Initiera Timer0
banksel option_reg
bcf option_reg, ps0
bcf option_reg, ps1
bsf option_reg, ps2
bcf option_reg, psa
bcf option_reg, tmr0cs
banksel intcon
bsf intcon, tmr0ie
; Starta interrupt
banksel intcon
bsf intcon, peie
bsf intcon, gie
;**********************************************************************
end_loop
GOTO end_loop
;
;**********************************************************************
; Text example stored in flash.
txt_sect3 code
txt_tab3 dt h'ff', h'00', h'7E', h'00', h'3C', h'00', h'18', h'00'
dt h'00', h'00', h'00', h'00'
dt h'00', h'61', h'00', h'91', h'00', h'91', h'00', h'91' ; S
dt h'00', h'8E', h'00', h'00'
dt h'00', h'0E', h'00', h'11', h'00', h'11', h'00', h'11' ; o
dt h'00', h'0E', h'00', h'00'
dt h'00', h'0E', h'00', h'11', h'00', h'11', h'00', h'09' ; d
dt h'00', h'FF', h'00', h'00'
dt h'00', h'02', h'00', h'01', h'00', h'21', h'00', h'BE' ; j
dt h'00', h'00', h'00', h'00'
dt h'00', h'06', h'00', h'29', h'00', h'29', h'00', h'29' ; a
dt h'00', h'1F', h'00', h'00'
dt h'00', h'3F', h'00', h'10', h'00', h'20', h'00', h'20' ; n
dt h'00', h'1F', h'00', h'00'
dt h'00', h'00', h'00', h'00', h'00', h'00', h'00', h'00'
dt h'00', h'1e', h'00', h'29', h'00', h'49', h'00', h'89' ; 6
dt h'00', h'86', h'00', h'00'
dt h'00', h'18', h'00', h'28', h'00', h'48', h'00', h'ff' ; 4
dt h'00', h'08', h'00', h'00'
dt h'00', h'11', h'00', h'0a', h'00', h'04', h'00', h'0a' ; x
dt h'00', h'11', h'00', h'00'
dt h'00', h'6e', h'00', h'91', h'00', h'91', h'00', h'91' ; 8
dt h'00', h'6e', h'00', h'00'
dt h'00', h'00', h'00', h'00', h'00', h'00', h'00', h'00'
dt h'00', h'ff', h'00', h'01', h'00', h'01', h'00', h'01' ; L
dt h'00', h'01', h'00', h'00'
dt h'00', h'ff', h'00', h'91', h'00', h'91', h'00', h'91' ; E
dt h'00', h'81', h'00', h'00'
dt h'00', h'ff', h'00', h'81', h'00', h'81', h'00', h'42' ; D
dt h'00', h'3c', h'00', h'00'
dt h'00', h'00', h'00', h'00', h'00', h'00', h'00', h'00'
dt h'00', h'0E', h'00', h'11', h'00', h'11', h'00', h'09' ; d
dt h'00', h'FF', h'00', h'00'
dt h'00', h'0e', h'00', h'15', h'00', h'15', h'00', h'15' ; e
dt h'00', h'0c', h'00', h'00'
dt h'00', h'3f', h'00', h'20', h'00', h'18', h'00', h'20' ; m
dt h'00', h'1f', h'00', h'00'
dt h'00', h'0E', h'00', h'11', h'00', h'11', h'00', h'11' ; o
dt h'00', h'0E', h'00', h'00'
dt h'00', h'00', h'00', h'00', h'00', h'00', h'00', h'00'
dt h'00', h'ff', h'00', h'88', h'00', h'88', h'00', h'88' ; P
dt h'00', h'70', h'00', h'00'
dt h'00', h'81', h'00', h'81', h'00', h'ff', h'00', h'81' ; I
dt h'00', h'81', h'00', h'00'
dt h'00', h'7e', h'00', h'81', h'00', h'81', h'00', h'81' ; C
dt h'00', h'42', h'00', h'00'
dt h'00', h'00', h'00', h'41', h'00', h'ff', h'00', h'01' ; 1
dt h'00', h'00', h'00', h'00'
dt h'00', h'1e', h'00', h'29', h'00', h'49', h'00', h'89' ; 6
dt h'00', h'86', h'00', h'00'
dt h'00', h'ff', h'00', h'90', h'00', h'90', h'00', h'90' ; F
dt h'00', h'80', h'00', h'00'
dt h'00', h'00', h'00', h'00'
dt h'00', h'00', h'00', h'00'
dt h'00', h'00', h'00', h'00'
dt h'00', h'00', h'00', h'00'
dt h'00', h'00', h'00', h'00'
dt h'00', h'00', h'00', h'00'
dt h'00', h'00', h'00', h'00'
dt h'00', h'00', h'00', h'00'
dt h'00', h'00', h'00', h'00'
dt h'00', h'00', h'00', h'00'
dt h'00', h'00', h'00', h'00'
dt h'00', h'00', h'00', h'00'
dt h'00', h'00', h'00', h'00'
dt h'00', h'00', h'00', h'00'
dt h'00', h'00', h'00', h'00'
dt h'00', h'00', h'00', h'00'
END
Re: Read & Write to Flash [PIC16F1705]
Kan du förklara vad som händer här?
movlw high out_buff
high är en literal/constant, men var får den sitt värde och hur fungerar det?
movlw high out_buff
high är en literal/constant, men var får den sitt värde och hur fungerar det?
Re: Read & Write to Flash [PIC16F1705]
"out_buff" är en symbol som pekar på adressen till början av en 384 byte buffert:
Notera att minnet allokeras från sektion LINEAR0 i linker filen.
Sedan ska index registret FSR0 (2 bytes) laddas med adressen till out_buff.
Det görs i två steg med 1 byte i taget. Först de höga 8 bitarna till FSR0H och
sedan de låga 8 bitarna till FSR0L (ordningen spelar så klart ingen roll):
> high är en literal/constant
Nej, det är det inte. User Guide till MPASM skriver:
(i detta fall). I det aktuella fallet så har out_buff värdet 0x002000, alltså starten av
"linear memory". FSR0H kommer att bli 0x20 och FSRL kommer att bli 0x00.
Adress 0x2000 är samma position i minnet som 0x20 i första banken (bank0) och
MPASM ser så klart till att det inte dubbel allokeras...
Kod: Markera allt
LINEAR0 UDATA
out_buff RES d'384'
Sedan ska index registret FSR0 (2 bytes) laddas med adressen till out_buff.
Det görs i två steg med 1 byte i taget. Först de höga 8 bitarna till FSR0H och
sedan de låga 8 bitarna till FSR0L (ordningen spelar så klart ingen roll):
Kod: Markera allt
; Load FSR0 with start adress of buffer.
movlw high out_buff
movwf fsr0h
movlw low out_buff
movwf fsr0l
Nej, det är det inte. User Guide till MPASM skriver:
High/low bara talar om vilken del av symbolen "out_buff" som man vill ladda till W6.4 LOW, HIGH AND UPPER OPERATORS
Low, high and upper operators are used to return one byte of a multi-byte label value.
If low is used, only bits 0 through 7 of the expression will be used. If high is used, only
bits 8 through 15 of the expression will be used. If upper is used, only bits 16 through
21 of the expression will be used.
(i detta fall). I det aktuella fallet så har out_buff värdet 0x002000, alltså starten av
"linear memory". FSR0H kommer att bli 0x20 och FSRL kommer att bli 0x00.
Adress 0x2000 är samma position i minnet som 0x20 i första banken (bank0) och
MPASM ser så klart till att det inte dubbel allokeras...
Re: Read & Write to Flash [PIC16F1705]
Förresten, skrivning till Flash inhiberar inte microprocessorn.
Vilket antyds rätt tydligt med att man ska börja med att stänga av GIE.
Clocks, timers och peripherals jobbar på som vanligt.
Dvs skrivning gör den fullständigt upptagen med det momentet, inte mer än så.
Vilket för mig är nödvändigt veta, för då faller kravet på att exakt veta hur lång tid proceduren tar.
Påverkas inte klockorna så är det betydligt enklare upplåta tiden olika input är "blinda".
Vilket antyds rätt tydligt med att man ska börja med att stänga av GIE.
Clocks, timers och peripherals jobbar på som vanligt.
Dvs skrivning gör den fullständigt upptagen med det momentet, inte mer än så.
Vilket för mig är nödvändigt veta, för då faller kravet på att exakt veta hur lång tid proceduren tar.
Påverkas inte klockorna så är det betydligt enklare upplåta tiden olika input är "blinda".
Re: Read & Write to Flash [PIC16F1705]
Att man ska stänga GIE beror på att den kan "komma mellan" skrivprocedurens första steg - innan själva skrivningen sker - och därmed sabba den totalt.
Re: Read & Write to Flash [PIC16F1705]
Tja, det kan hända mycket under de 2x 4-5 ms som en skrivning tar, så det gäller att ha kontroll på vad som händer med periferienheterna innan man påbörjar skrivning.Erik M skrev:Förresten, skrivning till Flash inhiberar inte microprocessorn.
Vilket antyds rätt tydligt med att man ska börja med att stänga av GIE.
Clocks, timers och peripherals jobbar på som vanligt.
Dvs skrivning gör den fullständigt upptagen med det momentet, inte mer än så.
Vilket för mig är nödvändigt veta, för då faller kravet på att exakt veta hur lång tid proceduren tar.
Påverkas inte klockorna så är det betydligt enklare upplåta tiden olika input är "blinda".
Re: Read & Write to Flash [PIC16F1705]
Som sagt - clocks, timers och peripherals fortsätter som vanligt.
Vilket gör att jag kan se till att övriga just då ej aktiva procedurer inte påverkas,
men ändå behåller kontakt med den input som anger när de skall aktiveras.
Vilket gör att jag kan se till att övriga just då ej aktiva procedurer inte påverkas,
men ändå behåller kontakt med den input som anger när de skall aktiveras.
Re: Read & Write to Flash [PIC16F1705]
En skrivning till flash kräver en specifik sekvens som INTE får avbrytas om det ska fungera. En interrupt kan komma "mellan" och paja sekvensen så att skrivningen går om intet.
Re: Read & Write to Flash [PIC16F1705]
Just så är det, och dessutom så fortsätter clocks, timers och peripherals som vanligt.
Det vill säga det blir ingen inhibering, som sagts ovan.
Att ett stycke kod, i detta fall skrivning till Flash, vill göra sitt arbete utan avbrott, är inget unikt.
Det är bra veta hur lång denna upptagenhet är, så man kan undvika problem som skulle kunna uppstå, mer än så är det inte.
Genom att veta att det inte är någon inhibering behöver man inte försöka kompensera för bortfallen tid, en tid som dessutom är okänd då den flukturerar slumpmässigt.
Det vill säga det blir ingen inhibering, som sagts ovan.
Att ett stycke kod, i detta fall skrivning till Flash, vill göra sitt arbete utan avbrott, är inget unikt.
Det är bra veta hur lång denna upptagenhet är, så man kan undvika problem som skulle kunna uppstå, mer än så är det inte.
Genom att veta att det inte är någon inhibering behöver man inte försöka kompensera för bortfallen tid, en tid som dessutom är okänd då den flukturerar slumpmässigt.
Re: Read & Write to Flash [PIC16F1705]
Jo det blir en inhibering, eftersom processorn inte exekverar någon som helst kod under den tiden det tar att rensa/skriva till flash.
Att periferienheter såsom timers, uarts etc fortsätter att snurra som ingenting hänt kan både vara bra och dåligt, beroende på vad man använder dem till och hur de är satta.
Att periferienheter såsom timers, uarts etc fortsätter att snurra som ingenting hänt kan både vara bra och dåligt, beroende på vad man använder dem till och hur de är satta.
Re: Read & Write to Flash [PIC16F1705]
"Erik, håll hårdare i påsen med trollgodis."
Senast redigerad av Erik M 6 november 2016, 19:32:53, redigerad totalt 1 gång.
Re: Read & Write to Flash [PIC16F1705]
Varför det, förutom att timers uppdateras och eventuellt rullar runt under tiden.Att processorns klockor fortsätter ticka är det egentligen enda intressanta.