16F886, PORTB beter sig mycket konstigt...
16F886, PORTB beter sig mycket konstigt...
Hejsan!
Hade tänkt att börja exprimentera med AD-omvandling och har därför införskaffat en PIC 16F886.
Började som vanligt med att ställa in CONFIG-Word, samt köra det gamla "blinka led" programmet. Inga problem alls...
Då var det bara en LED som styrdes.
Men när jag sedan skulle börja styra flera LEDs på PORTB så hände något mycket konstigt...
Om man försöker förändra värdet i PORTB på något annat sätt än att skriva tex PORTB=23; så blir alla bitar 0.
Om man skriver:
PORTB=23;
PORTB.0=0;
Dvs: sätt PORTB till 23 och 0-ställ bit 0 i PORTB
Då blir alla bitarna i PORTB 0...
Men om man gör exakt samma sak på tex PORTC så blir det inga problem..
Följande program används för att göra ett rinnande ljus: Rinnande Ljus
Om man använder PORTB(som i programet) så blir det bara ett kort blink på PORTB.0 och PORTB.2.
Om man sedan kopplar om hårdvaran och
använder PORTC så får man ett rinnande ljus..
(Hårdvaran alltid samma, förutom portbyte)
Vad kan det vara?
Edit: Radbrytningar
Hade tänkt att börja exprimentera med AD-omvandling och har därför införskaffat en PIC 16F886.
Började som vanligt med att ställa in CONFIG-Word, samt köra det gamla "blinka led" programmet. Inga problem alls...
Då var det bara en LED som styrdes.
Men när jag sedan skulle börja styra flera LEDs på PORTB så hände något mycket konstigt...
Om man försöker förändra värdet i PORTB på något annat sätt än att skriva tex PORTB=23; så blir alla bitar 0.
Om man skriver:
PORTB=23;
PORTB.0=0;
Dvs: sätt PORTB till 23 och 0-ställ bit 0 i PORTB
Då blir alla bitarna i PORTB 0...
Men om man gör exakt samma sak på tex PORTC så blir det inga problem..
Följande program används för att göra ett rinnande ljus: Rinnande Ljus
Om man använder PORTB(som i programet) så blir det bara ett kort blink på PORTB.0 och PORTB.2.
Om man sedan kopplar om hårdvaran och
använder PORTC så får man ett rinnande ljus..
(Hårdvaran alltid samma, förutom portbyte)
Vad kan det vara?
Edit: Radbrytningar
Ja, det behövs, ifall Du vill kunna läsa hur utgångarna står.
Vid läsning så läses pinnens status, inte latchen. När en enda bit skall ändras så läses porten, biten ändras och alla åtta bits skrivs tillbaka. Eftersom då de som är analogkonfiguerade läses som nollor så skrivs de tillbaka som nollor fast de skulle vara ettor.
Alternativen är att konfigurera rätt (enklast), använd en kopia at manipulera och skriv sedan till porten (mindre manualläsande?) eller använda PIC18 där latchen kan läsas (kräver även det lite manualläsande så rätt register används).
Vid läsning så läses pinnens status, inte latchen. När en enda bit skall ändras så läses porten, biten ändras och alla åtta bits skrivs tillbaka. Eftersom då de som är analogkonfiguerade läses som nollor så skrivs de tillbaka som nollor fast de skulle vara ettor.
Alternativen är att konfigurera rätt (enklast), använd en kopia at manipulera och skriv sedan till porten (mindre manualläsande?) eller använda PIC18 där latchen kan läsas (kräver även det lite manualläsande så rätt register används).
På ett ställa står det "I/O pins configured as analog input always read 0."
Lite otydligt kanske...
På ett annat (betydligt tydligare) :
"The state of the ANSELH bits has no affect on digital
output functions. A pin with TRIS clear and ANSELH
set will still operate as a digital output, but the Input
mode will be analog. This can cause unexpected
behavior when executing read-modify-write
instructions on the affected port."
Och "Unexpected" var väl precis vad det blev.
Och det är alltså det du gör med dina instruktioner som försöker
ändra en enstaka pinne, alla pinnarna läses (R) som "0", din bit ändras (M)
och det hela skrivs tillbaka (W). Och alltså kommer alla andra bitar
att vara 0 efter operationen. D.v.s ett "R-M-W-problem".
Men, som sagt, varför har du pinnarna som *analoga* I/O-pinnar alls ??
Lite otydligt kanske...
På ett annat (betydligt tydligare) :
"The state of the ANSELH bits has no affect on digital
output functions. A pin with TRIS clear and ANSELH
set will still operate as a digital output, but the Input
mode will be analog. This can cause unexpected
behavior when executing read-modify-write
instructions on the affected port."
Och "Unexpected" var väl precis vad det blev.

Och det är alltså det du gör med dina instruktioner som försöker
ändra en enstaka pinne, alla pinnarna läses (R) som "0", din bit ändras (M)
och det hela skrivs tillbaka (W). Och alltså kommer alla andra bitar
att vara 0 efter operationen. D.v.s ett "R-M-W-problem".
Men, som sagt, varför har du pinnarna som *analoga* I/O-pinnar alls ??
Ja... Varför har jag dom som analoga?
Än en gång har net4all's oförmåga att läsa datablad ordentligt skapat en ny tråd!
Hade uppenbarligen missat det med read-modify-write och
trott att output inte skulle påverkas...
Men nu fungerar det, så: Tack för hjälpen allihop!
(ADC nästa, hoppas det går lättare, har ju exempelkod!)
Än en gång har net4all's oförmåga att läsa datablad ordentligt skapat en ny tråd!
Hade uppenbarligen missat det med read-modify-write och
trott att output inte skulle påverkas...

Men nu fungerar det, så: Tack för hjälpen allihop!

(ADC nästa, hoppas det går lättare, har ju exempelkod!)
Istället för att skapa en ny tråd så frågar jag här igen:
ADC'n fungerar med en trimpot, dvs 3-polig, AD pinnen får en spänning mellan VSS till VDD. Allt funkar
Men hur ska jag göra om jag har ett temperaturkänsligt motstånd?
Dvs en termistor, resistans ca 100-200 ohm
Kan inte hitta något som går igenom hårdvaran till ADC'n, bara mjukvaran, som jag redan löst...
ADC'n fungerar med en trimpot, dvs 3-polig, AD pinnen får en spänning mellan VSS till VDD. Allt funkar

Men hur ska jag göra om jag har ett temperaturkänsligt motstånd?
Dvs en termistor, resistans ca 100-200 ohm
Kan inte hitta något som går igenom hårdvaran till ADC'n, bara mjukvaran, som jag redan löst...
> Kan inte hitta något som går igenom hårdvaran till ADC'n,
Databladet har allt om ADC'n både hård och mjukvara.
Däremot så finns det inget i databladet om vad du gör *utanför*
processorn, förrutom minsta impedans t.ex.
> Dvs en termistor, resistans ca 100-200 ohm...
Igen speciellt bra "temperaturmätare", men du kan göra en enkel
spänningsdelare med termistorn och ett motstånd. Eventuellt med en
opamp för att få ett bättre sving, eller helt enkelt en riktigt temp-givare...
Databladet har allt om ADC'n både hård och mjukvara.
Däremot så finns det inget i databladet om vad du gör *utanför*
processorn, förrutom minsta impedans t.ex.
> Dvs en termistor, resistans ca 100-200 ohm...
Igen speciellt bra "temperaturmätare", men du kan göra en enkel
spänningsdelare med termistorn och ett motstånd. Eventuellt med en
opamp för att få ett bättre sving, eller helt enkelt en riktigt temp-givare...
- JimmyAndersson
- Inlägg: 26586
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
Jaså? Har inte lyckats hitta något...
Men jag har fått det att fungera med spänningsdelare, dock har jag inte gått in på att omvandla ADC'ns värde till grader C.....
En primitiv robot sattes även ihop, mäter egen matnings spänning/varnar när batteriet blir dåligt, navigerar genom att mäta IR-ljus/+"vanligt" ljus
Jobbar vidare på ADC'n
Men jag har fått det att fungera med spänningsdelare, dock har jag inte gått in på att omvandla ADC'ns värde till grader C.....
En primitiv robot sattes även ihop, mäter egen matnings spänning/varnar när batteriet blir dåligt, navigerar genom att mäta IR-ljus/+"vanligt" ljus

Jobbar vidare på ADC'n
