En lite anorlunda blik kod

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 7487
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Inlägg 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






sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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
:-)
Senast redigerad av sodjan 9 november 2008, 20:49:57, redigerad totalt 1 gång.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 7487
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Inlägg 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.
Användarvisningsbild
AndersG
EF Sponsor
Inlägg: 9127
Blev medlem: 25 februari 2008, 17:10:58
Ort: Mariehamn
Kontakt:

Inlägg 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.
Alex_k
Inlägg: 43
Blev medlem: 6 oktober 2008, 16:25:37
Ort: stockholm

Tack!

Inlägg av Alex_k »

Tack så jättemycket för era fantastiska svar! :D Nu börjar jag genast förstå väldigt mycket mer! :D Ni har skrivit så många olika alternativ. :D Det var precis det här jag behövde för att få en bra start på hur man programerar med assembler. :D 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. :D Tack igen för era underbara svar! :D Jag återkommer om jag stöter på probem (vilket jag inte tror kommer ske)
TACK! :wink:
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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...
Alex_k
Inlägg: 43
Blev medlem: 6 oktober 2008, 16:25:37
Ort: stockholm

Inlägg 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?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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.
Användarvisningsbild
AndersG
EF Sponsor
Inlägg: 9127
Blev medlem: 25 februari 2008, 17:10:58
Ort: Mariehamn
Kontakt:

Inlägg 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.
Skriv svar