Bestämma vilken analog ingång som ska användas? - PIC. AS
- JimmyAndersson
- Inlägg: 26586
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
Bestämma vilken analog ingång som ska användas? - PIC. AS
PIC12F675. ASM.
Jag har två analoga ingångar (AD0 och AD1). En spänning på 0,5V - 1V kan kopplas till någon av dessa (en i taget) och jag vill i PIC-kretsen bestämma vilken ingång som man kopplade spänningen till.
Pga konstruktionen så kan jag inte förstärka spänningen innan den kopplas till ingången. Därför kan jag inte läsa av en logisk etta genom att använda den digitala ingången på samma pinne och på så sätt avgöra vilken ingång man kopplade spänningen till.
Går detta att lösa på något smidigt sätt?
Jag har två analoga ingångar (AD0 och AD1). En spänning på 0,5V - 1V kan kopplas till någon av dessa (en i taget) och jag vill i PIC-kretsen bestämma vilken ingång som man kopplade spänningen till.
Pga konstruktionen så kan jag inte förstärka spänningen innan den kopplas till ingången. Därför kan jag inte läsa av en logisk etta genom att använda den digitala ingången på samma pinne och på så sätt avgöra vilken ingång man kopplade spänningen till.
Går detta att lösa på något smidigt sätt?
- JimmyAndersson
- Inlägg: 26586
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
- JimmyAndersson
- Inlägg: 26586
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
Sant.
Somnade när jag hade migrän igår och vaknade några timmar senare med ett tjockt täcke uppdraget till hakan. Det var väldigt varmt!!
Annars har jag varit duktig med min nya kost. Har sovit helt ok också, så jag blev lite förvånad när jag plötsligt fick migrän. Det enda jag kan komma på är att jag satt vid en lite för flimrig skärm i en lite hukad arbeställning i några timmar i förrgår.
Nu ska jag bara knappa ihop interrupt-rutinen, sedan är det dags för test 1A.
Den här gången har jag varit duktig och gjort ett bra schema på vad hela koden ska göra.

Somnade när jag hade migrän igår och vaknade några timmar senare med ett tjockt täcke uppdraget till hakan. Det var väldigt varmt!!

Annars har jag varit duktig med min nya kost. Har sovit helt ok också, så jag blev lite förvånad när jag plötsligt fick migrän. Det enda jag kan komma på är att jag satt vid en lite för flimrig skärm i en lite hukad arbeställning i några timmar i förrgår.
Nu ska jag bara knappa ihop interrupt-rutinen, sedan är det dags för test 1A.
Den här gången har jag varit duktig och gjort ett bra schema på vad hela koden ska göra.

- JimmyAndersson
- Inlägg: 26586
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
Så sant. Jag måste tänka extra mycket på det eftersom jag dricker ganska mycket kaffe, cola, te och sånt.
Det här ser väl bra ut?
Ej med på bild: Rutinen read_ad.
edit: Kan den sena rensningen av komparatorns avbrottsflagga innebära problem? Kan ju inte sätta den direkt efter interruptet pga att jag använder btfss och tycker det är smidigt.
Det här ser väl bra ut?
Kod: Markera allt
;***********************************************
isr_rutin CODE
isr_rutin
bcf STATUS, RP0 ;Bank0
btfss PIR, ADIF ;Om AD'n gett interrupt: Fortsätt med nästa rad. Annars: Hoppa över nästa.
goto read_ad ;Gå till rutinen för att läsa av AD'n.
btfss PIR1, CMIF ;Om komparatorn har gett interrupt: Fortsätt med nästa rad.
goto read_comparator ;Gå till rutinen för att läsa av komparatorn.
retfie
;***********************************************
;***********************************************
read_comparator CODE
read_comparator
btfss CMCON, COUT ;Om signalen på CIN+ (GPIO.0) är högst så går vi vidare till nästa rad.
bcf channel, 0 ;Om Toslink (GPIO.0 AN0) har signal så sätts kanal-flaggan till 0.
bsf channel, 0 ;Om Koaxial (GPIO.1 AN1) har signal så sätts kanal-flaggan till 1.
btfss channel ;Om kanal-flaggan är 1 (koaxial) så körs nästa rad.
bsf ADCON0, CHS0 ;Ändrar till x1. (X är redan satt till 0 vid initieringen.) -Väljer AN1. (Koaxialt)
bcf ADCON0, CHS0 ;Ändrar till x0. (X är redan satt till 0 initieringen.) -Väljer AN0. (Toslink)
bcf PIR1, CMIF ;Clerar avbrottsflaggan för komparatorn.
return
;***********************************************
edit: Kan den sena rensningen av komparatorns avbrottsflagga innebära problem? Kan ju inte sätta den direkt efter interruptet pga att jag använder btfss och tycker det är smidigt.
Det kan vara en idé att spara W och sånt när du går in i ISR och återställer allt när du lämnar ISR, man kan få så "lustiga" fel annars 
Hur man gör? Oj då..... hmmmm, låt mig saxa lite:

