Pickit2 varför fungerar min kod?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
zood
Inlägg: 9
Blev medlem: 8 november 2011, 21:19:51

Pickit2 varför fungerar min kod?

Inlägg av zood »

Hej
Jag sitter och experimenterar lite med mitt Pickit2 och skulle behöva hjälp med att förstå följande kod. Jag har försökt att göra ett program som tänder en lysdiod på demokortet när man håller inne knappen.
Den första koden jag skrev fungerade inte som jag ville men efter att jag ändrade om lite så funkade det men jag fattar inte varfö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)
     org 0


Start:
      
     bsf       STATUS,RP0          ; select Register Page 1
     movlw     0xFF
     movwf     TRISA               ; Make PortA all input
     clrf      TRISC               ; Make PortC all output

     bcf       STATUS,RP0          ; address Register Page 2
     bsf       STATUS,RP1     
     movlw     0xF7                ; PortA3 pin is digital
     movwf     ANSEL
     bcf       STATUS,RP0          ; address Register Page 0
     bcf       STATUS,RP1
  
	bcf PORTC,0

loop:                     ;Denna loopen är till för att kolla om knappen blir nertryckt
   btfsc PORTA,3     ;Här tycker jag att det borde stå "btfss PORTA,3" men då blir det motsatt effekt och man släcker dioden
   goto loop                
   bsf PORTC,0        ;Ska tända dioden om knappen blir tryckt på

   end
Så denna koden gör att när jag håller inne knappen så tänder sig lysdioden och när jag släpper så släcks den. Vill jag tända lysdioden igen så är det bara att hålla inne knappen igen och så kan jag göra hur många gånger som helst.

Om man börjar med loopen så tycker jag att det borde vara "btfss PORTA,3" istället för "btfsc PORTA,3".
Det är ju meningen att den ska kolla om PORTA,3 är "set" och isåfall "skippa" nästa rad (goto loop-raden). Men jag måste skriva tvärtom för att få det att funka, varför det?

Sedan så förstår jag inte varför programmet loopar om sig om och om igen. Jag förväntade mig att det bara skulle fungera en gång. Jag väntade mig att programmet skulle vänta på att knappen blev intryckt och då tända lysdioden och sen ta slut men programmet släcker lysdioden när man släpper knappen igen och det förstår jag inte riktigt varför? :humm:

Skulle vara jättetacksam om någon tog sig tid att hjälpa en stackars nybörjare :)

/zood
Användarvisningsbild
Klas-Kenny
Inlägg: 11843
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Pickit2 varför fungerar min kod?

Inlägg av Klas-Kenny »

Ett program får aldrig ta slut!

Nu vet jag inte helt hundra hur microprocessorn reagerar på ett program som tar slut, men jag tror att den börjar om från början.

Sätter du tex:

endlessloop:
goto endlessloop

På slutet, så kommer programmet fungera som du väntar dig.
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4750
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Re: Pickit2 varför fungerar min kod?

Inlägg av Swech »

Dina tryckknappar sluter nog säkerligen mot jord, så när du trycker på knappen blir det
"0" på porten

Programmet slutar med END
Vart skall det ta vägen då?
Jo det fortsätter köra instruktione och kommer tillslut tillbaks till början igen då den gått igenom
hela minnet på processorn.

Swech
zood
Inlägg: 9
Blev medlem: 8 november 2011, 21:19:51

Re: Pickit2 varför fungerar min kod?

Inlägg av zood »

Ja swech du har rätt min tryckknapp sluter mot jord när jag kollat efter.

Klas-kenny om jag lägger till
endlessloop:
goto endlessloop
i slutet så lyser dioden konstant istället, alltså även om jag inte tryckt på knappen.
Jag testade att ta bort bsf PORTC,0 som ligger efter min loop och då är lysdioden släckt från början.
Så det verkar som picen tar sig igenom loopen

Kod: Markera allt

loop:
    btfsc PORTA,3
    goto loop
oavsett om knappen trycks in eller inte.

Hur kan det bli så? :S
Användarvisningsbild
Klas-Kenny
Inlägg: 11843
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Pickit2 varför fungerar min kod?

Inlägg av Klas-Kenny »

Posta hela koden, svårt att vara säker på hur du skrivit annars. :)
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Pickit2 varför fungerar min kod?

Inlägg av sodjan »

Flera har gett bra tips. Det jag skulle vilja lägga till är att en kod som
denna är väldigt enkel att felsöka i MPSIM. Du kan simulera din
knapp med och stega dig igenom instruktion för instruktion.

Det som kan vara svårt att simulera är kontaktstudsar. Jag vet inte
om det eventuellt är ett problem för just din kod, det får du
fundera på. Vad händer om en tryckning på knappen i själva verket
är 10-20 tryckningar i snabb följd, inom ca 20-50 ms ?
zood
Inlägg: 9
Blev medlem: 8 november 2011, 21:19:51

