PIC18F1320: Problem med PORTA

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
JimmyAndersson
Inlägg: 26603
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

PIC18F1320: Problem med PORTA

Inlägg av JimmyAndersson »

MikroBasic. PIC18F1320. Intern oscillator. (8MHz).
På PORTA.0 och PORTA.1 sitter två lysdioder. (En på varje pinne.) Dessa är kopplade med varsitt 330-ohms motstånd. Från MCLR går ett 10k motstånd till +5V. Det sitter avstörnings-kondingar över PIC'ens matningspänning. Resten av labbplattan är tom.



Jag stötte på något konstigt när jag debuggade en kod. Snabb problem-beskrivning:

Detta blinkar med båda lysdioderna samtidigt:

while true
PORTA = $FF
delay_ms(500)
PORTA = $00
delay_ms(500)
wend

-------

Om jag däremot gör såhär:

while true
PORTA.0 = 1
PORTA.1 = 1
delay_ms(500)
PORTA.0 = 0
PORTA.1 = 0
delay_ms(500)
wend

Så blinkar bara lysdioden på PORTA.1 (Den andra är släckt hela tiden.)
Byter jag plats på PORT-raderna så det blir såhär:

while true
PORTA.1 = 1
PORTA.0 = 1
delay_ms(500)
PORTA.1 = 0
PORTA.0 = 0
delay_ms(500)
wend

så blinkar bara lysdioden på PORTA.0 (Den andra är släckt hela tiden.)


Varför?? Det går förstås att komma runt, men det vore bra att veta varför det blir såhär.



Bifogar hela test-koden ifall någon vill kika:

Kod: Markera allt

'Använder interna oscillatorn.
'INTI02_OSC_1H är satt i Project -> Edit -> Device Flags.

'INTERN OSCILATOR SÄTTS HÄR!
OSCCON.IDLEN = 0 ' Run-mode enabled; CPU-core is clocked in Run-modes, but not in Sleep-mode.
OSCCON.IRCF2 = 1 ' 8MHz! Internal Oscillator Frequency. (Source drives clock directly.)
OSCCON.IRCF1 = 1 ' 8MHz! Internal Oscillator Frequency. (Source drives clock directly.)
OSCCON.IRCF0 = 1 ' 8MHz! Internal Oscillator Frequency. (Source drives clock directly.)
OSCCON.SCS1 = 1 ' Internal oscillator.

'Utgångar och rensar PORT A
TRISA = 0
PORTA = 0

'PORT A2 - A4 = Digitala in.
ADCON1 = %00001100

'Stäng av komparator..
CCP1CON = $0

'Stäng av interrupt..
INTCON = $0
PIE1 = $0
PIE2 = $0

'Low-voltage-detect = OFF  -Bara för att vara säker. :-)
LVDCON.LVDEN = 0

main:

while true
  PORTA.0 = 1
  PORTA.1 = 1
  delay_ms(500)

  PORTA.0 = 0
  PORTA.1 = 0
  delay_ms(500)
wend

end.
cyr
Inlägg: 2712
Blev medlem: 27 maj 2003, 16:02:39
Ort: linköping
Kontakt:

Inlägg av cyr »

Det var ett tag sen jag pysslade med PIC senast, men jag har för mig att bit-operationer på portarna är "read-modify-write", och att ingångar som är satta som analoga in alltid läses som 0.

Dvs när du kör PORTA.1 = 1 så läses hela PORTA in, bit 0 läses som 0 (fast du nyss satt den till 1), bit 1 sätts till 1 och sen skrivs resultatet tillbaka till porten (så att bit 0 skrivs som 0).

Om du ser till att PORTA bit 0,1 är digitala ingångar så funkar det nog bättre.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Lägg en kort (räcker med en eller ett par NOP, om du kan det)
delay mellen de två "=1" och "=0" oerationerns. Det *ser ut*
som RMW problemet.

Eller, byt PORTA.x => LATA.x
Användarvisningsbild
JimmyAndersson
Inlägg: 26603
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

MikroBasic klarar NOP, men eftersom det behövdes ganska många (fler än 3-4st) så provade jag med LAT istället, och det fungerade utmärkt.

Tack för hjälpen! :)
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> MikroBasic klarar NOP, men eftersom det behövdes ganska många (fler än 3-4st)

Lite märkligt att det behövdes så pass många NOP's. Har du något annat
på samma pinnar förrutom LED'arna ? Eller är det långa ledningar ?
Breadboard ?

> så provade jag med LAT istället, och det fungerade utmärkt.

