"Cleara" InterruptOnChange flagga på en PIC 12F629

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
PopUnoNkoK
Inlägg: 789
Blev medlem: 10 december 2007, 12:40:08
Ort: Piteå

"Cleara" InterruptOnChange flagga på en PIC 12F629

Inlägg av PopUnoNkoK »

Här kommer en dubbelpost utan dess like. :oops:
Anledningen till detta:
Jag har postat samma fråga i Idebanken i en tråd med helt annat namn och som är inne på 3 sidor nu. Jag postade där för att slippa starta en ny tråd. Problemet jag ser är dock att jag tror att det är många som läst den tråden från början och som vet vad "ideen" handlar om och kanske nu inte läser tråden längre. Jag vet att jag själv håller mig inom vissa delar av detta forum. Jag tänker att Mikroprocessorrävarna håller sig främst till dessa delar av forumet.
Jag tänker mig också att en fråga av denna typ brukar generera flera bra förslag på vad felet kan vara men i den andra tråden är det stendött.
Frågan som sådan gäller uteslutande en Mikroprocessor och dess kod.

Frågan.

Processor: 12f629

Problem: Jag klarar inte att "cleara" Interupptflaggan.
Allt fungerar bra från början, simulatorn fastnar i min "MainLoop". Den "hänger" där tills jag sätter GPIO,0 till hög i stimulus kontrollfönstret. Då hamnar den i ISRen, helt enligt planerna.
Men sen, så fastnar den där.- Den går igenom ISRen och hoppar direkt till början av ISRen.

Detta beror väl på att jag inte lyckats "Cleara" interuppt flaggan för interupt on change.
I data bladet står det att jag måste:
a) Any read or write of GPIO. This will end the mismatch condition.
b) Clear the flag bit GPIF

Detta gör jag så här i koden:

Kod: Markera allt

MOVFW   GPIO         ;Läser GPIO för att ta bort "mismatch"
BCF      INTCON,GPIF      ;Clear InteruptOnChange Flag
Trots detta så så "rensas" inte flaggan.

Tacksam för ideer hur jag ska rensa flaggan. Antar att det är något som krävs att göras före flaggan kan rensas.

Koden i sin helhet som jag kör med nu.

Kod: Markera allt

;******************************************************************************
;   This file is a basic code template for object module code                 *
;   generation on the PIC12F629. This file contains the                       *
;   basic code building blocks to build upon.                                 *
;                                                                             *
;   Refer to the MPASM User's Guide for additional information on             *
;   features of the assembler and linker (Document DS33014).                  *
;                                                                             *
;   Refer to the respective PIC data sheet for additional                     *
;   information on the instruction set.                                       *
;                                                                             *
;******************************************************************************
;                                                                             *
;    Filename:      xxx.asm                                                   *
;    Date:                                                                    *
;    File Version:                                                            *
;                                                                             *
;    Author:                                                                  *
;    Company:                                                                 *
;                                                                             *
;                                                                             *
;******************************************************************************
;                                                                             *
;    Files required: P12F629.INC                                              *
;                                                                             *
;                                                                             *
;                                                                             *
;******************************************************************************
;                                                                             *
;    Notes:                                                                   *
;                                                                             *
;******************************************************************************

;------------------------------------------------------------------------------
; PROCESSOR DECLARATION
;------------------------------------------------------------------------------

     LIST      P=12F629              ; list directive to define processor
     #INCLUDE <P12F629.INC>          ; processor specific variable definitions

;------------------------------------------------------------------------------
;
; CONFIGURATION WORD SETUP
;
; The 'CONFIG' directive is used to embed the configuration word within the
; .asm file. The lables following the directive are located in the respective
; .inc file.  See the data sheet for additional information on configuration
; word settings.
;
;------------------------------------------------------------------------------

    __CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT

;------------------------------------------------------------------------------
; VARIABLE DEFINITIONS
;------------------------------------------------------------------------------

