PIC16F690 och förmodad tankevurpa hos mig

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
MrIzoard
Inlägg: 339
Blev medlem: 25 september 2011, 15:33:08
Ort: Göteborg

PIC16F690 och förmodad tankevurpa hos mig

Inlägg av MrIzoard »

Hej igen!

Dags för nästa nybörjarfråga.....

Så här ser mitt program ut:

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
d1                    ; variabel för delayloopen
d2                    ; variabel för delayloopen
d3                    ; variabel för delayloopen
     endc
     
     org 0
Start:
    banksel    TRISA    ; väljer rätt registerbank för att sätta trisa
    movlw      0x02     ; sättar RA1 till ingång och RA0, RA2, RA3, RA4 samt RA5 till utgångar
    movwf      TRISA
    banksel    PORTA    ; väljer rätt registerbank för att styra ut porta
    movlw      0x01     ; sätter RA0 till 1 sätter alla andra utgångar på PORTA till 0
    movwf      PORTA

Loop:
    call       Delay2s
    btfsc      PORTA,1    ; kollar om RA1 är 1 (då har vi mycket vatten), om 1 så skall vi inte göra något 
    goto       Loop    

Rela:
    movlw      0x05    ; sätter RA0 och RA2 till 1
    movwf      PORTA
    call       Delay2s
    movlw      0x01    ; sätter RA0 till 1
    movwf      PORTA
    goto       Loop

Delay2s:
    movlw      0x11
    movwf      d1
    movlw      0x5D
    movwf      d2
    movlw      0x05
    movwf      d3
Delay_2s
    decfsz     d1, f
    goto       $+2
    decfsz     d2, f
    goto       $+2
    decfsz     d3, f
    goto       Delay_2s
    goto       $+1    ; 4 cykler
    goto       $+1

    return
     end
Det som händer är att jag hela tiden kommer ner till delen Rela oavsett om RA1 är 0 eller +5 V.

Är det någon vänlig själ som kan säga var jag körde i diket för någonstans?

M.v.h.
Ulf L.
Användarvisningsbild
Icecap
Inlägg: 26652
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: PIC16F690 och förmodad tankevurpa hos mig

Inlägg av Icecap »

Din initiering är synnerligt bristfällig! Kolla noga under PORTA och analoga funktioner, dom måste du stänga av!
Användarvisningsbild
Klas-Kenny
Inlägg: 11843
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: PIC16F690 och förmodad tankevurpa hos mig

Inlägg av Klas-Kenny »

EDIT: Det var inget, feltänk av mig.
MrIzoard
Inlägg: 339
Blev medlem: 25 september 2011, 15:33:08
Ort: Göteborg

Re: PIC16F690 och förmodad tankevurpa hos mig

Inlägg av MrIzoard »

Man tackar och bockar!

Jag adderade följande rader i koden:

Kod: Markera allt

banksel ANSEL
clrf    ANSEL
då hände det grejer.
Måste se till att skriva ut databladet och läsa igenom det, jag klarar verkligen inte gå igenom det på skärmen.

Är det något mer fundamentalt dumt i koden som jag bör åtgärda?

M.v.h.
Ulf L.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: PIC16F690 och förmodad tankevurpa hos mig

Inlägg av sodjan »

Felet i detta fall har ju med slarv (eller andra brister) i studerandet av en enda
sida i databladet, sidan 59 med "4.1 PORTA and the TRISA Registers". Där finns
en liten grå ruta som är kollosalt kritisk (kanske det viktigaste i hela databladet!)
som du uppenbarligen har missat. :-)

> Måste se till att skriva ut databladet...

Ja det inte en dum ide i alla fall för den första processorn man jobbar med.
Senare går det snabbare att hitta rätt även direkt i PDF'erna.
Databladen är väldigt lika från en processor till en annan.

Men printa inte ut *allt*. Börja med de delar som är centrala.

För en 16F690 så skulle det räcka med t.ex :

