Sida 4 av 4
Postat: 9 november 2008, 15:48:48
av sodjan
> Vad fyller ''OffDelayLoop'' för funktio? Kan man inte bara lägga till lite delay i slutet av ''OndelayLoop''?
Du måste ju ha en "delay" både när lysdioden är tänd och då den är släckt.
Annars kommer den bara ett släckas väldigt kort tid och tändas direkt igen.
> Varför fins det 2 stycken ''goto OndelayLoop'' i ''OndelayLoop''
Första GOTO körs tills "decfsz Delay1, f " blir = 0.
> borde inte lampan lysa hela tiden...
Lysdioden är tänd tills "decfsz Delay2, f" blir = 0.
D.v.s att :
Kod: Markera allt
OndelayLoop:
decfsz Delay1,f ; Waste time.
goto OndelayLoop
körs tills Delay1 = 0.
Sedan minskas Delay2 med 1 och ovanstående körs om tills Delay1 blir = 0 igen.
Första GOTO körs alltså 256 gånger för varje gång som Delay2 minskas med 1.
När även Delay2 är = 0, så är fördröjningen klar.
Postat: 9 november 2008, 16:08:33
av sodjan
Här är en version med *en* DelayLoop istället för två.
Det blir lite färre instruktioner och lite tydligare kod.
Jag tog bara med själva koden, resten är samma...
Kod: Markera allt
Start:
bsf STATUS, RP0 ; select Register Page 1
bcf TRISC, 0 ; make IO Pin B.0 an output
bcf STATUS, RP0 ; back to Register Page 0
MainLoop:
bsf PORTC, 0 ; turn on LED C0
call DelayLoop
bcf PORTC, 0 ; Turn off LED C0
call DelayLoop
goto MainLoop ; Do it again...
DelayLoop:
decfsz Delay1, f
goto DelayLoop
decfsz Delay2, f
goto DelayLoop
return
end
Postat: 9 november 2008, 16:09:50
av Marta
Med reservation för att jag inte är så van vid PIC standard-assembler och
kan ha gjort något korkat syntaxfel så borde det gå att göra såhär:
Kod: Markera allt
.
#include <p16F690.inc>
__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
cblock 0x20
Delay1 ; Define two file registers for the
Delay2 ; delay loop
Delay3
endc
org 0
; this code setup the port as an output on PORTC bit 0
Start:
bsf STATUS,RP0 ; select Register Page 1
bcf TRISC,0 ; make IO Pin B.0 an output
bcf STATUS,RP0 ; back to Register Page 0
MainLoop:
; first blink
bsf PORTC,0 ; turn on LED C0
movlw 5 ; wait five-tenths of a second.
call DelayLoop
bcf PORTC,0 ; Turn off LED C0
movlw 5 ; wait five-tenths of a second.
call DelayLoop
; second blink
bsf PORTC,0 ; turn on LED C0
movlw 5 ; wait five-tenths of a second.
call DelayLoop
bcf PORTC,0 ; Turn off LED C0
movlw 5 ; wait five-tenths of a second.
call DelayLoop
; third blink
bsf PORTC,0 ; turn on LED C0
movlw 5 ; wait five-tenths of a second.
call DelayLoop
bcf PORTC,0 ; Turn off LED C0
movlw 5 ; wait five-tenths of a second.
call DelayLoop
movlw 50 ; wait five seconds
call DelayLoop
goto MainLoop ; Do it again...
; Wait number of 1/10 seconds in w
DelayLoop:
movwf Delay3 ; Set variable delay counter
bsf Delay2,7 ; Shorten two inner loops to about 1/10 second
DelayLoop1:
decfsz Delay1,f ; Waste time.
goto DelayLoop1 ; The Inner loop takes 3 instructions per loop * 256 loopss = 768 instructions
decfsz Delay2,f ; The outer loop takes and additional 3 instructions per lap * 256 loops
goto DelayLoop1 ; (768+3) * 128 / 1M instructions per second
decfsz Delay3,f ; call it a one-tenths of a second.
goto DelayLoop1
return
end
Postat: 9 november 2008, 17:20:22
av sodjan
Det är bara att köra den i MPSIM med "Stopwatch" på så ser man
både att/om det fungerar och vilka blinktider man får...
*Lite* kortare blir det om man gör:
Kod: Markera allt
MainLoop:
; first blink
bsf PORTC,0 ; turn on LED C0
call delayLoop_5 ; wait five-tenths of a second.
bcf PORTC,0 ; Turn off LED C0
call delayLoop_5 ; wait five-tenths of a second.
; second blink
bsf PORTC,0 ; turn on LED C0
call delayLoop_5 ; wait five-tenths of a second.
bcf PORTC,0 ; Turn off LED C0
call delayLoop_5 ; wait five-tenths of a second.
; third blink
bsf PORTC,0 ; turn on LED C0
call delayLoop_5 ; wait five-tenths of a second.
bcf PORTC,0 ; Turn off LED C0
call delayLoop_5 ; wait five-tenths of a second.
movlw 50 ; wait five seconds
call DelayLoop
goto MainLoop ; Do it again...
DelayLoop_5
mowlw 5
call DelayLoop
return
; Wait number of 1/10 seconds in w
DelayLoop:
movwf Delay3 ; Set variable delay counter
bsf Delay2,7 ; Shorten two inner loops to about 1/10 second
DelayLoop1:
decfsz Delay1,f ; Waste time.
goto DelayLoop1 ; The Inner loop takes 3 instructions per loop * 256 loopss = 768 instructions
decfsz Delay2,f ; The outer loop takes and additional 3 instructions per lap * 256 loops
goto DelayLoop1 ; (768+3) * 128 / 1M instructions per second
decfsz Delay3,f ; call it a one-tenths of a second.
goto DelayLoop1
return
end
Eller för den delen :
Kod: Markera allt
MainLoop:
; blink three times
call One_Blink
call One_Blink
call One_Blink
call DelayLoop_50
goto MainLoop ; Do it again...
One_Blink
bsf PORTC,0 ; turn on LED C0
call delayLoop_5 ; wait five-tenths of a second.
bcf PORTC,0 ; Turn off LED C0
call delayLoop_5 ; wait five-tenths of a second.
return ; <<== Hade missat denna...
DelayLoop_5
mowlw 5
goto DelayLoop
Delayloop_50
mowlw 50
; Wait number of 1/10 seconds in w
DelayLoop:
movwf Delay3 ; Set variable delay counter
bsf Delay2,7 ; Shorten two inner loops to about 1/10 second
DelayLoop1:
decfsz Delay1,f ; Waste time.
goto DelayLoop1 ; The Inner loop takes 3 instructions per loop * 256 loopss = 768 instructions
decfsz Delay2,f ; The outer loop takes and additional 3 instructions per lap * 256 loops
goto DelayLoop1 ; (768+3) * 128 / 1M instructions per second
decfsz Delay3,f ; call it a one-tenths of a second.
goto DelayLoop1
return
end