Re: Pickit2 varför fungerar min kod?

Inlägg av zood »

Hej igen tack för era tips! Jag har fortfarande inte riktigt fått grepp på det här :)

Klas-kenny här är hela koden som jag har skrivit:

Kod: Markera allt

#include <p16F690.inc>
     __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
     org 0


Start:
      
     bsf       STATUS,RP0          ; select Register Page 1
     movlw     0xFF
     movwf     TRISA               ; Make PortA all input
     clrf      TRISC               ; Make PortC all output

     bcf       STATUS,RP0          ; address Register Page 2
     bsf       STATUS,RP1     
     movlw     0xF7                ; PortA3 pin is digital
     movwf     ANSEL
     bcf       STATUS,RP0          ; address Register Page 0
     bcf       STATUS,RP1
  
	bcf PORTC,0
loop:
   btfsc PORTA,3
   goto loop

   bsf PORTC,0

endlessloop:	
	goto endlessloop
	
    end
Jag har testat att köra i MPLAB Sim. Jag har uppe en ruta som heter "Special functions register" samtidigt som jag simulerar programmet.
Där kan man se dom olika värdena på registrerna. När programmet kommer till raden bsf PORTC,0 så ändrar sig inte värdet på PORTC utan är fortfarande 0x00.

Nu när jag kollar lite närmare så ser jag att värdet för TRISA inte ändrar sig heller.
I mitt program så ska TRISA få värdet 0xFF för att alla PORTA ska bli ingångar men "special functions register"-rutan säger att TRISA har värde 0x3F.
Kan det vara fel på mitt sätt att initiera programmet?
Har läst i andra trådar på forumet att flera av er sagt att det är bättre att använda banksel istället för att använda sig av bsf STATUS,RP0.

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

Re: Pickit2 varför fungerar min kod?

Inlägg av sodjan »

Du har stängt av alla analoga funktioner ?
Notera att för en pinne som har sin analoga funktion påslagen
så visas den alltid som "0" i MPSIM eftersom det är så den läses.
Själva den fysiska *pinnen* kan dock fortfarande var "1".

Enklast att bara göra :

Kod: Markera allt

  clrf   ansel
  clrf   anselh
så behöver du inte tänka mer på det.

Och sätt inte RP0/1 manuellt, använd BANKSEL. Alltså :

Kod: Markera allt

     banksel   TRISA
     movlw     0xFF
     movwf     TRISA               ; Make PortA all input
     clrf      TRISC, f            ; Make PortC all output

     banksel   ANSEL
     clrf      ANSEL, f            ; All pins digital
     clrf      ANSELH, f           ; All pins digital

     banksel   porta
     bcf       PORTC, 0
Sen så bör du inte göra pinnar till "digital input" som du inte använder/ansluter.
Gör dom till output...
ToPNoTCH
Inlägg: 5152
Blev medlem: 21 december 2009, 17:59:48

Re: Pickit2 varför fungerar min kod?

Inlägg av ToPNoTCH »

Om det nu är pullup på RA3 så funkar koden.

(Jag testade den själv på skoj)

Delvis...För det finns inget som släcker dioden när du släpper knappen igen.
AndersL
EF Sponsor
Inlägg: 148
Blev medlem: 17 september 2004, 21:39:22
Ort: Ängelholm

Re: Pickit2 varför fungerar min kod?

Inlägg av AndersL »

Jag kanske missförstår något, men oftast vill man ju kunna köra programmet flera gånger. Om man bara vill kunna tända lysdioden en gång så är detta ok, men vill man ha funktionen att lysdioden är tänd när knappen är intryckt behöver man ju gå tillbaka till raden där lysdioden släcks (bcf PORTC,0) och köra loopen där knappen kollas.
zood
Inlägg: 9
Blev medlem: 8 november 2011, 21:19:51

Re: Pickit2 varför fungerar min kod?

Inlägg av zood »

TopNotch och AndersL, Jag skulle skriva ett program som släckte dioden och sen kunde tända dioden igen.
Men när jag kommit halvvägs så kompilerade jag för att testa hur programmet fungerade så långt så funkade inte programmet som jag förväntat mig och därav trådstarten :)

Jag har testat att köra programmet i MPLAB SIM igen nu när jag lärt mig hur man simulerar ett knapptryck på PORTA3 och programmet fungerar ju som det ska precis som du säger topnotch.
Däremot när jag laddar in programmet i PICen så beter det sig annorlunda..

Kod: Markera allt

#include <p16F690.inc>
     __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
     org 0


Start:
      
      banksel   TRISA
     movlw     0xFF
     movwf     TRISA               ; Make PortA all input
     clrf      TRISC                 ; Make PortC all output

     banksel   ANSEL
     clrf      ANSEL            ; All pins digital
     clrf      ANSELH           ; All pins digital

     banksel   PORTA
  
   bcf PORTC,0