1.0 DEVICE OVERVIEW
2.0 MEMORY ORGANIZATION
3.0 OSCILLATOR MODULE (WITH FAIL-SAFE CLOCK MONITOR)
4.0 I/O PORTS
14.0 SPECIAL FEATURES OF THE CPU

Sedan kompletterar man när det uppstår behov med de olika
kapitlen 5-13 för de olika "enheterna". Det finns inget i dom som
du *måste* läsa så länge som du inte använder dom.

15.0 INSTRUCTION SET SUMMARY kan du ha som en referens.

16.0 DEVELOPMENT SUPPORT har jag nog aldrig läst. Har man en
programmerare så har den sin egen dokumentation.

Kap 17 och 18 (alla elektriska detaljer) är knappast direkt kritiska
till en början och jag har nog aldrig skrivit ut dom i alla fall.

Så som du ser så är det inte speciellt mycket som hör till de delar som
gemensamt oberoende av vad man gör och som hör till de delar som
man absolut måste kunna.
Användarvisningsbild
Icecap
Inlägg: 26652
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: PIC16F690 och förmodad tankevurpa hos mig

Inlägg av Icecap »

Jag använder numera bara PDF-filer med databladen, jag har en stor bibliotek med allt jag kan behöva. Hemma har jag två datorer bredvid varandra, den ena programmerar & CAD'dar jag på och den andra sköter e-mail och dylikt - samt visning av datablad!

På det jobb jag förhoppningsvis mycket snart får blir det en dator med två skärmar, just för detta med datablad.

Enligt utredningen har jag så dåligt arbetsminne att om jag ska växla sida för att se något i databladet har jag glömt det när jag ska skriva in det i programmet/rita i CAD'en.
MrIzoard
Inlägg: 339
Blev medlem: 25 september 2011, 15:33:08
Ort: Göteborg

Re: PIC16F690 och förmodad tankevurpa hos mig

Inlägg av MrIzoard »

Istället för att starta en ny tråd så fortsätter jag med en ny fråga här.

Jag har kopplat upp min PIC16F690 på ett kopplingsbord till en 7-segments LED-display med tre tecken.
Uppkopplingen mellan aktuella pinnar på PIC'en och displayen fungerar (har matat positionerna på pinnarna där PIC'en skall sitta manuellt och sett att det stämmer).

Tanken med mitt bifogade program är att räkna upp displayen på position 3 från 1 till 3 (ungefär 1 sekund på varje tecken) och när jag gjort detta 5 gånger så skall jag visa siffran 1 på displayen på position 1. Sedan fortsätter displayen på position 3 räkna från 1 till 3.

Som det fungerar nu är att displayen på position 3 räknar från 1 till 3 och det sker ingenting efter 5 gånger utan position 3 räknar bara vidare och vidare.
Det är ju något i min snurra som kollar värdet på variabeln, alt. variabeln som inte är som den skall.

Finns det någon vänlig själ som kan upplysa mig om vad jag gör för fel?
På tala gärna alla dumma saker ni ser i koden.

Kod: Markera allt

    list      p=16f690
#include <p16F690.inc>
     __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)

     cblock     0x20
        Delay1                ; Variabel Delay1
        Delay2                ; Variabel Delay2
        Delay3                ; Variabel Delay3
        Raknare               ; Variabel Raknare, räknar upp 
     endc
     org 0
Start:
        banksel    TRISC           ; Gör det möjligt att ställa in TRISC
        movlw      0x80            ; RC7 = ingång, RC6 - RC0 = utgångar
        movwf      TRISC
        banksel    TRISA           ; Gör det möjligt att ställa in TRISA
        movlw      0xF8            ; RA7 - RA3 = ingångar, RA2 - RA0 = utgångar
        movwf      TRISA
        banksel    ANSEL
        clrf       ANSEL
        movlw      0x00
        movwf      Raknare         ; Lägger in värdet 0 i variabeln Raknare

Rakna:
        movf       Raknare,0       ; Laddar Raknare i arbetsregistret
        xorlw      0x05            ; Kollar om Raknare är 5
        btfsc      STATUS,Z    
        goto       Testa           ; Hoppar till Testa om Raknare = 5