; example of using Shared Uninitialized Data Section
INT_VAR     UDATA_SHR   0x20   
W_TEMP      RES     1             ; variable used for context saving
STATUS_TEMP RES     1             ; variable used for context saving

;------------------------------------------------------------------------------
; EEPROM INITIALIZATION
;
; The 12F629 has 128 bytes of non-volatile EEPROM, starting at address 0x2100
;
;------------------------------------------------------------------------------

DATAEE    CODE  0x2100
    DE    "MCHP"          ; Place 'M' 'C' 'H' 'P' at address 0,1,2,3

;------------------------------------------------------------------------------
; OSCILLATOR CALIBRATION VALUE
;------------------------------------------------------------------------------

OSC       CODE    0x03FF

; Internal RC calibration value is placed at location 0x3FF by Microchip as
; a 0xADDLW K instruction, where the K is a literal value to be loaded into
; the OSCCAL register. 

;------------------------------------------------------------------------------
; RESET VECTOR
;------------------------------------------------------------------------------

RESET_VECTOR  CODE      0x0000 ; processor reset vector
        GOTO    START          ; go to beginning of program

;------------------------------------------------------------------------------
; INTERRUPT SERVICE ROUTINE
;------------------------------------------------------------------------------

INT_VECTOR    CODE    0x0004  ; interrupt vector location
        MOVWF   W_TEMP        ; save off current W register contents
        MOVF    STATUS,w      ; move status register into W register
        MOVWF   STATUS_TEMP   ; save off contents of STATUS register

; isr code can go here or be located as a call subroutine elsewhere
      MOVFW   GPIO         ;Läser GPIO för att ta bort "mismatch"
      BCF      INTCON,GPIF      ;Clear InteruptOnChange Flag


      NOP



        MOVF    STATUS_TEMP,w ; retrieve copy of STATUS register
        MOVWF   STATUS        ; restore pre-isr STATUS register contents
        SWAPF   W_TEMP,f
        SWAPF   W_TEMP,w      ; restore pre-isr W register contents
        RETFIE                ; return from interrupt

;------------------------------------------------------------------------------
; MAIN PROGRAM
;------------------------------------------------------------------------------

MAIN_PROG     CODE
      




START

;------------------------------------------------------------------------------
; OSCCAL RESTORE (not required if internal OSC is not used)
;------------------------------------------------------------------------------

        errorlevel -302
        BSF     STATUS,RP0    ; set file register bank to 1
        CALL    0x3FF         ; retrieve factory calibration value
        MOVWF   OSCCAL        ; update register with factory cal value
        BCF     STATUS,RP0    ; set file register bank to 0
        errorlevel +302
       
;------------------------------------------------------------------------------
; PLACE USER PROGRAM HERE
;------------------------------------------------------------------------------

      BANKSEL      GPIO
      CLRF      GPIO      ;Init GPIO
      MOVLW      07h         ;Set GP<2:0> to
      MOVWF      CMCON      ;digital IO
      BANKSEL      TRISIO
      MOVLW      b'000001'   ;Set GPIO 0=input
      MOVWF      TRISIO      ;and GPIO 1-5=output

      BSF         INTCON,GIE   ;Enable GloblInterupt
      BSF         IOC,IOC0   ;Enable InteruptOnChange on GPIO,0
      BSF         INTCON,GPIE   ;Enable InteruptOnChange


MainLoop

      GOTO   MainLoop


      NOP
        END                       ; directive 'end of program'
Som sagt, ber om ursäkt för dubbelpost, ni får gärna ha synpunkter på hur ni tycker man ska förhålla sig i detta fall. Är lite orolig för att jag kommer få mycket mothugg men det får jag ta då.

MVH Peter
Senast redigerad av blueint 11 september 2011, 16:22:50, redigerad totalt 1 gång.
Anledning: PIC
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: "Cleara" InterruptOnChange flagga på en 12F629

Inlägg av sodjan »

Med följande lilla justering så fungerar det :

