Delay bekymmer
Delay bekymmer
Hej jag har ett litet problem.Det är så att jag har programmerat ett program i mplab till pic 18f452.
När jag simulerar detta program så fungerar det som det ska. Men sedan när jag lör det i verkligheten och kopplar upp det så fungerar det inte alls.
Problemet är att till/ och från slaget av min utgång som går till lysdioder går för fort att blotta ögat hinner inte med. Så då tänkte jag att lägga en delayer i mellan till /och från läget. denna delay subrutin ser ut så här(Bygger på två st loppar, en inre och en yttre).
Delayfunk:
Movlw HFFFF
Movf delay1
Yttre_ loop: Movlw HFFFF
Movf delay2
Inre _loop:
Decfsz delay1
Goto inre_loop
Decfsz delay1
Goto Yttre_loop
Return
Men som ni förstår men inte jag så kommer jag inte få tillräklig fördröjning med denna typen av delayer. Jag behöver att komma upp i en sekund i alla fall. Så man hinner att reagera. När jag kör tid hur länge det tar för picen att köra igenom denna kod så tar det bara 30ms sekunder. Med den hastighet hinner man inte att se någon. Så min fråga är hur man ska skapa en sådan fördöjning som vara i alla fall en sekund?
När jag simulerar detta program så fungerar det som det ska. Men sedan när jag lör det i verkligheten och kopplar upp det så fungerar det inte alls.
Problemet är att till/ och från slaget av min utgång som går till lysdioder går för fort att blotta ögat hinner inte med. Så då tänkte jag att lägga en delayer i mellan till /och från läget. denna delay subrutin ser ut så här(Bygger på två st loppar, en inre och en yttre).
Delayfunk:
Movlw HFFFF
Movf delay1
Yttre_ loop: Movlw HFFFF
Movf delay2
Inre _loop:
Decfsz delay1
Goto inre_loop
Decfsz delay1
Goto Yttre_loop
Return
Men som ni förstår men inte jag så kommer jag inte få tillräklig fördröjning med denna typen av delayer. Jag behöver att komma upp i en sekund i alla fall. Så man hinner att reagera. När jag kör tid hur länge det tar för picen att köra igenom denna kod så tar det bara 30ms sekunder. Med den hastighet hinner man inte att se någon. Så min fråga är hur man ska skapa en sådan fördöjning som vara i alla fall en sekund?
-
- Inlägg: 2360
- Blev medlem: 16 september 2003, 17:18:13
- Ort: Dubai, United Arab Emirates
- Kontakt:
Lägg ytterligare en yttre loop så att du har 3 loopar i varandra.
Eller lägg in en några st NOP'ar innuti den inre loopen.
Eller! Nu när jag kollade på din kod så ser jag att du aldrig decrementerar Delay2. Båda Decfsz går på variabeln delay1 - vilket innbär att du inte alls har simuletar koden och fått den att fungera bra i simulatorn ;-) Fixa koden så fungerar den säkert bättre.
Eller lägg in en några st NOP'ar innuti den inre loopen.
Eller! Nu när jag kollade på din kod så ser jag att du aldrig decrementerar Delay2. Båda Decfsz går på variabeln delay1 - vilket innbär att du inte alls har simuletar koden och fått den att fungera bra i simulatorn ;-) Fixa koden så fungerar den säkert bättre.
ok,vist ett exempel på hur man kan skapa timer med delay
Hur ser ett delay funktion ut med hjälp av timer.Kan du visa mig ett exempel hur man kan skapa en sådan delay.det har jag haldrig gjort förut.bara andvänt delay enlig föregående kod bit.
Jag stängde just av PC'n där jag har MPLAB och källkoder... 
Men i princip står allt du behöver veta i databladet, så
jag föreslår att du börjar där. Du har väl läst databladet
flera gånger, eller hur ?
I princip rör det sig om att :
- Sätta upp en timer med ett lämpligt intervall.
- Sätta upp interrupt från timern.
- Fixa en interruptrutin (ISR) där du togglar LED'en.
Sedan kommer allt att nästan gå av sig självt...
Jag har inte i huvudet just nu vilken av de 4 timers som
är lämpligast, du får kolla lite i databladet vilken som ger
längst intervall.
Slutligen, koden som du har postat fungerar *inte* i MPLAB/MPASM,
eftersom allt står i position 1. Se till att din kod är korrekt
formatterad och använd "code" taggarna

Men i princip står allt du behöver veta i databladet, så
jag föreslår att du börjar där. Du har väl läst databladet
flera gånger, eller hur ?
I princip rör det sig om att :
- Sätta upp en timer med ett lämpligt intervall.
- Sätta upp interrupt från timern.
- Fixa en interruptrutin (ISR) där du togglar LED'en.
Sedan kommer allt att nästan gå av sig självt...

