 |
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
Silvo Moderator


 
Pridružen-a: Pon 24 Feb 2003 17:09 Prispevkov: 14673 Aktiv.: 61.95 Kraj: Koroška-okolica Dravograda
|
Objavljeno: Čet Jun 16, 2005 9:02 am Naslov sporočila: PIC in port latch |
|
|
Moram reči, da sem naletel na zanimivo "težavo" , ki mi je "požrla" kar nekaj časa.
Pisal sem eno rutinco za I2C za 12F675. Glede na to, da sem hotel stanje 1-0 izvesti s preklopom vhoda na izhod (stanje 1- pin definiran kot vhod na 1 ga "potegne" pullup stanje 0 - pin izhod z nizkim stanjem)
Načeloma velja, da se lahko stanje v port lath, ki sicer ni fizičen register vpišemo pred tem, da pine spremenimo na izhode sem to hotel storiti na čim enostavnejši način. Primer start bita:
Koda: |
#define SDA GPIO,5
#define SCL GPIO,4
;--------------------------------------------------
;procedura poslje start bit
;--------------------------------------------------
I2C_START
bcf SDA
bcF SCL
bsf STATUS,RP0
bsf SCL ;-pina sta visoka vhoda
bsf SDA ;/
call P5uS
bcf SDA
call P5uS
bcf SCL
bcf STATUS,RP0
return |
Ampak na moje začudenje zadeva ni delala kot je napisano - pin SDA je ostal VISOK sicer izhod
Ko sem stvar napisal malo drugaše pa je stvar delala ..
Koda: |
;--------------------------------------------------
;procedura poslje start bit
;--------------------------------------------------
I2C_START
clrf GPIO
bsf STATUS,RP0
bsf SCL ;-pina sta visoka vhoda
bsf SDA ;/
call P5uS
bcf SDA
call P5uS
bcf SCL
bcf STATUS,RP0
return
|
Zaključek tega - v port lath je potrebno vpisati z eno instrukcijo cel port. Ce se postavi le en bit se vsi ostali biti postavijo na visoko stanje.
Če, kdo uprablja kak simulator naj proba - prav zanima me kako bo to "prebavil" simulator. _________________ lp
Silvo |
|
Nazaj na vrh |
|
 |
twom Član


Pridružen-a: Ned 26 Okt 2003 0:37 Prispevkov: 986 Aktiv.: 4.16 Kraj: Ljubljana
|
Objavljeno: Sob Jun 18, 2005 7:24 am Naslov sporočila: |
|
|
Kaj pa če je potrebno upoštevati tole:
5.4 I/O Programming Considerations
5.4.1 BI-DIRECTIONAL I/O PORTS
Any instruction which writes, operates internally as a
read followed by a write operation. The BCF and BSF
instructions, for example, read the register into the
CPU, execute the bit operation and write the result back
to the register. Caution must be used when these
instructions are applied to a port with both inputs and
outputs defined. For example, a BSF operation on bit5
of GPIO will cause all eight bits of GPIO to be read into
the CPU. Then the BSF operation takes place on bit5
and GPIO is written to the output latches. If another bit
of GPIO is used as a bi-directional I/O pin (i.e., bit0) and
it is defined as an input at this time, the input signal
present on the pin itself would be read into the CPU and
rewritten to the data latch of this particular pin, overwriting
the previous content. As long as the pin stays in the
input mode, no problem occurs. However, if bit0 is
switched to an output, the content of the data latch may
now be unknown.
Kopirano iz Microchip PIC12C67x - 30561b datasheeta
P.S. Silvo ali sta kodi v tvojem sporočilu v napačnem vrstnem redu?
Lp,
Peter |
|
Nazaj na vrh |
|
 |
Silvo Moderator


 
Pridružen-a: Pon 24 Feb 2003 17:09 Prispevkov: 14673 Aktiv.: 61.95 Kraj: Koroška-okolica Dravograda
|
Objavljeno: Sob Jun 18, 2005 10:11 am Naslov sporočila: |
|
|
Da, Peter prav to je.
Ker mi ni dalo miru sem zadevo še testiral v praksi.
Torej v primeru, ko nasloviš cel port istočano so pini po je stanje po preklopu na izhode tako kot smo ga naslovili.
Koda: |
movlw b'101'
movwf PORTB
bsf STATUS,RP0
clrf TRISB
bcf STATUS,RP0
|
Ne glede na to, da so na vseh pinih recimo pullup upori, bo v zgornjem primeru le pin RB0 ter RB2 visok.
Če pa napišemo drugače:
Koda: |
bsf PORTB,0
bcf PORTB,1
bsf PORTB,2
movwf PORTB
bsf STATUS,RP0
clrf TRISB
bcf STATUS,RP0 |
Če bomo imeli v tem primeru pullup upore pa bo cel port po preklopu na visokem nivoju
Zakaj; Na zadnje smo definirali RB2 kot visok - ostali pini pa so bili vhodi ter se je port latch "napolnil" s stanja na njih.
Iz tega tudi zgoraj opisana moja "težava". Na pinih namreč imam pullup upore. _________________ lp
Silvo |
|
Nazaj na vrh |
|
 |