Och jag hoppas att du har listat ut *varför*... :-)
Användarvisningsbild
JimmyAndersson
Inlägg: 26603
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Jag tror att jag förstått. :)

Svaret på läxan:
(Använder PORTA.0 och PORTA.1 som exempel.)

När man skriver till t.ex PORTA.0 så läses först hela porten lästs av, sedan modifieras detta och skrivs till data-latchen (och därefter till PORTA.0). RMW-problemet uppstår när två skrivningar (t.ex till PORTA.0 och PORTA.1) sker för tätt. Så att när man skriver till PORTA.1 och portens (utgångens) innehåll lagrats i data-latchen, så har inte innehållet från PORTA.0-skrivningen inte hunnit nå utgångs-pinnen. Därför syns inte skrivningen till PORTA.0 på utgången. (Den blir helt enkelt "överskriven" igen.) Hoppas det lät begripligt. :)

När man däremot skriver till LAT så läses innehållet från data-latchen, istället för att läsas från i/o-pinnen.

(Hoppas på bra betyg) :)


"Lite märkligt att det behövdes så pass många NOP's. Har du något annat på samma pinnar förrutom LED'arna ? Eller är det långa ledningar ?
Breadboard ?"


Inget annat på samma pinnar. Korta sladdar, så det ser inte ut såhär alltså. :D
Däremot sitter kretsen (och lysdioderna) mycket riktigt på ett breadboard.

När vi ändå är inne på breadboard:
Du råkar inte ha några till salu? :)
cyr
Inlägg: 2712
Blev medlem: 27 maj 2003, 16:02:39
Ort: linköping
Kontakt:

Inlägg av cyr »

När man använder PORTA så läses det direkt från själva pinnen, och när man använder LATA så läser man bara värdet som man tidigare skrivit till utgången.

Fast jag har själv aldrig märkt att värdet inte "hunnit" ut på en cykel. Det beror förstås på lasten på pinnen och andra saker i "omvärlden".
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Japp, stämmer.
Det stämmer också som cyr säger att det är inte så där jättevanligt
att man "ser" fenomenet. Det beror på två faktorer, vilken kapacitans
som pinner "ser" och vilket hastighet man kör processorn i.

> När vi ändå är inne på breadboard:
> Du råkar inte ha några till salu?

De fabriksnya jag hade är slut.
Jag har ett parti beg, 50:- inkl frakt och allt.
Är ganska skapliga...

/Janne.
Användarvisningsbild
JimmyAndersson
Inlägg: 26603
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

"Det beror på två faktorer, vilken kapacitans som pinner "ser" och vilket hastighet man kör processorn i."

Mycket bra att veta.


Breadboarden/labbplattorna är intressanta. Jag har renoverat sådana tidigare. :D :oops:
Hm, jag skickar ett PM. :)
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Igentligen är det som att "driva" vilken RC-länk som helst.

PIC pinnen kan inte driva oändligt med ström, alltså har den en
ekvivalent resistans på kanske några 10-tal ohm. Om man sedan
har en kapacitiv last (kan räcka med kontaktbanorna i en labbplatta
vid höga hastigheter) så har man en RC länk.

Varje intruktionscycel (Tcy) består av 4 faser. Skrivningen sker i sista
fasen och läsningen sker i första. Så om man har *två* BCF/BSF (eller
liknande) direkt efter varandra, så har inte pinnen en hel Tcy "på sig"
innan nästa läsning sker, utan snarare Tcy/4, eller samma som
oscillator frekvensen. I ditt fall med 8 Mhz, alltså 0.125 us. Om man lägger
till *en* NOP så har man plötstligt *en hel* Tcy ytterligare på sig, eller
(vid 8 Mhz) ca 0.125 + 0.5 = 0.625 us, fem gånger mer än innan.
Så en enda NOP kan göra stor skillnad och man tänker kanse inte på
att det gör så stor skillnad som 5 gånger...

Hur som helst, på PIC18 är lösningen oftast att köra med LATx registren.
Detta är en av de stora fördelarna med PIC18. PIC16 har i och för sig
samma *interna* arkitektur med ett "latch" register, men det är inte
"mappat" i minnesmappen bland övriga SFR's, så man kan inte använda
dete direkt i sin kod...

Och där kom PM'et när jag tryckte "Förhandsgranska"... :-)
Då kollar vi det istället......
Användarvisningsbild
JimmyAndersson
Inlägg: 26603
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Intressant! Man lär sig något nytt hela tiden. :)

Jahopp, nu har man spenderat lite pengar utan att resa sig från stolen.. :)
Skriv svar