Open collector I/O på PIC.

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
GoAmiga
Inlägg: 36
Blev medlem: 17 november 2005, 11:34:24

Open collector I/O på PIC.

Inlägg av GoAmiga »

Hej!
Har lite problem med att få en open collector utgång att fungera. Jag tänker bara dra upp hur jag gör i teorin och vill veta om det finns några minor man kan springa på, för jag tror att jag gjort det :(

Det jag ska göra är att skicka en byte seriellt på open collector vis. När jag vill ha en HÖG nivå sätter jag PIC's aktuella I/O till ingång . När jag vill ha den låg så gör jag den till utgång (och har dess för innan satt GPIO för pinnen till LÅG)

typ så här...
(Jag förutsätter att SYSDATA initialt är ingång)

Kod: Markera allt

bcf GPIO,SYSDATA ;I/O pinnen till låg
bsf STATUS,RP0             ;Bank1
bcf TRISA,SYSDATA        ; SYSDATA utgång (Låg)
call WAIT
bsf TRISA,SYSDATA        ;SYSDATA Ingång (Hög)
call WAIT
bcf TRISA,SYSDATA        ; SYSDATA utgång (Låg)
bcf STATUS,RP0             ;Bank0
vilket borde ge Låg, Hög, Låg....

I min "riktiga" kod så växlar jag mycket mer mellan bankerna eftersom jag har lagt vissa intressanta variabler i bank0. Kan detta ge mycket bekymmer? Finns det något smart sätt att lösa det så man slipper swappa mellan bankerna?
Jag använder en gammal 12c672. (Snälla ifrågasätt inte varför)
Pjoms
EF Sponsor
Inlägg: 644
Blev medlem: 24 maj 2004, 12:18:40
Ort: Ö-vik

Inlägg av Pjoms »

> "Jag använder en gammal 12c672. (Snälla ifrågasätt inte varför)"

Varför använder du en gammal 12c672?
Sorry, kunde inte hålla mig... :D :wink: :D
sodjan
EF Sponsor
Inlägg: 43265
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Hur är "SYSDATA" definierat. Du har missat att visa det...

Du har en pullup på "linjen" ?

> så man slipper swappa mellan bankerna?

Och vad är problemet med just *det* ???
Att du kör en gammal utgången "C" processor är ett större problem... :-)

> vilket borde ge Låg, Hög, Låg....

Och vad händer ???
Användarvisningsbild
Chribbe76
EF Sponsor
Inlägg: 1167
Blev medlem: 17 januari 2004, 22:43:17
Ort: Stockholm

Inlägg av Chribbe76 »

För att sänka en pinne måste du först sätta tris till utgång, sen lägga 0 på pinnen.

Problemet är att pinnen har gemensamt register för utgång och ingång så tillståndet utgång låg glöms bort när du ändrar till ingång.

Picar med LAT på portarna har olika register för utgång och ingång och blir då enklare att köra open collector med.

[EDIT]
Hmm... När man byter till utgång och pinnen är hög blir det ju kortslutning om någon gör utgång låg samtidigt.
Då går det alltså inte att köra open collector på ett korrekt sätt med en pic utan LAT.

Har jag rätt? Nu känner jag mig lite osäker.
sodjan
EF Sponsor
Inlägg: 43265
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> För att sänka en pinne måste du först sätta tris till utgång, sen lägga 0 på pinnen.

Helt fel ordning.

> När man byter till utgång och pinnen är hög

Den ska *aldrig* vara hög när pinnen är utgång.

> Då går det alltså inte att köra open collector på ett korrekt sätt med en pic utan LAT.

Jodå... :-)
Användarvisningsbild
Chribbe76
EF Sponsor
Inlägg: 1167
Blev medlem: 17 januari 2004, 22:43:17
Ort: Stockholm

Inlägg av Chribbe76 »

Är detta förfarande korrekt sodjan?

* Pinnen är utgång låg.

* Pinnen ändras till ingång och pinnen blir 1 av pullup.