Oliver Član

Pridružen-a: Sre 27 Okt 2004 13:36 Prispevkov: 39 Aktiv.: 0.16 Kraj: Ljubljana
|
Objavljeno: Sob Jun 18, 2005 11:43 pm Naslov sporočila: Re: PIC in port latch |
|
|
Silvo je napisal/a: |
Moram reči, da sem naletel na zanimivo "težavo" , ki mi je "požrla" kar nekaj časa.
|
Dobrodošel v (zelo množičen) klub žrtev zloglasnega READ-MODIFY-WRITE načina delovanja portov na PIC-ih.
Citiram: |
Zaključek tega - v port lath je potrebno vpisati z eno instrukcijo cel port. |
Tako je!
Citiram: |
Ce se postavi le en bit se vsi ostali biti postavijo na visoko stanje. |
Tako je v tvojem primeru, ker imaš na fizičnem portu pullupe, splošno pa velja: ostali biti se postavijo v tako stanje, kot je bilo stanje na fizičnem portu v času ukaza.
peter_nn je napisal/a: |
Kaj pa če je potrebno upoštevati tole:
5.4 I/O Programming Considerations
5.4.1 BI-DIRECTIONAL I/O PORTS |
Točno to.
Ker je ta READ-MODIFY-WRITE tako pogost vir nepričakovanega obnašanja programov bom še enkrat povzel:
Ko vpisujemo vrednost na port vpisujemo pravzaprav v port latch. Vrednost na pinu je vrednost port latcha, če je ustrezen pin definiran kot output in ni kakšne zunanje periferije, ki bi prevpila pic. Če je pin definiran kot input, je seveda vrednost na pinu, kot ga definira periferija, če periferija ne definira stanja pa pin "plava" (kar ni priporočljivo). Sedaj pa zelo važno: pri kakeršnem koli ukazu, ki vpisuje v port latch se vpisovanje izvrši v treh korakih: najprej se cel byte (tudi če vpisujemo na samo en bit) včita iz fizičnih pinov (READ), potem se ustrezne bite spremeni, kot to zahteva ukaz - npr. BFS postavi ustrezen bit, XORWF izvede exclusive or med W in prej včitanimi vrednostmi s fizičnih pinov itd. (MODIFY), potem se šele tako popravljene vrednosti vpišejo v port latch (WRITE). Tako vidimo, da trenutna vrednost na fizičnih pinih "zaide" v port latch, kar pa nas velika večina vse prerado pozabi!
modificiran Silvotov primer:
Koda: |
- pomeni nas ne zanima, X pomeni ali 0 ali 1
1 na PORT PINU pomeni napetost blizu napajanja
0 na PORT PINU pomeni napetost blizu 0
na začetku je port definiran ko input
Komentar 12 34 1-4: komentarji za ustrezne bite
UKAZ PORT LATCH PORT PINI
; ------XX ------11
bcf PORTB,0 ; ------10 ------11 1: prepis s 4; 2: ukaz; 3 in 4: pull up
bcf PORTB,1 ; ------01 ------11 1: ukaz; 2: prepis s 3; 3 in 4: pull up
bsf STATUS,RP0 ; ------01 ------11 ni sprememb
clrf TRISB ; ------01 ------01 4: zaradi 2. ukaza 1 namesto željene 0
|
Vendar je to šele polovica zgodbe in to tista ta manj zoprna in bolj predvidljiva.
Na drugo polovico opozarja odstavek v priročniku, ki sledi že citiranemu in pravi:
ZAPOREDNE OPERACIJE NA I/O PORTih
Dejanski vpis na I/O port se zgodi ob koncu ukaznega cikla, medtem ko mora biti za branje vrednost na portu prave vrednosti že na začetku ukaznega cikla. Zatorej je potrebno paziti, če vpisu sledi branje (moja opomba: ki se izvrši tudi pri vpisu - zaradi READ-MODIFY-WRITE) na istem I/O portu. Zaporedje ukazov naj bi bilo tako, da se napetost na pinu že ustali (odvisno od bremena), preden se začne izvrševati naslednji ukaz, ki včitava z istega pina. Sicer se lahko zgodi, da bo v procesor včitana prejšnja vrednost na tem pinu, namesto nove. V dvomu, je med take ukaze bolje vriniti dodatni NOP ali pa kakšen drug ukaz.
Najbolje, da zopet pogledamo primer:
Koda: |
- pomeni nas ne zanima, X pomeni ali 0 ali 1
1 na PORT PINU pomeni napetost blizu napajanja
0 na PORT PINU pomeni napetost blizu 0
^ napetost narašča, kako hitro, je odvisno od bremena
? neznana vrednost
Komentar 12 34 1-4: komentarji za ustrezne bite
UKAZ PORT LATCH PORT PINI
; ------00 ------00
bsf PORTB,0 ; ------01 ------1^ 4: napetost narašča
bsf PORTB,1 ; ------1? ------1? 2: če je napetost že dovolj narastla 1 sicer 0
|
In zakaj je to še veliko bolj zoprno, kot ono prej? Zato ker je bilo ono prej vsaj predvidljivo (čeprav se dostikrat pozabi), medtem ko si tuka vedno lahko v dvomu. Tudi če program lepo teče na testni plošči ali pa celo na ta pravi, ni zagotovila, da se ti ob drugih pogojih (beri: drugačna obremenitev zaradi spremenjene periferije, temperature, vlage, položaja zvezd ali menstrualnega ciklusa) program nenadoma ne začne obnašati povsem drugače, kot si nameraval. Kako vedeti ali je potreben dodaten NOP, ali morda celo dva, trije? Ker je to res tako zoprno so pri Microchipu to pri seriji 18-ic odpravili tako, da se pri READ fazi vrednosti zajemajo iz port latcha ne pa iz fizičnih pinov, ta port latch pa je tudi dosegljiv z ukazi. Beremo lahko torej npr. PORTB (vrednisi na pinih) ali pa LATB (vrednosti na port latchu).
Se opravičujem za malo daljše sporočilo, ampak upam, da bo s tem vsaj komu prihranjeno nekaj časa in živcev.
LP, Oliver |
|
Nazaj na vrh |
|
 |
