Sida 1 av 4
A/D-fråga om PIC18F1320
Postat: 4 december 2006, 12:33:42
av JimmyAndersson
PIC18F1320.
Jag är lite tveksam till hur jag ska läsa av två analoga ingångar (AN4 och AN5.)
Funktionen jag är ute efter:
Några knappar är kopplade så de ger olika spänningar in till AN5. Vid en förändring (dvs en knapp tryckts ner) vill jag få ett interrupt och så gör knapparna det de ska. Den delen är inga problem. Det knepiga kommer när en av dessa knappar ska starta en "avläsning" av AN4.
Med CHS2:CHS0 (ADCON0) väljer man Analog Channel Select bits. Antingen AN4 *eller* AN5 då i mitt fall...
En lösning som jag tänkte på var att CNS2:CHS0 är inställd på AN5 "i vanliga fall" och när rätt knapp tryckts ner så ändrar jag CNS2:CNS0 till AN4. Sedan när jag läst av AN4 så återgår CNS2:CNS0 till AN5. Blir det rätt?
Hur gör ni?

Postat: 4 december 2006, 12:56:50
av sodjan
På dessa PICs måste du alltid välja *en* ADC kanal och starta en mätning på den.
När/hur du väljer kanal har mer med logiken i din applikation att göra än
med ADC'n i sig.
Detta är naturligtsvis nackdelen med att "reservera" ADC'n för tangentbordet,
blir kan bli lite pyssligt om man vill använda ADC'n till "normala" saker
samtidigt...
Din lösning är den naturliga (och enda) lösningen.
Förreten, hur gör du för att få ett *interrupt* från AN5 ?
Postat: 4 december 2006, 14:14:04
av JimmyAndersson
Jag tänkte kolla efter interrupt på ADC'n (PIR1.ADIF). Har inte knappat in den delen än, men jag gjorde så i ett annat projekt.
Postat: 4 december 2006, 14:22:44
av sodjan
Jo, men ett ADC interrupt får du enbart efter att du har startat en konvertering.
D.v.s startat från din kod. Inte p.g.a att någon tryckte på en knapp.
Så "Vid en förändring (dvs en knapp tryckts ner) vill jag få ett interrupt" fungerar inte.
Postat: 4 december 2006, 14:37:03
av bearing
Det kanske finns någon standardlösning för detta, men jag fick en ide'.
Det kanske går att lösa med komparatorn. Om du från "knappspänningen" kopplar ett stort motstånd till en kondensator och sedan kopplar knappspänning och kondensatorspänning till komparatorn. Då kanske det går att få ett interrupt från komparatorn när knappspänningen ändras och kondingen inte "hinner med". Går det?
Postat: 4 december 2006, 14:56:15
av JimmyAndersson
bearing:
Om det innebär att jag behöver använda ytterligare en in-pinne så blir det problem. Jag har helt enkelt inga lediga.
sodjan:
Det har du rätt i när jag tänker efter. Jag formulerade mig nog knasigt. Jag måste inte få interruptet när en knapp trycks ner. Det duger fint om det kommer när man startat en konvertering. Bara man kan kolla vilken knapp som tryckts ner.
Postat: 4 december 2006, 15:24:59
av sodjan
> Det duger fint om det kommer när man startat en konvertering.
Alltså, interruptet kommer när konverteringen är *klar*, inte när den startas...
> Bara man kan kolla vilken knapp som tryckts ner.
Vid varje ADC interrupt måste du kolla ADC värdet och ta ett beslut hurvida
en knapp (och vilken) som är nedtryckt. Eventuellt invänta att 2 eller 3
avlästa värden i rad visar samma knapp för att undertrycka störningar.
Postat: 4 december 2006, 15:58:26
av JimmyAndersson
Ungefär såhär alltså:
Kod: Markera allt
if TestBit(PIR1, ADIF) = 1 then
PIR1.ADIF = 0
knapp_lo = ADRESL
knapp_hi = ADRESH
'slå ihop till ett word:
knapp = (word(knapp_hi << 8)) OR knapp_lo
end if
'och sedan kolla vilken knapp som trycktes. T.ex:
if (knapp >= 509) and (knapp <=515) then
...osv..
Postat: 4 december 2006, 16:01:05
av RasmusB
Hoppas du inte har gjort kretskortet än, för jag har en elegant lösning på lager
-Koppla din matris till RB4.
-Sätt pinne RB4 till digital ingång.
-Enabla "PORTB interrupt on change" (kap. 9.8 i databladet)
-När någon knapp trycks ner, får du en interrupt som betyder att någon knapp tryckts ner
-Starta AD-omvandlaren (fortfarande i interruptrutinen), välj kanal AD6 (samma pinne som RB4)
-Sampla tills du fått samma värde 2-3 gånger i rad
-Ställ tillbaka RB4 till digital ingång
-Avsluta interrupten
-Använd värdet
Hela lösningen hänger på att du kan använda RB4, eftersom det är den enda pinne som har BÅDE interrupt on change samt AD-omvandling...
Edit: Det hänger också på att din matris sänker spänningen så pass att förändringen ger utslag på en digital ingång. Men med tanke på att precisionen är rätt bra i AD-omvandlaren så borde det gå att fixa om du inte har för många knappar...