* Pinnen ändras till utgång och kommer bli utgång hög eftersom den var 1 innan.
Användarvisningsbild
persika
EF Sponsor
Inlägg: 1551
Blev medlem: 31 juli 2006, 22:14:37
Ort: Österlen, Skåne

Inlägg av persika »

Läser denna tråd med intresse eftersom det är nästan samma som jag frågade om igår, se tråd "PIC IO ?"


Vad är LAT för någonting ?
Användarvisningsbild
Chribbe76
EF Sponsor
Inlägg: 1167
Blev medlem: 17 januari 2004, 22:43:17
Ort: Stockholm

Inlägg av Chribbe76 »

Är det så att portens värde bara ändras av att man läser av porten eller skriver till den?
Isf kan man skriva till porten när den är ingång och byta till utgång så får man rätt tillstånd direkt.

Det måste vara så det fungerar, det verkar vettigt.

LAT är ett register som innehåller tillståndet för utgången även om man har använt pinnen som ingång.
Om man inte har LAT så måste man lägga 0 på porten innan varje byte till utgång om man har läst av porten när den var ingång.

[EDIT] ändrade till utgång, lite trött idag
Senast redigerad av Chribbe76 25 oktober 2006, 19:05:34, redigerad totalt 2 gånger.
Användarvisningsbild
persika
EF Sponsor
Inlägg: 1551
Blev medlem: 31 juli 2006, 22:14:37
Ort: Österlen, Skåne

Inlägg av persika »

Vad betyder LAT ?
Användarvisningsbild
JimmyAndersson
Inlägg: 26650
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

LAT betyder att man inte orkar läsa databladet och kolla. :wink:


Men ok, LAT betyder Data Latch. :)
sodjan
EF Sponsor
Inlägg: 43265
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Är detta förfarande korrekt sodjan?

*Detta* är korrekt :
  1. Pinnen är utgång och låg.
  2. Pinnen sätts till ingång och "lyfts" till hög av pullup.
  3. En operation utförs som medför att GPIO (eller PORTx på en större PIC)
    läses och återskrivs (Read-Modify-Write, eller RMW). Pinnen kommer att
    läsas som hög och sättas som hög i GPIO (eller PORTx i en störe PIC).
  4. Pinnen sätts som utgång och kommer nu att "driva" pinnen hög...
Utan punkt 3 ovan händer ingenting...

> Är det så att portens värde bara ändras av att man läser av porten eller skriver till den?

*ALLA* operationer som skriver till ett register (behöver inte vara en *port*)
innebär att det först läses, sedan modifieras, slutningen skrivs tillbaka.

Det är klart att för instruktioner som hanterar *hela* registeret (CLRF,
MOVWF, INCF eller liknande) så är det ingen problem. Det är speciellt
BCF/BSF som medför RMW problem om man inte ser upp.

Lösningen är att hålla reda på "läget" på de pinnar som man vill
hantera på detta sätt någon annanstans än enbart i GPIO/PORTx.
Och sedan justera GPIO/PORTx precis innan man ändrar TRISIO/TRISx

LAT är (förrutom Jimmys helt korrekta förklaring) ett extra register i PIC18
serien som gör att man i princip inte har RMW problemet med dessa.
Om man har mycket "pin-wiggling" i sin kod, så är PIC18 betydligt
smidigare p.g.a detta.
GoAmiga
Inlägg: 36
Blev medlem: 17 november 2005, 11:34:24

Inlägg av GoAmiga »

Hej!
Finns det någon del i denna kod där man enkelt kan visa på att
här uppstår det ett fel. Ni behöver inte rätta till den i helhet men visa på var
jag får problem med att portarna ändras utan att jag "vill"


Kod: Markera allt

SEND_KEY

		bcf	GPIO,SYSDATA ;Sätter SYSDATA LÅG
		bcf	GPIO,SYSCLK    ;Sätter SYSCLK LÅG
		bsf	STATUS,RP0	;Bank1
		bcf	TRISA,SYSDATA    ;Data Går först låg (startbit)