Kod: Markera allt

      banksel gpio         ; Se till att vi är i rätt bank
      MOVFW   GPIO         ; Läser GPIO för att ta bort "mismatch"
      banksel intcon       ; Se till att vi är i rätt bank
      BCF     INTCON,GPIF  ; Clear InteruptOnChange Flag
      banksel gpio         ; Kanske inte helt nödvändigt...
Du var alltså inte i rätt bank och läst något annat än GPIO, vad det nu var/blev.
PopUnoNkoK
Inlägg: 789
Blev medlem: 10 december 2007, 12:40:08
Ort: Piteå

Re: "Cleara" InterruptOnChange flagga på en 12F629

Inlägg av PopUnoNkoK »

Tackar Sodjan! Funkar perfekt.

Jag har inte fått in någon bra rutin för Bankbyten. Jag gör det när jag sätter upp TMR0 och Option_Reg. Men har inte riktigt fått kläm på det i "programkoden". Måste bli bättre på det.

En fråga till. Ett PullDown motstånd. Hur stort bör det vara om man kör kretsen på 5v? Jag kommer att bryta kretsen för att få InterruptOnChange att ske och vill juh då dra pinnen till noll istället för att det blir en öppen ingång.

Visst kopplar jag brytaren från Pinnen på PICen till 5v. (Pinne hög när brytaren är på) Och ett pulldown motstånd direkt från pinnen till Jord. Är det så man kopplar?

Tack för givande svar Sodjan.
Användarvisningsbild
Icecap
Inlägg: 26652
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: "Cleara" InterruptOnChange flagga på en 12F629

Inlägg av Icecap »

Jag föredrar att ha pull-up och sedan har brytaren mellan GND och pinnen med lite motstånd och kondensator mellan. Det ger färre störningar.

Men det du beskriver är korrekt och ett 10k motstånd duger alldeles utmärkt. Du bör dock veta att vissa brytare behöver en viss minimal ström för att rensa kontaktytorna.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: "Cleara" InterruptOnChange flagga på en 12F629

Inlägg av sodjan »

> Jag har inte fått in någon bra rutin för Bankbyten.

Enklast är att bara lägga till en banksel före varje register-access.
Då blir det i alla fall aldrig fel bank.

Sedan, när allt fungerar, så kan man, om det behövs, trimma
det hela genom att plocka bort onödiga banksel.

> En fråga till. Ett PullDown motstånd.

Som Icecap säger, pull- *up* och "brytaren" jord är nog vanligare.
Vad är förresten "brytaren" ? Är det något mekansikt ?
Har du funderat på kontaktstudsar ? Om inte så kommer din ISR
att köras flera gånger vid varje slutning av brytaren.
PopUnoNkoK
Inlägg: 789
Blev medlem: 10 december 2007, 12:40:08
Ort: Piteå

Re: "Cleara" InterruptOnChange flagga på en PIC 12F629

Inlägg av PopUnoNkoK »

Banksel före varje memory call. Man får väl göra så.

"Brytaren" kommer vid ett första test att vara en foliestrip som kommer att skjutas av med en luftpistol.
Om det hinner bli kontaktstudsar tror jag ändå inte att det kommer att bli ett problem då "brytaren" kommer att trigga en kamerablixt. Den kommer inte att hinna ladda upp sig något under den tiden.

Det är som sagt ett första test, vi får se vart det bär hän. =)

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

Re: "Cleara" InterruptOnChange flagga på en PIC 12F629

Inlägg av sodjan »

> Banksel före varje memory call. Man får väl göra så.

Utom de minnen som du har allokerat vid DATA_SHR, d.v.s
från "unbanked memory". Finnessen med det är ju just att
slippa bank bytena. Och när det gäller just en 12F629 så gäller
det faktiskt hela minnet (GPR). Enbart DATA_SHR fungerar och du
behöver aldrig BANKSEL före dina egna register/variabler.

Detsamma gäller de SFR som alltid ligger mappat över alla banker.
På en 12F629 är det bl.a STATUS och INTCON. Så den BANKSEL som
jag la in före "BCF INTCON,GPIF" är alltså egentligen helt onödig.
Det var BANKSEL'en före "MOVFW GPIO" som var det kritiska !