Test_Display1:
        banksel    PORTA
        movlw      0xFB            ; Väljer Display 3 genom att nollställa RA2 (1111 1011)
        movwf      PORTA
        banksel    PORTC
        movlw      0x06            ; Tänder siffran 1 på Display 3
        movwf      PORTC
        call       Delay           ; Skickar in en fördröjning
        movlw      0x00            ; Nollställer Display 3
        movwf      PORTC
        movf       Raknare,0       ; Laddar Raknare i arbetsregistret
        addlw      0x01            ; Lägger till värdet 1 till Raknare, resultat i arbetsregistret
        movwf      Raknare         ; Laddare Raknare med värdet i arbetsregistret

Test_Display2:
        banksel    PORTA
        movlw      0xFB            ; Väljer Display 3 genom att nollställa den
        movwf      PORTA
        banksel    PORTC
        movlw      0x5B            ; Tänder siffran 2 på Display 3
        movwf      PORTC
        call       Delay           ; Skickar in en fördröjning
        movlw      0x00            ; Nollställer Display 3
        movwf      PORTC

Test_Display3:
        banksel    PORTA
        movlw      0xFB            ; Väljer Display 3 genom att nollställa den
        movwf      PORTA
        banksel    PORTC
        movlw      0x4F            ; Tänder siffran 3 på Display 3
        movwf      PORTC
        call       Delay           ; Skickar in en fördröjning
        movlw      0x00            ; Nollställer Display 3
        movwf      PORTC
        goto       Rakna

Testa:
        banksel    PORTA
        movlw      0xFE            ; Väljer Display 1 genom att nollställa RA0 (1111 1110)
        movwf      PORTA
        banksel    PORTC
        movlw      0x06            ; Tänder siffran 1 på Display 1
        movwf      PORTC
        call       Delay           ; Skickar in en fördröjning
        movlw      0x00            ; Nollställer Display 1
        movwf      PORTC
        movf       Raknare,0       ; Laddar Raknare i arbetsregistret
        addlw      0x01            ; Lägger till värdet 1 till Raknare, resultat i arbetsregistret
        movwf      Raknare         ; Laddare Raknare med värdet i arbetsregistret
        goto       Rakna

Delay:
    movlw    0x08
    movwf    Delay1
    movlw    0x2F
    movwf    Delay2
    movlw    0x03
    movwf    Delay3
Delay_0
    decfsz    Delay1, f
    goto    $+2
    decfsz    Delay2, f
    goto    $+2
    decfsz    Delay3, f
    goto    Delay_0
    goto    $+1
    return

     end
M.v.h.
Ulf L.
Användarvisningsbild
Icecap
Inlägg: 26652
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: PIC16F690 och förmodad tankevurpa hos mig

Inlägg av Icecap »

Jag kollade lite snabbt men orkade inte att gå igenom allt då jag såg följande:
movf Raknare,0 ; Laddar Raknare i arbetsregistret
xorlw 0x05

Problem 1: movf Raknare,0 Menar du F eller W? Nej, jag ids inte leta igenom databladet! Helt fel sätt att skriva det på!
Problem 2: xorlw 0x05; OK, inte ett gigantisk problem, mer en varning. Du kollar på detta sätt om värdet är exakt 5, inget annat. Jag har upplevd (såklart pga. mina fel i programmeringen) att ett värde hoppade över det värde man kollade efter och blev 1 större. Jag kollar numera alltid enligt principen "större eller lika med" och det görs ganska enkelt i detta!

addlw d'-5' ; Om du adderar -5 kommer Carry-flaggan att aktiveras om den slår runt.
btfss STATUS,C

Att du sedan väljer att köra absolut mode känns lite fel också men det kan fungera, det är bara mer att hålla koll på och mindre hjälp från kompilern.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: PIC16F690 och förmodad tankevurpa hos mig

Inlägg av sodjan »

Har du kört koden i MPSIM ? Om inte så borde du absolut gjörda det!
En kod av denna typ (som inte har några externa signaler/beroenden)
går alldeles utmärkt att simulera.

