1ms fördröjning blir ca 250ms?
1ms fördröjning blir ca 250ms?
Har fifflat ihop en simpel led som ska blinka varje millisekund. Vet att det är för fort för att se men jag provade bara att ställa ner det så mycket det gick och det går ändå för sakta. ca 2 blink i sekunden...
Hur som helst. Använder timer0 på en PIC16F628A med prescale 8. Med intern oscillator på 4mhz får jag för mig att tmr0 då borde köra en interrupt var 8:e μs.
Räknar sedan i varje interrupt upp ett "tick" ändå tills jag kommer till 125 och trodde då att jag skulle få 1ms...
Antar att jag tänker fel någonstans, var lite väl länge sedan man skrev assembler...
Hur som helst. Använder timer0 på en PIC16F628A med prescale 8. Med intern oscillator på 4mhz får jag för mig att tmr0 då borde köra en interrupt var 8:e μs.
Räknar sedan i varje interrupt upp ett "tick" ändå tills jag kommer till 125 och trodde då att jag skulle få 1ms...
Antar att jag tänker fel någonstans, var lite väl länge sedan man skrev assembler...
Tänkte jag skulle slippa klippa ur kod här och där men här kommer den iaf:
Kod: Markera allt
org 0000h
goto INIT
org 0004h
movwf TEMPW ; Save W in a temporary variable
movfw STATUS ; Save Status register in temporary variable
movwf TEMPSTATUS
movfw TICKSTART ; Preset timer 6 steps ahead
movwf TMR0
incf MS,1 ; Increment Millisecond counter
movfw TEMPSTATUS ; Read back Status register from temporary variable
movwf STATUS
movfw TEMPW ; Read back W from temporary variable
bcf INTCON,2 ; Clear interrupt flag
retfie
INIT
movlw b'00000001' ; Set timer0 interrupt and prescale
movwf OPTION_REG
movlw 0x06 ; Preset timer 6 steps ahead
movwf TICKSTART
movwf TMR0
MAIN
.
.
.
goto MAINOm du använder Mplab...
Sätt en breakpoint i interrupt-rutinen.
Använd stopwatch för att se hur många cycler det är mellan interrupt.
Du har skrivit "incf MS,1"
Det blir tydligare om man använder ,w och ,f istället.
,f är default så du behöver inte skriva något alls.
Jag använder aldrig movfw för jag tycker det blir för likt movwf (grötar ihop sig i hjärnan), dessutom står movfw inte i databladet.
Sätt en breakpoint i interrupt-rutinen.
Använd stopwatch för att se hur många cycler det är mellan interrupt.
Du har skrivit "incf MS,1"
Det blir tydligare om man använder ,w och ,f istället.
,f är default så du behöver inte skriva något alls.
Jag använder aldrig movfw för jag tycker det blir för likt movwf (grötar ihop sig i hjärnan), dessutom står movfw inte i databladet.
Har du tagit hänsyn till tiden från det att interruptet inträffar
fram till att du sätter TMR0 ?
Som Cribba sa, använd symbolerna istället för bitnummer.
Din save/restore av context är inte enligt "standard". Se exmepl i databladet.
Du talade om "blink i sekunden", jag ser inget i koden som "blinkar"...
fram till att du sätter TMR0 ?
Som Cribba sa, använd symbolerna istället för bitnummer.
Din save/restore av context är inte enligt "standard". Se exmepl i databladet.
Du talade om "blink i sekunden", jag ser inget i koden som "blinkar"...
Det var ett tag sen, men ett trick jag använde när jag gjorde liknande saker var att addera ett tal till TMR0 istället för att sätta den. Det kompenserar automatiskt för cyklerna det tar att köra "introt" i ISR (allt utom cykeln där själva additionen körs, om jag minns rätt angående timerns beteende).
Alltså
movlw XXX
addwf TMR0,f
Alltså
movlw XXX
addwf TMR0,f