Postat: 9 november 2008, 18:08:28
av Marta
Tar man bort return från DelayLoop_5 och låter den falla igeom så blir det ännu
kortare och framför allt så sparas en stacknivå. Är där flera fastatider så kan
goto användas efter att ha satt w istället för call så sparas också då en
stacknivå. Okritiskt här, men helt avgörande om det ligger på gränsen till att
stacken skall slå runt.
Postat: 9 november 2008, 19:03:28
av AndersG
Kod: Markera allt
OndelayLoop:
decfsz Delay1,f ; Waste time.
goto OndelayLoop ; The Inner loop takes 3 instructions per loop * 256 loopss = 768 instructions
decfsz Delay2,f ; The outer loop takes and additional 3 instructions per lap * 256 loops
goto OndelayLoop ; (768+3) * 256 = 197376 instructions / 1M instructions per second = 0.197 sec.
; call it a two-tenths of a second.
Det står precis varför i kommentarerna.Först snurrar den och minskar delay1, sedan minskar den delay två med ett och går tillbaka. Då får du en fördröjning om delay1*delay2.
Tack!
Postat: 9 november 2008, 19:06:12
av Alex_k
Tack så jättemycket för era fantastiska svar!

Nu börjar jag genast förstå väldigt mycket mer!

Ni har skrivit så många olika alternativ.

Det var precis det här jag behövde för att få en bra start på hur man programerar med assembler.

Jag tror själv att jag ska glömma bort det där med BASIC och enbart jobba med assembler för det verkar mycket bättre och roligare.

Tack igen för era underbara svar!

Jag återkommer om jag stöter på probem (vilket jag inte tror kommer ske)
TACK!

Postat: 9 november 2008, 20:45:56
av sodjan
> Jag återkommer om jag stöter på probem (vilket jag inte tror kommer ske)
Ha !
Och jultomten finns på riktigt, säger en del...
Jag har även rättat ett skit-fel i min sista kod.
Och gjort de ändringar som föreslogs av Marta...
Postat: 9 november 2008, 22:19:36
av Alex_k
Som du sa så har jag redan 2 nya frågor att ställa den första är kan jag paralellkoppla två lysdioder på samma port eller måste jag skriva programmet så två olika portar gör samma sak?
Den andra är kan jag programera vilken prossesor som helst med mitt PICKIT 2 genom att bara ändra en inställning i MBLAB IDE?
Postat: 9 november 2008, 23:21:53
av sodjan
Du kan programmera de processorer som dokumentationen
till PICkit2 säger att du kan programmera, så klart.
Sen så måste ju koden i sig också gå att köra på den aktuella
processorn, men det är ju självklart...
> kan jag paralellkoppla två lysdioder på samma port...
Ja, med var sitt motstånd. Och så att de tillsammans inte överskrider
max ström för en I/O pinne, normalt 25 mA.
Postat: 10 november 2008, 07:24:41
av AndersG
Ett litet tips bara, Alex: Det finns massvis med bra exempelkof man kan lära sig av, tex här:
http://www.piclist.com/techref/piclist/index.htm
Att gå igenom och analysera andras kod kan vara verkligt lärorikt.