PIC IO ?
PIC IO ?
Har tänkt att använda en pinne på en 12F629 som öppen-kollektor utgång/ingång.
Tanken är att pinnen ska vara högohmig då den är ingång och när den är hög som utgång, alltså ska den låg när den är lågohmig.
Jag vet inte riktigt vad som händer när man ställer om i TRISIO-registret från ingång till utgång, kommer pinnen att ge ut den nivå den hade när den var ingång, precis innan TRSIO ändrades ?
se exempel här:
12F629
; OC-pinne ställs in för normaltillstånd som ingång
bsf status, RP0 ; bank 1
bsf TRISIO, OC-pinne
bcf status, RP0 ; bank 0
;
;
;
;signal skickas ut på OC-pinne, dvs den görs låg
; ställ om till utgång
bsf status, RP0 ; bank 1
bcf TRISIO, OC-pinne
bcf status, RP0 ; bank 0
; Här är det okänt om OC-pinne är 1 eller 0, bara känt att den är
lågohmig, eller.. ?
bcf GPIO, OC-pinne ; OC-pinne görs låg
Tanken är att pinnen ska vara högohmig då den är ingång och när den är hög som utgång, alltså ska den låg när den är lågohmig.
Jag vet inte riktigt vad som händer när man ställer om i TRISIO-registret från ingång till utgång, kommer pinnen att ge ut den nivå den hade när den var ingång, precis innan TRSIO ändrades ?
se exempel här:
12F629
; OC-pinne ställs in för normaltillstånd som ingång
bsf status, RP0 ; bank 1
bsf TRISIO, OC-pinne
bcf status, RP0 ; bank 0
;
;
;
;signal skickas ut på OC-pinne, dvs den görs låg
; ställ om till utgång
bsf status, RP0 ; bank 1
bcf TRISIO, OC-pinne
bcf status, RP0 ; bank 0
; Här är det okänt om OC-pinne är 1 eller 0, bara känt att den är
lågohmig, eller.. ?
bcf GPIO, OC-pinne ; OC-pinne görs låg
När pinnen är ingång, är den högohmig.
När pinnen är utgång styrs den av motsvarande bit i GPIO registret.
Du ska alltså ha en pullup på pinnen (eller "linjen" den är kopplad till,
normalt gör man så här för att bygga en "bus" med flera processorer...).
> kommer pinnen att ge ut den nivå den hade när den var ingång, precis innan TRSIO ändrades ?
Den kommer att ha värdet som motsvarande bit i GPIO har.
Detta värde kanske inte är det som du tror, p.g.a av operationer
mot GPIO som du gjorde medan pinnen var ingång. Om du t.ex gör
en bcf/bsf mot en *annan* pinne, så kommer hela GPIO att läsas
(inkl OC-pinnen), den andra pinnen sätts enligt bcf/bsf parametern och
resultatet skrivs tillbaka til GPIO. Alltså har din OC-pinnen nu samma
värde som ingången just nu istället för det du tror.
Ovanstående kallas "read-modify-write" (eller bara RMW) fenomenet.
Bäst är att se till att GPIO-biten är korrekt direkt innan pinnen sätts till utgång.
När pinnen är utgång styrs den av motsvarande bit i GPIO registret.
Du ska alltså ha en pullup på pinnen (eller "linjen" den är kopplad till,
normalt gör man så här för att bygga en "bus" med flera processorer...).
> kommer pinnen att ge ut den nivå den hade när den var ingång, precis innan TRSIO ändrades ?
Den kommer att ha värdet som motsvarande bit i GPIO har.
Detta värde kanske inte är det som du tror, p.g.a av operationer
mot GPIO som du gjorde medan pinnen var ingång. Om du t.ex gör
en bcf/bsf mot en *annan* pinne, så kommer hela GPIO att läsas
(inkl OC-pinnen), den andra pinnen sätts enligt bcf/bsf parametern och
resultatet skrivs tillbaka til GPIO. Alltså har din OC-pinnen nu samma
värde som ingången just nu istället för det du tror.
Ovanstående kallas "read-modify-write" (eller bara RMW) fenomenet.
Bäst är att se till att GPIO-biten är korrekt direkt innan pinnen sätts till utgång.
>När pinnen är ingång, är den högohmig.
>När pinnen är utgång styrs den av motsvarande bit i GPIO registret.
Jag är helt med på det.
>Du ska alltså ha en pullup på pinnen (eller "linjen" den är kopplad till,
>normalt gör man så här för att bygga en "bus" med flera processorer...).
Det är så jag tänkt.
Om jag förstått rätt:
Så alltså under tiden OC-pinnen är en ingång, så nollställer man motsvarande bit i GPIO.
Då skulle egentligen OC-pinnen nollställas, om den hade varit en utgång, det görs så att säga i luften.
Så när man sen gör om OC-pinnen till en utgång så har den rätt nivå direkt.
Om ett avbrott (interrupt) kommer mitt i ovanstående, kan det bli fel då ?
>När pinnen är utgång styrs den av motsvarande bit i GPIO registret.
Jag är helt med på det.
>Du ska alltså ha en pullup på pinnen (eller "linjen" den är kopplad till,
>normalt gör man så här för att bygga en "bus" med flera processorer...).
Det är så jag tänkt.
Om jag förstått rätt:
Så alltså under tiden OC-pinnen är en ingång, så nollställer man motsvarande bit i GPIO.
Då skulle egentligen OC-pinnen nollställas, om den hade varit en utgång, det görs så att säga i luften.
Så när man sen gör om OC-pinnen till en utgång så har den rätt nivå direkt.
Om ett avbrott (interrupt) kommer mitt i ovanstående, kan det bli fel då ?
> Då skulle egentligen OC-pinnen nollställas, om den hade varit en utgång, det görs så att säga i luften.
Tja, i "luften" vet jag inte, det görs i GPIO registret.
Det är bara det att om pinnen än ingång, så finns det så att säga
igen koppling mellan GPIO och själva pinnen...
Om du tittar på schemat för GP0/GP1 i databladet, så ser du att det
finns en D-vippa där dete står "WR PORT" (jag tycker att det borde ha stått
"WR GPIO" men i alla fall). Den D-vippan är en en av bitarna i GPIO registret.
Sedan går utgången från den D-vippan till I/O pin via en buffert (den
trekantiga lilla saken).
Sen finns det en D-vippa till vid "WR-TRISIO". Notera att en av utgångarna
från *den* vippan (som alltså utgör en bit av TRISIO) styr den lilla
bufferten och kan sätta den i högimp läge.
Notera att "RD PORT" läser pinnen *efter* bufferten, så om pinnen är
en ingång så läses nivån på pinnen, inte på GPIO vippan. Det är därför
det kan bli problem när man gör bcf/bsf på *andra* pinnar, eftersom
alltid hela GPIO läses och skrivs tillbaka (och alltså sätter GPIP
vippan = aktuell nivå på pinnen...).
Tja, i "luften" vet jag inte, det görs i GPIO registret.
Det är bara det att om pinnen än ingång, så finns det så att säga
igen koppling mellan GPIO och själva pinnen...
Om du tittar på schemat för GP0/GP1 i databladet, så ser du att det
finns en D-vippa där dete står "WR PORT" (jag tycker att det borde ha stått
"WR GPIO" men i alla fall). Den D-vippan är en en av bitarna i GPIO registret.
Sedan går utgången från den D-vippan till I/O pin via en buffert (den
trekantiga lilla saken).
Sen finns det en D-vippa till vid "WR-TRISIO". Notera att en av utgångarna
från *den* vippan (som alltså utgör en bit av TRISIO) styr den lilla
bufferten och kan sätta den i högimp läge.
Notera att "RD PORT" läser pinnen *efter* bufferten, så om pinnen är
en ingång så läses nivån på pinnen, inte på GPIO vippan. Det är därför
det kan bli problem när man gör bcf/bsf på *andra* pinnar, eftersom
alltid hela GPIO läses och skrivs tillbaka (och alltså sätter GPIP
vippan = aktuell nivå på pinnen...).
Rent spontant känns detta förfarande en smula märkligt, lite som att "be om problem"... Antar att det finns en tanke bakom, som jag dock inte ser.sodjan skrev:> Notera att "RD PORT" läser pinnen *efter* bufferten, så om pinnen är
en ingång så läses nivån på pinnen, inte på GPIO vippan. Det är därför
det kan bli problem när man gör bcf/bsf på *andra* pinnar, eftersom
alltid hela GPIO läses och skrivs tillbaka (och alltså sätter GPIP
vippan = aktuell nivå på pinnen...).
Vid läsning av porten så måste man läsa från ingången om man bara har ett läsregister annars får du inte in indata med porten som ingång. Lösningen är ett extra register där du kan läsa ut latchens data vilket är infört i PIC18-arkitekturen. Detta är inget speciellt udda utan väldigt vanligt på mikrokontrollers I/O-pinnar.