Silvo Moderator


 
Pridružen-a: Pon 24 Feb 2003 17:09 Prispevkov: 14673 Aktiv.: 61.95 Kraj: Koroška-okolica Dravograda
|
Objavljeno: Ned Jun 19, 2005 9:40 am Naslov sporočila: |
|
|
Oliver hvala za zanimivo razlago. Vrjamem, da bo marsikomu prišla prav. Če prav se s pici ukvarjam že dolgo, nekako še nisem "padel" na to "foro" kar se mi je zgodilo.. Tole se je zgodilo zgolj slučajno. Vedno kadar sem pin uporabljal kot I/O sem stanje na portu pred preklopom shranil v en začasni register, preklopil pin na vhod prebral stanje, ga vrnil na izhod ter mu vrnil stanje iz začasnega regista. Izhodom pa običajno menjam stanje, ko so le ti že definirani kot izhodi.
Mimogrede, če sem prav videl datashet za serijo 18Fxxx ima ta serija že fizičen port latch register? _________________ lp
Silvo |
|
Nazaj na vrh |
|
 |
Silvo Moderator


 
Pridružen-a: Pon 24 Feb 2003 17:09 Prispevkov: 14673 Aktiv.: 61.95 Kraj: Koroška-okolica Dravograda
|
Objavljeno: Ned Jun 19, 2005 10:13 am Naslov sporočila: |
|
|
Silvo je napisal/a: |
Mimogrede, če sem prav videl datashet za serijo 18Fxxx ima ta serija že fizičen port latch register? |
Oliver mi je zgoraj že odgovoril. Pri prvem branju spročila sem to očitno spregledal.  _________________ lp
Silvo |
|
Nazaj na vrh |
|
 |
Silvo Moderator


 
Pridružen-a: Pon 24 Feb 2003 17:09 Prispevkov: 14673 Aktiv.: 61.95 Kraj: Koroška-okolica Dravograda
|
Objavljeno: Pon Jun 20, 2005 6:26 am Naslov sporočila: |
|
|
Mimogrede, je kdo posusil kako tole "READ-MODIFY-WRITE" prebavljajo simulatorji?  _________________ lp
Silvo |
|
Nazaj na vrh |
|
 |
polh Član


Pridružen-a: Pet 08 Apr 2005 18:27 Prispevkov: 225 Aktiv.: 0.95 Kraj: Maribor-Ljubljana
|
Objavljeno: Čet Apr 27, 2006 9:56 pm Naslov sporočila: |
|
|
Isti problem me je mučil nekoliko časa nazaj. Takrat sem slučajno stvar nekak popravil (malo spremenil kodo) in je delalo. Zdaj vsaj vem kaj je bilo narobe.
Na problem sem pa naletel v skoraj istem primeru kot Silvo. Pri I2C  |
|
Nazaj na vrh |
|
 |
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 492 dni
Powered by phpBB © 2001, 2005 phpBB Group
|