Se databladet för detaljer, speciellt "FIGURE 2-2: DATA MEMORY MAP
OF THE PIC12F629/675".
PopUnoNkoK
Inlägg: 789
Blev medlem: 10 december 2007, 12:40:08
Ort: Piteå

Re: "Cleara" InterruptOnChange flagga på en PIC 12F629

Inlägg av PopUnoNkoK »

Icecap: Skulle du konkret kunna säga hur du skulle koppla en brytare för att slippa störningar. Jag har lite problem med det. Vad för motstånd och vad för kondensatorer. (vilka värden och hur du skulle koppla dom).
Skit att den "verkliga världen" ska störa mitt kodande. Kontaktstudsar och störningar hade jag verkligen kunna klarat mig utan. =)

Givetvis får andra svara som har kunskap på området. =)

MVH Peter F
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4750
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Re: "Cleara" InterruptOnChange flagga på en PIC 12F629

Inlägg av Swech »

Det är sällan man behöver/skall köra en strömbrytare som trig ingång med
interrupt on change just på grund av att studsar skapar problem.

Om du inte speciellt behöver läsa av en exakt tidpunkt då knappen aktiveras eller
t.ex. vakna upp från power save så bör du istället läsa av
knappen med jämna mellanrum.
Läs av knappen 10-20ggr / sekund.
Har du samma mätvärde 3 gånger efter varandra så är studsarna bortfiltrerade

Swech
PopUnoNkoK
Inlägg: 789
Blev medlem: 10 december 2007, 12:40:08
Ort: Piteå

Re: "Cleara" InterruptOnChange flagga på en PIC 12F629

Inlägg av PopUnoNkoK »

Alltså den kod jag nu kör använder sig inte av "Interrupt on change" trots att tråden handlar om det. Jag kom bara ihåg att Icecap nämnt om komponenter i anslutning till brytaren för att minska störningar.

I det läget jag nu är i koden så är det bara en loop som enbart pollar brytaren och om den är intryckt väntar den 10 millisec innan den pollar igen, är den även intryckt då så registreras det som ett tryck.
Alltså en väldigt enkel debounce. Men jag är mest nyfiken hur man kopplar för att slippa störningar i största utsträckning.
Eller är det lika bra att bara hantera dessa i koden. Alltså typ som Swech skriver. Att man nöjer sig med en lite mer avancerad debounce och struntar i fler komponenter?

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

Re: "Cleara" InterruptOnChange flagga på en PIC 12F629

Inlägg av sodjan »

> Eller är det lika bra att bara hantera dessa i koden.

Ja, det sparar ju komponenter.

> Att man nöjer sig med en lite mer avancerad debounce

Ja, om inte din lösning med 2 läsningar med 10 ms intervall
fungerar tillräckligt bra så kan du ju läsa 3 eller 4 gånger.

Sen så lät det som att din kod är låst under de där 10 ms, normalt
vill man inte ha det så utan man gör läsningen (som någon sa)
i ett timer-inerrupt med 10 ms intervall. Sedan kan processorn
göra annat mellan interrupten.

Att ha ett generellt interrupt som en "klocka" kan vara bra till mycket
annat. Man kanske vill ha status LED's som ska blinka, ibland med
olika hastighet beeroende på vilket "status" som ska indikeras. Det
bli ganska enkelt med ett regelbundet interrupt och ett par räknare.
PopUnoNkoK
Inlägg: 789
Blev medlem: 10 december 2007, 12:40:08
Ort: Piteå

Re: "Cleara" InterruptOnChange flagga på en PIC 12F629

Inlägg av PopUnoNkoK »

Ja då skippar jag de komponenter jag tänkte sätta dit.