Sätt upp en "watch" på dina räknare och stega på bara. När du kommer till
delayen så klickar du bara "step out" så slipper du snurra runt i den.
Eller så sätter du en breakpoint just innan siffra 2 ska uppdateras och
kör "Run" så stannar den där och du kan kolla alla register.

Det går snabbare att köra det i MPSIM än att läsa koden och försöka
se vad det är.
MrIzoard
Inlägg: 339
Blev medlem: 25 september 2011, 15:33:08
Ort: Göteborg

Re: PIC16F690 och förmodad tankevurpa hos mig

Inlägg av MrIzoard »

Tack för att ni försöker hjälpa mig.

sodjan: nu har jag kört programmet i MPLAB SIM, tack för lite snabbinstruktioner, och hur konstigt det än låter så fungerar det ju som jag tänkt i den miljön.
Jag kollar i filregistret på adress 023 (det borde det väl bli med tanke på min deklaration i början?) och resultatet i registret börjar på 0 och sedan räknar det upp så som jag tänkt mig. Den flyttar ut värdet från adress 023 till arbetsregistret och lägger till 1 och sedan stoppar den tillbaka värdet i arbetsregistret till adress 023.
När den sedan kommer i min "funktion" som heter Rakna så ser man hur den jämför såsom tänkt och när adress 023 har värdet 5 så hoppar den ner till "funktionen" testa och löper igenom den.
Men som sagt när jag PIC'en utanför så bara räknar displayen upp och den byter aldrig till den andra displayen (dessutom blir det ju en sekunds extra väntan när man är i "funktionen" testa så den borde jag lagt märke till tycker jag.
Jag har även provat att byta position på displayen jag räknar upp och sedan skicka ut min 1'a på den andra positionen på displayen (för att utesluta att jag gör något fel i den "funktionen" som jag inte märker jag kommer in i) och det fungerar fint.
Kan det verkligen fungera olika i simulerad miljö kontra när jag har den utanför?

Icecap: är det inte bra att använda movf, jag hittade den i databladet och tyckte den verkade fylla mina behov (den fungerar ju som tänkt i simuleringen), hur skriver man det bättre? (obs det är absolut inget tykigt svar från mig utan jag vill så klart lära mig hur man bäst gör)
Bra tips med hur man kontrollerar större än eller lika med, det kommer jag att prova när jag väl fått bukt på detta problem.

M.v.h.
Ulf L.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: PIC16F690 och förmodad tankevurpa hos mig

Inlägg av sodjan »

Om du skriver din kod i "relocatable mode" istället så kan du använda
de symboliska d1, d2 och d3 d3namnen direkt i SIM.

Och skriv för jösse namn "d3" i stället för "adress 23" !!

Detta

Kod: Markera allt

        movf       Raknare,0       ; Laddar Raknare i arbetsregistret
        addlw      0x01            ; Lägger till värdet 1 till Raknare, resultat i arbetsregistret
        movwf      Raknare         ; Laddare Raknare med värdet i arbetsregistret
skriv enklare med :

Kod: Markera allt

        incf       Raknare, f
Sen så har du en stor bugg.
I din rutin Rakna så ska du nollställa Raknare, inte öka det med ett igen.
Den fortsätter efter 5 med 6, 7, 8 o.s.v, men du vill väll börja om på noll ?

Här är en kod som i alla fall "fungerar". Om den gör det du vill vet jag inte :-)
porta_x och portc_x är bara för att ha något att titta på i watch.
Notera att porta och portc inte kommer att visa det du skriver (med movwf) till dom
eftersom inte alla pinnar är utgångar.

Jag har kommenterat bort call till dalay för att underlätta i SIM. Man kan ju vänta själv
hur länga amn vill... :-)

Du kan plocka in Delay1 o.s.v. direkt i watch via "Add Symbol".

Kod: Markera allt

    list      p=16f690
#include <p16F690.inc>
     __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)

my_vars     udata_shr
Delay1      res 1                ; Variabel Delay1
Delay2      res 1                ; Variabel Delay2
Delay3      res 1                ; Variabel Delay3
Raknare     res 1                ; Variabel Raknare, räknar upp
porta_x     res 1
portc_x     res 1  