Hur man gör? Oj då..... hmmmm, låt mig saxa lite:
Kod: Markera allt
ISR org 0x004 ; 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
movf PCLATH,W
movwf pclath_temp
clrf PCLATH ; Be sure that wer'e home alone
banksel PIR1
Timer2_Int
btfss PIR1,TMR2IF ; Is it Timer2?
goto Timer0_Int ; Jump if not
bcf PIR1,TMR2IF ; Clear interrupt flag first of all
.... // en massa dravel
Timer0_Int
btfss INTCON,T0IF ; Is it Timer0?
goto ISR_Exit ; Jump if not
bcf INTCON,T0IF ; Clear interript request flag
.... // Mer dravel
ISR_Exit
movf pclath_temp,W ; Read copy of PCLATH
movwf PCLATH ; Restore to pre-ISR content
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
- JimmyAndersson
- Inlägg: 26586
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
> > clrf PCLATH ; Be sure that wer'e home alone
> Varför nollställer man den här?
I detta fall förutsätts att ISR'en befinner sig på PAGE-0,
d.v.s någonstans i de första 2 K-ord programminne i PIC16
arkitekturen. Att "nolla" PCLATH gör att alla CALL och GOTO
också kommer att gå till PAGE-0.
Eftersom en PIC12F inte har *mer* än 2K-ord, så kommer
(de rellevanta bitarna av) PCLATH aldrig att vara något annat
än just b'00' i alla fall...
Däremot kan de lägra bitarna av PCLATH (som används vid
"computed GOTO") kanske vara något annat eftersom de anger
en 256 bytes area av programminnet. Se "2.3 PCL and PCLATH"
i databladet.
Notera att koden inte fungerar om ISR'n kan befinna sig
var som helst ! Då fungerar t.ex "pagesel <label>", där <label>
är en lämplig label inom ISR'en. I princip vilken label som helst,
eftersom ISR'en normalt ligger i sin helhet inom same PAGE. I
exemplet skulle man kunna göra "pagesel Timer2_Int" t.ex...
Om man låter länkaren (MPLINK) bygga sin kod, så kommer
aldrig ett code-segment att korsa en 2Kord gräns. Om man däremot
kör enligt gamla stilen (absolute mode), så är det lätt gjort...
Notera också att "w_temp", "status_temp" och "pclath_temp" *MÅSTE*
allokeras från "shared memory" (även kallat "non-banked memory").
Antingen via korrekta EQU's (fy satan...
) eller genom att allokera
dessa tre bytes via UDATA_SHR (yes
).
> Varför nollställer man den här?
I detta fall förutsätts att ISR'en befinner sig på PAGE-0,
d.v.s någonstans i de första 2 K-ord programminne i PIC16
arkitekturen. Att "nolla" PCLATH gör att alla CALL och GOTO
också kommer att gå till PAGE-0.
Eftersom en PIC12F inte har *mer* än 2K-ord, så kommer
(de rellevanta bitarna av) PCLATH aldrig att vara något annat
än just b'00' i alla fall...
Däremot kan de lägra bitarna av PCLATH (som används vid
"computed GOTO") kanske vara något annat eftersom de anger
en 256 bytes area av programminnet. Se "2.3 PCL and PCLATH"
i databladet.
Notera att koden inte fungerar om ISR'n kan befinna sig
var som helst ! Då fungerar t.ex "pagesel <label>", där <label>
är en lämplig label inom ISR'en. I princip vilken label som helst,
eftersom ISR'en normalt ligger i sin helhet inom same PAGE. I
exemplet skulle man kunna göra "pagesel Timer2_Int" t.ex...
Om man låter länkaren (MPLINK) bygga sin kod, så kommer
aldrig ett code-segment att korsa en 2Kord gräns. Om man däremot
kör enligt gamla stilen (absolute mode), så är det lätt gjort...
Notera också att "w_temp", "status_temp" och "pclath_temp" *MÅSTE*
allokeras från "shared memory" (även kallat "non-banked memory").
Antingen via korrekta EQU's (fy satan...

dessa tre bytes via UDATA_SHR (yes

- JimmyAndersson
- Inlägg: 26586
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
- JimmyAndersson
- Inlägg: 26586
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
- JimmyAndersson
- Inlägg: 26586
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt: