Sida 1 av 1
PIC ställer om PORT-register själv? (Svar: Nej, RMW-fel.)
Postat: 14 november 2007, 11:34:10
av Tottish
Detta får jag inte riktigt att gå ihop och som vanligt så skyller jag på Microchip och att deras chip gått sönder istället för att direkt erkänna att allt är mitt fel. =)
Skämt å sido, Jag kör med en PIC16f886 och har saxat ett litet test-case nedan.
Kod: Markera allt
banksel PORTB
clrf PORTB ;Set all pins on PORTB low
*bsf PORTB, 4* ;except Pin 4
Start
call Delay_2
banksel TRISB
bcf TRISB, 0
call Delay_2
banksel TRISB
bsf TRISB, 0
goto Start
Jag har intärna Pull-ups tilslagna på samtliga pinnar i PORTB. Koden skall alltså generera en fyrkantsvåg med periodtiden ca 2 x Delay_2 = 50ms på RB0.
Detta klarar den galant om raden märkt med * utelämnas. Om jag däremot inkluderar den raden (naturligtvis utan *-tecken) så verkar det som att även PORTB, 0 ställs till logiskt ett. På skopet får jag upp en något fladdrig "5V-linje" i det sisstnämnda fallet. Ser precis ut som när man har en pull-up på en pinne, PORT-värdet ställt till 1 och växlar mellan I/O på densamma.
Vad är det som händer här igentligen? Någon som känner igen problematiken?
Förbehåller mig rätten för att det, mycket väl, kan vara ett idiotfel, jag har vart uppe för länge =).
Ha en bra dag!
/Tottish
Postat: 14 november 2007, 13:15:11
av sodjan
Du har inte ett komplett exempel så att man ser hur du
t.ex hanterar de analoga funktionerna på PORTB ?
Postat: 14 november 2007, 17:10:23
av Tottish
Det kan jag ordna. Får dock vænta tills imorgon eftermiddag. Då kan jag æven sjælv se øver hur jag egentligen stællt in analog-registren. Har inte alls hållt på med analoga funktionerna så det ær møjligt att jag missat något dær.
Vill bestæmt minnas att jag har kørt clrf på ansel och anselh i alla fall. Kan ju alltid passa på att læsa på lite om de analoga funktionerna om jag får død-tid hær på jobbet =). Man har ju hørt att de kan generera en del skumma fel om man inte hanterar dem korrekt så dær kanske vi har boven.
Kan væl tillægga att det fungerade felfritt tills jag flyttade kopplingen från (solderless) lab-plattan till en sån som man løder fast komponneterna på.
Hmm.. tror det ær tredje tråden jag startar om den hær "flytten". Tycker att det har varit naturligt eftersom problemen har dykt upp efter hand och har handlat om ganska olika saker. Sæg gærna till om ni tycker att jag borde hållt mig till en tråd. Så man får høra vad ni tycker.
MVH
/Tottish
Postat: 14 november 2007, 17:13:46
av sodjan
Jo, det kan ju alltid hjälpa att veta att det är samma koppling
det gäller...
> Har inte alls hållt på med analoga funktionerna så det ær møjligt att jag missat något dær.
Det brukar finnas ett tydligt exempel i en egen rute i avsnittet
om PORT's i databladet. Följer man det så brukar det fungera.
Postat: 14 november 2007, 20:36:42
av bengt-re
Det är ett vanligt misstag att glömma att stänga av komparatorn...
Postat: 15 november 2007, 16:20:30
av Tottish
Hemma till sist då!
Nu har jag lyckats isolera felet eller åt minstone gjort en väldigt liten kod som jag inte förstår varför "felet" uppstår i.
Har skummat igenom PORTB i databladet men inte hittat något kortfattat exempel på hur man får av alla analoga funktioner. Enligt vad jag kunde förstå (okej, jag läste inte jätte-noggrant) så var det bara ANSELH som skulle clear:as efter POR de andra funktionerna (utom digital I/O) måste man väl själv aktivera för att de ska fungera?
Lägg till dessa rader kod ovanför det jag postade i första inlägget så har ni hur hela min kod ser ut nu så när som på konfigurations-bitarna.
Kod: Markera allt
banksel ANSEL
clrf ANSEL
clrf ANSELH
banksel TRISB
movlw b'11111111' ;All RB to inputs
movwf TRISB
Är det någon analog funktion som jag har förbisett som spökar i min krets?
Har föresten också slagit av (låtit bli att slå på) de intärna pull-upsen som jag hade tidigare. För att isolera felet. Använder nu en extärn pull-up på ca 100kΩ.
MVH
/TOttish
Postat: 15 november 2007, 16:36:28
av sodjan
OK, vi tar en sak i taget...
För att :
bcf TRISB, 0
bsf TRISB, 0
ska fungera så måste PORTB,0 vara "0", OK ?
D.v.s i ena läget så drar pullupen (int eller ext spelar ingen roll) pinnen till "1"
och i den andra läget så drar PORTB-registret pinnen till "0".
Det fenomen du ser tyder på att PORTB,0 är = "1".
Sen så, om PB0 är en *ingång* när du gör "bsf PORTB, 4",
så kommer även PORTB,0 att sättas till "1". Kom ihåg
att BSP/BCF mot ett PORTx register alltid först läser *HELA* PORTx,
sedan ändrar den bit som ligger i kommandot, och sen skriver tillbaka
*HELA* PORTx registret.
Notera att en läsning från en PORTx alltid ger vad som
faktiskt finns på den *fysiska* pinnen, och med en pullup
så är ju en ingång alltid "1".
Så även om du först gör BCF PORTB,0 så kommer den att sättas
till "1" så fort du gör något annat mot någon annan pinne på PORTB !
Ett klassiskt R-M-W fenomen !
Lösningen är att sätta pinnarna i rätt ordning.
Allternativt se till att ha PORTB,0 som utgång medans alla
pinnar sätts upp, det beror på vad som passar din applikation.
Eller att sätta RB4 först och RB0 sedan...
Postat: 15 november 2007, 17:00:00
av Tottish
Sodjan skrev:
Notera att en läsning från en PORTx alltid ger vad som
faktiskt finns på den *fysiska* pinnen, och med en pullup
så är ju en ingång alltid "1".
DÄR gick det upp ett ljus för mig. Har aldrig förstått vad RMW faktiskt innebär. Trodde att PORTB-bitarna bara var knutna till utgångarna när TRISB för motsvarande pinne var 0. Förstod därför inte varför databladet var så noggrant med att poängtera att den läser PORTB innan den skrev till densamma.
Tack för att du tänt ytterligare ett ljus i min trötta hjärna, Sodjan!
Ska ändra detta så att jag får fason på det hela. Tyvärr får det kanske vänta tills imorgon då jag är trött som en liten gris.
Tack igen!
MVH
/Tottish
Postat: 15 november 2007, 17:02:58
av sodjan
> Trodde att PORTB-bitarna bara var knutna till utgångarna när TRISB för motsvarande pinne var 0.
Exakt så är det !
Annars så styrs pinnen av omvärlden (och eventuellt av intern pullup).
> Förstod därför inte varför databladet var så noggrant med att poängtera att den läser PORTB innan den skrev till densamma.
Det säger *INTE* så !!!
Det säger att den läser från "the port pins" (eller något likannde),
INTE att den läser från PORTB (d.v.s själva *registret*).
EDIT:
Notera att man *ALDRIG*, vad man än gör, kan *LÄSA* från själva
*registret* PORTB. Man läsar alltid från *pinnarna*...
Postat: 15 november 2007, 17:35:21
av Tottish
Helt rätt Sodjan. Så blir det, ja. Och så står det i databladet. Den läser pinnarna i porten, modifierar det man sagt åt den och skriver sedan till PORTx.
Fråga: Varför läser den inte från PORTx (alltså registret och inte de fysiska pinnarna) istället? Förstår att det finns fördelar med detta sätt men... Hm, det känns som att läsa PORTx borde vara bättre i de flesta lägen.
Nu kan jag ju inte påstå att jag känner mig i stånd till att konstruktivt kunna ifrågasätta Microchips val i designen av dessa små fantastiska chip men ändå. =)
/Tottish
Postat: 15 november 2007, 19:11:48
av squiz3r
Detta va en bra tråd!
Det förklarar nog ett antal konstiga "ologiska" fel jag har haft
Tack!
Mvh
Postat: 15 november 2007, 21:47:11
av sodjan
> Varför läser den inte från PORTx...
Varför är solen gul ? Tja, det är så det är bara...
Sen är det naturligtsvis väldigt förvirrande att man i *koden* läser från PORTB...
Notera att PIC18 serien har något som kallas LATx.
Vid *skrivning* så fungerar (t.ex) LATB och PORTB exakt likadant.
Men vid *läsning* så läser LATB från "output latches", inte från själva pinnarna.
Därför existerar inte R-M-W på PIC18 när man användr LATx registren.
Postat: 16 november 2007, 06:12:54
av Tottish
OK! Låter bra det. Tror det får bli PIC18 i næsta projekt, de verkar trevliga på många sætt!
Tack før en bra tråd, sodjan. See you in the next one!
MVH
/Tottish