NEXT_SEND_BIT
       bsf    STATUS,RP0 ;Behövs då vi hoppar till "NEXT_SEND_BIT" längre ner i koden.
		call	WAIT20			
		bcf	TRISA,SYSCLK	; CLK går låg för att klocka ut startbiten.
		call	WAIT12
		bsf	TRISA,SYSCLK	; CLK går hög
		
       bcf STATUS,RP0   ;Bank0 , där ligger SENDW varablen	
       rrf SENDW,f	; Rotera värdet i SENDW genom carry
		btfss	STATUS,C	;Var biten 1 eller 0?
		goto	LOW_S
		goto	HIGH_S

LOW_S	
      bsf STATUS,RP0   ;Bank1
		bcf	TRISA,SYSDATA
		goto	SEND_END

HIGH_S     
      bsf STATUS,RP0    ;Bank1
		bsf	TRISA,SYSDATA
		
SEND_END	
         bcf STATUS,RP0 ;Bank0, Där COUNT varabel ligger.
		decfsz	COUNT,f
		goto	NEXT_SEND_BIT		
		rrf		SENDW,f ;rotera Datat så det hamnar "rätt"
		
      bsf STATUS,RP0
		call	WAIT20
		bcf	TRISA,SYSCLK
		call	WAIT12
		bsf	TRISA,SYSCLK
			
		
sodjan
EF Sponsor
Inlägg: 43265
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Definitioner till SYSDATA och SYSCLK ?
Använd inte "egna" symboler utan att även visa att du har definierat dom rätt.

Använd gärna BANKSEL istället för BCF/BSF direkt på bank-bitarna.
Det blir mindre risk för (slarv-) fel. Därmed inte sagt att det är fel
i din kod, det vet jag inte (och jag tänker inte slå upp varje register
i data bladet för att kolla, kör med BANKSEL så slipper man det...)


(1) bcf GPIO,SYSDATA ;Sätter SYSDATA LÅG
(2) bcf GPIO,SYSCLK ;Sätter SYSCLK LÅG
(3) bsf STATUS,RP0 ;Bank1
(4) bcf TRISA,SYSDATA ;Data Går först låg (startbit)

Här har du precis det som har beskrivits i tidigare inlägg.

Jag utgår från att de "linjer" som båda SYSDATA och SYSCLK är kopplade
till har externa pullup motstånd ?

Förutsättning är att SYSDATA är ingång innan SEND_KEY...

I (1) sätts biten som SYSDATA pekar i GPIO låg.

I (2) sätts biten som SYSCLK pekar i GPIO låg.
*Samtidigt* kommer biten som sattes låg i (1), d.v.s SYSDATA, att
sättas hög igen eftersom *pinnen* hålls hög av pullup motståndet.
RMW fenomenet alltså!

I (4) sätts SYSDATA till utgång och *hög* !!

O.s.v....

Läs tidigare inlägg igen...

EDIT : Blandade ihop DATA och CLK lite...
GoAmiga
Inlägg: 36
Blev medlem: 17 november 2005, 11:34:24

Inlägg av GoAmiga »

Ok, då börjar jag förstå. Ursäkta för min tröghet och tack för ditt tålamod :)
sodjan
EF Sponsor
Inlägg: 43265
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Kanske detta skulle fungera bättre :

Kod: Markera allt

      bcf   GPIO,SYSDATA ;Sätter SYSDATA LÅG
      banksel trisa
      bcf   TRISA,SYSDATA    ;Data Går först låg (startbit)
      banksel  gpio
      bcf   GPIO,SYSCLK    ;Sätter SYSCLK LÅG
D.v.s att SYSDATA är *utgång* när SYSCLK sätts låg.
Då drivs DATA-linjen låg av SYSDATA, och den kommer alltså
att läsas "låg" när SYSCLK läses (i BCF instruktionens read-fas).

Beroende på hur snabt du kör processorn och hur mycket
capacitiv last DATA linjen har, så skulle jag sätta in en eller två
NOP för att säkerställa att DATA linjen hinner byta läge...

I resten av koden ser jag inte att du har just RMW fenomenet.
Men den kanske inte fungerar ändå... :-)
Skriv svar