Jag har inte i huvudet just nu vilken av de 4 timers som
är lämpligast, du får kolla lite i databladet vilken som ger
längst intervall.
Slutligen, koden som du har postat fungerar *inte* i MPLAB/MPASM,
eftersom allt står i position 1. Se till att din kod är korrekt
formatterad och använd "code" taggarna
En label får inte innehålla mellanslag. (kan den inte heller....så det är konstigt att du kan simulera din kod...). Ett av flera fel i din kod.
Hur vet du att det är 30ms? Vad går PICen i för hastighet? Kör du i 4MHz så behöver du 1 miljon cyklar för att få 1 sekunds fördröjning...
Men timer är nog bättre iofs, men ska du bara blinka med en diod så spelar det ingen roll. Testa båda sätten.
Hur vet du att det är 30ms? Vad går PICen i för hastighet? Kör du i 4MHz så behöver du 1 miljon cyklar för att få 1 sekunds fördröjning...
Men timer är nog bättre iofs, men ska du bara blinka med en diod så spelar det ingen roll. Testa båda sätten.
Jag har nu läst i genom databladet
Får igen riktig kontroll över hur jag ska programmera för att jag ska få en subrutin som ger mig en delay tid på 1 sekund.ingen som kan ge mig ett exempel hur det skulle se ut med timer
OK, om du vill ha en *subrutin* där du "ligger kvar" under hela sekunden,
så är det enklast att avlusa dina loopar du hade först. Jag antog att
man vill ha processorn ledig för annat medans man väntar på att
sekunden ska gå...
Men i så fall :
> Movlw HFFFF
W-reg är *en* byte (8 bitar). Alltså MOVLW h'FF'
(Och för max delay kan du skriva MOVLW h'00'...
Den sista decfsz ska vara på delay2.
Sen kommer du sannolikt att behöva en delay3 och en "mellan_loop" också.
så är det enklast att avlusa dina loopar du hade först. Jag antog att
man vill ha processorn ledig för annat medans man väntar på att
sekunden ska gå...
Men i så fall :
> Movlw HFFFF
W-reg är *en* byte (8 bitar). Alltså MOVLW h'FF'
(Och för max delay kan du skriva MOVLW h'00'...
Den sista decfsz ska vara på delay2.
Sen kommer du sannolikt att behöva en delay3 och en "mellan_loop" också.
nej det vill jag inte utan en subrutin
Nej jag vill bara ha en subrutin som ger mig ca 1 sekund i fördröjning alltså. Som jag kan anropa från andra dela i programmet med instruktionen call delay typ. när man behöver en fördröjning mellan vissa saker i koden för att ögat ska hinna och reagera.
koden skulle alltså se ut enligt följande med en delay 3 till:
Movlw HFF
Movf delay3
yttre_loop2: Movlw HFF
Movf delay2
Yttre_ loop: Movlw HFF
Movf delay1
Inre _loop: Decfsz delay1
Goto inre_loop
Decfsz delay2
Goto Yttre_loop
Decfsz delay3
Goto Yttre_loop2
Return
Är det så här du menar. detta skulle bli 256*256'256 instruktioner=16777216 st
koden skulle alltså se ut enligt följande med en delay 3 till:
Movlw HFF
Movf delay3
yttre_loop2: Movlw HFF
Movf delay2
Yttre_ loop: Movlw HFF
Movf delay1
Inre _loop: Decfsz delay1
Goto inre_loop
Decfsz delay2
Goto Yttre_loop
Decfsz delay3
Goto Yttre_loop2
Return
Är det så här du menar. detta skulle bli 256*256'256 instruktioner=16777216 st
Senast redigerad av Markus 14 februari 2006, 10:00:55, redigerad totalt 1 gång.
-
- Inlägg: 2360
- Blev medlem: 16 september 2003, 17:18:13
- Ort: Dubai, United Arab Emirates
- Kontakt:
Här http://www.piclist.com/techref/piclist/ ... /delay.htm har du en kodgenerator som gör en fördröjningsrutin åt dig, det är bara att klistra in koden.
Du matar in hur lång fördröjningen ska vara i sekunder typ 0.8, vilken klockfrekvens som din uC kör på tex 12 Mhz och klickar på Generate! så vips har du fått den här koden att klistra in i ditt program.
Du matar in hur lång fördröjningen ska vara i sekunder typ 0.8, vilken klockfrekvens som din uC kör på tex 12 Mhz och klickar på Generate! så vips har du fått den här koden att klistra in i ditt program.
Kod: Markera allt
; Delay = 0.8 seconds
; Clock frequency = 12 MHz
; Actual delay = 0.8 seconds = 2400000 cycles
; Error = 1.94025536378e-014 %
cblock
d1
d2
d3
endc
Delay800mS
;2399990 cycles
movlw 0x47
movwf d1
movlw 0x3C
movwf d2
movlw 0x06
movwf d3
Delay800mS_0
decfsz d1, f
goto $+2
decfsz d2, f
goto $+2
decfsz d3, f
goto Delay800mS_0
;6 cycles
goto $+1
goto $+1
goto $+1
;4 cycles (including call)
return
http://www.teknikutbildning.se/default.html finns också, men man lär sig inte mycket på det sättet...
ok,vart är mellan slaget på denna label
yttre_loop2 tex igenstans. förstår inte vad du menar. Men har jag rätt om vi bortser från bagateller som mellan slag att detta program kommer att göra ca 256*256*256 instruktioner. Ska bara kolla så jag tänker rätt.Ska simulera senare skulle bara kolla så jag är inne på rätt bana. Så jag fattar sodjan vad han menar med en tredje loop och avlusning av min kod.
är fortfarande bara grönjöling inom micropic prog men vill lära mig.därför frågar jag en del. Tex fattde inte riktig hur sodjan vill att jag kunde göra en delayer av timer. När jag ville bara ha en subrutin som jag kan anropa när jag vill för att skapa en sekunds fördröjning.
Men går det att skapa med timer så är jag mycket intresserad att se hur detta fungerar.
är fortfarande bara grönjöling inom micropic prog men vill lära mig.därför frågar jag en del. Tex fattde inte riktig hur sodjan vill att jag kunde göra en delayer av timer. När jag ville bara ha en subrutin som jag kan anropa när jag vill för att skapa en sekunds fördröjning.
Men går det att skapa med timer så är jag mycket intresserad att se hur detta fungerar.
"Yttre_ loop" och "Inre _loop" <-- Ser du nu?
. Föresten är det ingen bagatell, för koden kommer inte funka.
Du har fortfarande inte svarat på klockhastigheten...
EDIT: Jag roade mig med att skriva om din kod lite. Nu borde den iaf gå igenom MPLAB...Har inte testat än dock.

Du har fortfarande inte svarat på klockhastigheten...
EDIT: Jag roade mig med att skriva om din kod lite. Nu borde den iaf gå igenom MPLAB...Har inte testat än dock.
Kod: Markera allt
delay movlw hff
movwf delay3
yloop2 movlw hff
movwf delay2
yloop movlw hff
movwf delay1
iloop decfsz delay1,f
goto iloop
decfsz delay2,f
goto yloop
decfsz delay3,f
goto yloop2
return
> Nej jag vill bara ha en subrutin som ger mig ca 1 sekund i fördröjning alltså.
OK. det *normala* är att man inte vill "låsa up" processorn under tiden,
utan att den kan göra andra saker under tiden. Det var det jag menade.
> Tex fattade inte riktig hur sodjan vill att jag kunde göra en delayer av timer.
Enkelt, genom att läsa på om timers och interrupt...
Här är en enkel Blink-a-LED som använder en timer.
Koden är för en PIC16, så du får justera lite. Principerna bör du dock
kunna läsa ut. :
> Ska bara kolla så jag tänker rätt.Ska simulera senare
Varför inte göra tvärt om ? Simulera först, då kanske du t.o.m inte alls behöver posta den...
OK. det *normala* är att man inte vill "låsa up" processorn under tiden,
utan att den kan göra andra saker under tiden. Det var det jag menade.
> Tex fattade inte riktig hur sodjan vill att jag kunde göra en delayer av timer.
Enkelt, genom att läsa på om timers och interrupt...

Här är en enkel Blink-a-LED som använder en timer.
Koden är för en PIC16, så du får justera lite. Principerna bör du dock
kunna läsa ut. :
Kod: Markera allt
;**********************************************************************
; Enkelt blink-a-led, 16F870. *
; *
;**********************************************************************
; Files required: P16F870.INC *
; 16F870.LNK *
; *
;**********************************************************************
list p=16f628A
#include <p16f628A.inc>
__CONFIG _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT
RESET_VECTOR CODE 0x000 ; processor reset vector
goto start ; go to beginning of program
INT_VECTOR CODE 0x004 ; interrupt vector location
goto isr_routine ; goto main interrupt service routine.
MAIN CODE
start
; banksel adcon1
; movlw h'06'
; movwf adcon1 ; Stäng av ADC.
banksel cmcon
movlw h'FF' ; Shut off A/D-stuff value
movwf CMCON ; No A/D-stuff
banksel trisa
clrf trisa
clrf trisb
; clrf trisc ; Alla pinnar = utgångar.
banksel t1con
movlw b'00110001'
movwf t1con ; Se datablad...
banksel pie1
movlw b'00000001'
movwf pie1 ; Enable avbrott från TMR1.
banksel intcon
bsf intcon, peie
bsf intcon, gie ; Enable avbrott...
loop
goto loop ; Vänta på avbrott...
ISR_ROUTINE CODE
isr_routine
banksel portb
comf portb ; Blinka !!
banksel pir1
bcf pir1, tmr1if ; clear avbrotts flagga.
retfie
END
> Ska bara kolla så jag tänker rätt.Ska simulera senare
Varför inte göra tvärt om ? Simulera först, då kanske du t.o.m inte alls behöver posta den...