loop:
   btfsc PORTA,3
   goto loop

   bsf PORTC,0

endlessloop:   
   goto endlessloop
   
    end
Om jag kör detta programmet i simulatorn så fungerar det som tänkt att det väntar på att PORTA,3 ska blir clear och då skippa loopen och tända dioden och sedan fastna i "endlessloop"-loopen.
Men kör jag programmet i PICen så tänder sig dioden med en gång. Den verkar strunta i BTFSC och kör rakt igenom loopen :P
Det är så det verkar iallafall men det borde ju inte kunna hända 8)
För att undvika detta måste jag göra en mainloop och låta programmet börja om från början.
På så sätt så släcker sig dioden igen när man släppt knappen och man kan tända den på nytt..som det var tänkt från början! :)

Jag tror jag släpper det här nu och går vidare..Jag kanske kommer förstå mig på vad jag gör för fel längre fram när man fått lite djupare kunskaper..

Tack så mycket för hjälpen allihopa jag har lärt mig en hel del tack vare er! :tumupp:
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Pickit2 varför fungerar min kod?

Inlägg av sodjan »

Bara för att cleara ett par saker...

Hårdvaran är alltså PICkit2 med labbkortet med en 16F690 ?
Och "knappen" är den befintliga "reset-knappen" på labkortet ?

Egentligen så är inte en knapp på just RA3 (som ju även är reset/MCLR ingång)
den mest lämpliga nybörjarkopplingen. Det ger upphov till lite "övningar" som är
överkurs just nu. Du har MCLR avstängt ser jag (_PWRTE_OFF) och det är ju en
grundförutsättning för att det ska fungera alls. Helt OK alltså.

Det *kan* vara ett timing rellaterat fenomen mellan att PICkit2 "släpper" MCLR
pinnen och att din kod försöker läsa av den.

Bara som en enkel test, prova att byta "_PWRTE_OFF" mot "_PWRTE_ON".
Det ger en kort (ca 72 ms har jag för mig) delay innan koden går igång.
PopUnoNkoK
Inlägg: 789
Blev medlem: 10 december 2007, 12:40:08
Ort: Piteå

Re: Pickit2 varför fungerar min kod?

Inlägg av PopUnoNkoK »

Jag kollade databladet på Lowpincount Demoboard.
Om jag förstår det hela rätt så har du ett antal oanslutna ingångar. (Öppna inngångar).

Du har satt hela PORTA till Ingångar. (TRISA = 0xFF, Jag skulle heldre skrivit b'11111111')
Kollar man schemat (sida 12 i PDFens sidnummrering)i till Demoboarden så är RA0, RA1, RA2, RA4, RA5 oanslutna.

Sätt bara den BIT i PORTA till ingång som du har tänkt använda till ingång. De andra till utgång.
Detta skulle kunna avhjälpa ditt problem

MVH Peter F
labmaster
Inlägg: 2919
Blev medlem: 5 april 2011, 01:10:25

Re: Pickit2 varför fungerar min kod?

Inlägg av labmaster »

Det finns flera sätt att lösa tänd och släck av en diod med en knapp men generellt sett skall du göra en huvudloop som innehåller en loop där du pollar knappen och stannar i denna så länge knappen inte är intryckt (off). Direkt efter den lämnat loopen gör du en delayfunktion med lämpligt tidintervall. När tiden är passerad kollar du knappen igen, är den fortfarande nedtryckt så tänder du lysdioden och startar en ny loop som väntar på att knappen släpps. När loopen finner att knappen är släppt skall den lämna loopen och släcka dioden. När den släckt dioden skall den vänta med samma tidintervall som tidigare för att ta hand om kontaktstudsar innan nästa varv i huvudlopen.

Så här kan det se ut, "While (true)" är den "endless loop" som alltid skall finnas i uC sammanhang utan operativsystem.

Kod: Markera allt

setupRegistersAndPorts();

While (true) {

   While (!knapp) {} // utropstecken knapp betyder not knapp

   delay();

   if (knapp) {
      ledOn();
      While (knapp == 1) {}
      ledOff();
      delay();
   }

}
Ovanstående programkod är en principbeskrivning och du får själv översätta den till assemblerkod.
zood
Inlägg: 9
Blev medlem: 8 november 2011, 21:19:51

Re: Pickit2 varför fungerar min kod?

Inlägg av zood »

Sodjan: Ja, det är ett Pickit2 Starter kit som jag köpt på elfa. Jag har inte pillat eller modifierat nånting så allt är orginal.
Jag testade att ändra till "_PWRTE_ON" men jag fick samma resultat..

Har testat att sätta alla bitar förutom RA3 som ingång som PopUnoNkoK skrev men det hjälpte inte heller :humm:
Skriv svar