my_code     code h'0000'

Start:
        banksel    TRISC           ; Gör det möjligt att ställa in TRISC
        movlw      b'10000000'            ; RC7 = ingång, RC6 - RC0 = utgångar
        movwf      TRISC
        banksel    TRISA           ; Gör det möjligt att ställa in TRISA
        movlw      b'11111000'            ; RA7 - RA3 = ingångar, RA2 - RA0 = utgångar
        movwf      TRISA
        banksel    ANSEL
        clrf       ANSEL
        clrf       Raknare         ; Lägger in värdet 0 i variabeln Raknare

Rakna:
        movf       Raknare, w      ; Laddar Raknare i arbetsregistret
        xorlw      0x05            ; Kollar om Raknare är 5
        btfsc      STATUS,Z   
        goto       Testa           ; Hoppar till Testa om Raknare = 5

Test_Display1:
        banksel    PORTA
        movlw      0xFB            ; Väljer Display 3 genom att nollställa RA2 (1111 1011)
        movwf      PORTA
        movwf      porta_x
        banksel    PORTC
        movlw      0x06            ; Tänder siffran 1 på Display 3
        movwf      PORTC
        movwf      portc_x
;        call       Delay           ; Skickar in en fördröjning
        clrf       PORTC
        incf       Raknare, f

Test_Display2:
        banksel    PORTA
        movlw      h'FB'            ; Väljer Display 3 genom att nollställa den
        movwf      PORTA
        movwf      porta_x
        banksel    PORTC
        movlw      h'5B'            ; Tänder siffran 2 på Display 3
        movwf      PORTC
        movwf      portc_x
;        call       Delay           ; Skickar in en fördröjning
        clrf       PORTC
        clrf       portc_x

Test_Display3:
        banksel    PORTA
        movlw      0xFB            ; Väljer Display 3 genom att nollställa den
        movwf      PORTA
        movwf      porta_x
        banksel    PORTC
        movlw      0x4F            ; Tänder siffran 3 på Display 3
        movwf      PORTC
        movwf      portc_x
;        call       Delay           ; Skickar in en fördröjning
        clrf       PORTC
        clrf       portc_x
        goto       Rakna

Testa:
        banksel    PORTA
        movlw      0xFE            ; Väljer Display 1 genom att nollställa RA0 (1111 1110)
        movwf      PORTA
        movwf      porta_x
        banksel    PORTC
        movlw      0x06            ; Tänder siffran 1 på Display 1
        movwf      PORTC
        movwf      portc_x
;        call       Delay           ; Skickar in en fördröjning
        clrf       PORTC
        clrf       Raknare, w
        goto       Rakna

Delay:
    movlw    0x08
    movwf    Delay1
    movlw    0x2F
    movwf    Delay2
    movlw    0x03
    movwf    Delay3
Delay_0
    decfsz    Delay1, f
    goto    $+2
    decfsz    Delay2, f
    goto    $+2
    decfsz    Delay3, f
    goto    Delay_0
    goto    $+1
    return

     end
MrIzoard
Inlägg: 339
Blev medlem: 25 september 2011, 15:33:08
Ort: Göteborg

Re: PIC16F690 och förmodad tankevurpa hos mig

Inlägg av MrIzoard »

Jag provade att bara köra över koden utan att debugga den först (fanns ett fel på ett ställe i koden som behövde fixas först i och för sig).
Ja nog fasen fungerade det då.

Jo jag är medveten om att jag lät räknaren fortsätta efter att den nått upp till 5, jag tänkte ta tag i det när jag väl sett att den tände min display som tänkt.

Nu skall jag studera koden och debugga, tack sodjan!

M.v.h.
Ulf L.
Användarvisningsbild
Icecap
Inlägg: 26652
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: PIC16F690 och förmodad tankevurpa hos mig

Inlägg av Icecap »

Problemet är inte movf, det är movf xx,0!!! Använd W eller F istället för nollan!
Skriv svar