Postat: 4 december 2006, 16:37:43
av JimmyAndersson
Intressant idé!
Lyckligtvis har jag inte gjort något kretskort än.
Faktiskt så kan jag byta plats på AN5(RB1), där knapparna sitter, med AN6(RB4) som bara ska kopplas till en transistor och relä.
Om jag inte tänker fel så borde min matriskoppling fungera för att trigga en digital ingång.
Tråden med matrisen finns
här. (Gammal lösning som jag återanvänder.)

Postat: 4 december 2006, 16:57:19
av RasmusB
Om jag fattar det hela rätt så får du alltså 0v när du inte tryckt ner någon knapp? Tveksam på att 1 och 1.8 v räcker för att räknas som en logisk etta.
Postat: 4 december 2006, 17:51:50
av JimmyAndersson
Sant, men det går att lösa. Jag har ju 10 bitar på A/D'n, så det finns tillräckligt med marginal för att minska motstånden lite.
Postat: 4 december 2006, 21:10:19
av Greve Hamilton
bearing skrev:Det kanske finns någon standardlösning för detta, men jag fick en ide'.
Det kanske går att lösa med komparatorn. Om du från "knappspänningen" kopplar ett stort motstånd till en kondensator och sedan kopplar knappspänning och kondensatorspänning till komparatorn. Då kanske det går att få ett interrupt från komparatorn när knappspänningen ändras och kondingen inte "hinner med". Går det?
Jag har gjort en liknande lösning på ett av mina pågående projekt. Fungerar väldigt bra faktiskt. Man slipper sitta och polla förändringar hela tiden, sparar mycket tid.
Det där med kondingen tror jag inte spelar så stor roll, fungerar bra utan.
Liknande princip som den RasmusB talade om.
Postat: 4 december 2006, 21:21:08
av RasmusB
JimmyAndersson skrev:Sant, men det går att lösa. Jag har ju 10 bitar på A/D'n, så det finns tillräckligt med marginal för att minska motstånden lite.
Jovisst... men eftersom du sade att du skulle återanvända matrisen ville jag bara påpeka det...

Postat: 5 december 2006, 13:24:32
av JimmyAndersson
Helt ok.
Nu har jag fått ordning på det. Kör timer, encoder och knapparna (allt kollas med hjälp av interrupt) som visar respektive värden på en display. Kul att det fungerar så bra trots MikroBasic. Fick städa en del i interrupt-proceduren, men nu ser resultatet bra ut.
En nackdel när man knappar MikroBasic är att man inte kan ge interrupten olika prioritet. MikroBasic stödjer helt enkelt inte det av någon trist anledning. Eftersom jag i princip aldrig använder MikroBasic's egna rutiner så skulle jag egentligen lika gärna kunna gå över till assembler. Nackdelen är att det var minst 15 år sedan jag programmerade asm och det finns tyvärr för lite tid just nu för att friska upp minnet. Basic kan jag däremot i ryggmärgen. Har programmerat det i över 20 år. Jag har tillochmed gjort en fullt fungerande kopia av Win3.11 enbart i Basic.