Att PICen är låst under den tiden är helt sant. I detta fall gör det ingenting, jag har stängt av TMR0 interrupt i denna loop. Det är när jag ställer hur lång en nedräknare ska vara. 0-99. När man sedan är klar med inställningarna så sätter jag igång interrupten igen.
Jag gör så nu för enkelhetensskull. Jag tycker att ISR blir så sjukt stor, allt händer egentligen där, eller i en subbrutin som kallas därifrån. Känns inte riktigt bra. Har för mig att man ska lämna ISRen så fort som möjligt.

TACK för svar.

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

Re: "Cleara" InterruptOnChange flagga på en PIC 12F629

Inlägg av sodjan »

> Har för mig att man ska lämna ISRen så fort som möjligt.

Ja, generellt sätt. Men det är inget absolut krav.
Om du (eller processorn) i alla fall inte har något annat
att göra så spelar det ju ingen roll. Däremot så kan det
vara en lösning som du kanske får göra om ifall applikationen
växer med nya funktioner. Då kan det löna sig att ha en
snyggare arkitektur från början.
PopUnoNkoK
Inlägg: 789
Blev medlem: 10 december 2007, 12:40:08
Ort: Piteå

Re: "Cleara" InterruptOnChange flagga på en PIC 12F629

Inlägg av PopUnoNkoK »

OK några frågor på Debouncing med timer och interrupt.

Kan jag ha samma register som håller koll på om knappen varit nertryckt under en längre tid (= Inte kontaktstuds) till flera knappar?
Om man förväntar sig att det bara kommer att tryckas en knapp i taget. Eller är det dumt att göra så? Kanske är som gjort för att det ska strula.

Om jag debounsar i ISRen så kommer jag juh att vara i ISRen när jag upptäcker att knappen är nedtryckt och har varit det under den förinställda tiden. Sköter jag det som ska hända vid knapptryckningen där och då? Alltså i ISRen. Eller sätter jag en Flagga i ett register som jag sedan får "polla" ute i MainLoop?

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

Re: "Cleara" InterruptOnChange flagga på en PIC 12F629

Inlägg av sodjan »

Antag att ISR'en körs t.ex var 10 ms (tiden är inte alls kritisk, ta det som ger en
enkel uppsättning av timern). I ISR'en räknar jämför du först om nuvarnade läge
är lika med förra körningen av ISR'en. Om inte (det kan vara en studs), nollställ
räknaren och avsluta ISR'en. Om det är samma läge, öka räknaren.

När räknaren når (t.ex) 5, kolla om du nuvarande läget är detsamma som föregående
*stabila* läge. Om det är så så har du en ändring (antingen "knapp intryckt" eller
"knapp släppt"). Uppdatera "knapp-status" och sätt en flagga "status-ändrat" och
avsluta ISR'en.

Allt detta tar kanske 10-20 instruktioner i ISR'en och går på kanske 5 us
eller så beroende på frekvens på oscillatorn i processorn. Med ett avbrott
varje 10 ms så är det alltså kanske en promille av cyklerna så går till detta.

Flaggan "status-ändrat" kan du känna av i din main-loop och göra vad det nu är
som ska göras då knappen ändras. Det får du hålla reda på där.

D.v.s att ISR'en struntar helt i *vad* som ska göras då knappen trycks in eller släpps.
Den kollar bara *att* knappens läge har ändrats. Resten för main-loopen ta hand om.

Om du vill ha en blinkande LED med t.ex 0.5 sek, så är det bara att lägga en
räknare till i ISR'en som byter läge på LED-utgången var 50'de avbrott. Det blir
väldigt enkelt att lägga till om man har en bas-funktion enligt ovan. Du behöver
alltså inte ha en separat timer för att blinka med en LED. På samma sätt kan du
ha en massa saker som sker med en multipel av (t.ex) 10 ms utan att ändra något
i den övergripande arkitekturen i applikationen.

Visst, en 12F629 har inte överdrivet mycket minne, så man får kanske hushålla lite
med det. Men 64 bytes bör räcka ett tag. Annars har du 12F683 med dubbla minnet.

Eller 12F1840 med 256 bytes och *massor* av andra finesser. 10:20/st (ex moms)
i enstyck hos ELFA. 73-349-75.
Skriv svar