PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Auslesen von Bytes des PCF 8574



JensB
19.09.2004, 00:22
Hallo miteinander,

ich habe folgendes vor:
Ein PCF 8574AP soll die Datensignale von 8 IR Sensoren an die C-Conrol 1
weitergeben, damit diese diverse Steuerungsaufgaben übernehmen kann.

Mein Problem dabei:
Ich weiß nicht genau wie das geht.

Was ich bereits weiß:
Ich weiß bereits, daß der PCF 8574 die Basisadresse 112 hat.

Was ich nicht weiß ist, wie ich die Portzustände des PCF 8574 in eine Bytevariable packe, so daß ich zB. mit einer Anweisung "if Byte=255 then portX = 1 etwas schalten könnte.

Ich habe mir berits folgendes Listing durchgelesen, kriege es mit einer modifizierten Version davon nicht hin.

' --- Definitionen --------------------

define SDA port[1]
define SCL port[2]
define Daten byte
define Zaehler byte
define N byte

' --- Programmoperationen -------------

SDA = ON
SCL = ON


#Loop
for Zaehler = 0 to 255
gosub Start
Daten = 112 'Adresse PCF8574
gosub I2C_Write
Daten = Zaehler
gosub I2C_Write
gosub Stop
gosub Start
Daten = 113 'PCF8574, Lesen
gosub I2C_Write
gosub I2C_Read
print Daten
gosub NoAck
gosub Stop
next

goto Loop 'Endlosschleife

#Start
SDA = OFF
SCL = OFF
return

#Stop
SDA = OFF
SCL = ON
SDA = ON
return

#I2C_WRITE
for N = 1 to 8
SDA= OFF
if (Daten AND 128) = 128 then SDA = ON
pulse SCL
Daten = Daten shl 1 '1 Bit nach links
next
pulse SCL ' 9. Impuls
return

#I2C_Read
Daten = 0
deact SDA ' SDA = Eingang
for N = 1 to 8
Daten = Daten shl 1 '1 Bit nach links
SCL = ON
if SDA then Daten = Daten + 1
SCL = OFF
next
return

#Ack
SDA = 0
pulse SCL
return

#NoAck
SDA = 1
pulse SCL
return

end

Ich habe bei diesem Listing versucht die Teile die für den Schreibvorgang notwendig sind wegzulassen, da ich diese für meine Problemstellung ja nicht benötige(glaube ich).

Wäre toll von Euch wenn mir jemand helfen könnte ein Listing zu schreiben, daß wie gesagt nur die 8 Portzustände des PCF in eine Bytevariable packt, so daß ich diese verwerten kann.

Live long and prosper

Jens

19.09.2004, 09:51
Hallo Jens

Wie sieht denn dein angepaßtes Programm aus ?

Zum Auslessen brauchst du nur die routine:
#schleife
gosub Start
Daten = 113 'PCF8574, Lesen
gosub I2C_Write
gosub I2C_Read
gosub NoAck
gosub Stop

'Die Eigänge stehen dann in der Variablen DATEN

'Die Auswertung währe dann:

if daten and 1 then ........ else .......
if daten and 2 then ....... else ......
.......
if daten and 128 then ......... else.....
goto schleife


Denke auch an die Pullup-Widerstände.


gruß Harald

19.09.2004, 13:42
Hallo Harald, habs gestern Nacht um 02:00 Uhr noch hinbekommen, ich hatte über das Hyperterminal versucht die Daten auszulesen, jedoch immer nur den Wert 255 erhalten, jetzt weiß ich woran es lag......Ich hatte die Pullups vergessen. Jetzt kann ich die Daten verwerten, vielen Dank für Deine Hilfe. Sag mal kann es sein, daß I²C über Basic echt langsam ist? Kann man das ganze nicht auch über Assembler realisieren?
Ich trau mich da nicht so richtig ran, da das EEprom ja ebenfalls über Assemblerroutinen angesprochen wird. vielleicht hast Du ja auch nen Tip für mich.

Gruß Jens

PS: Mein angepaßtes Programm...

' --- Definitionen --------------------

define SDA port[1]
define SCL port[2]
define N byte
define Daten byte

' --- Programmoperationen -------------

SDA = ON
SCL = ON


#Loop
gosub Start

gosub Start
Daten = 113 'PCF8574, Lesen
gosub I2C_Write
gosub I2C_Read
print Daten
gosub Ack
gosub Stop
if daten = 207 then beep 250,50,0
pause 1
goto Loop 'Endlosschleife

#Start
SDA = OFF
SCL = OFF
return

#Stop
SDA = OFF
SCL = ON
SDA = ON
return

#I2C_WRITE
for N = 1 to 8
SDA= OFF
if (Daten AND 128) = 128 then SDA = ON
pulse SCL
Daten = Daten shl 1 '1 Bit nach links
next
pulse SCL ' 9. Impuls
return

#I2C_Read
Daten = 0
deact SDA ' SDA = Eingang
for N = 1 to 8
Daten = Daten shl 1 '1 Bit nach links
SCL = ON
if SDA then Daten = Daten + 1
SCL = OFF
next
return

#Ack
SDA = 0
pulse SCL
return

#NoAck
SDA = 1
pulse SCL
return

end

Habe den Wert 207 genommen, da ich P6 und P7 des PCF auf 0 gesetzt habe

19.09.2004, 19:27
Hallo Jens

In Basic ist das Programm natürlich langsam.

Ich habe das auch in Assembler gelöst. Aber nicht über die Leitungen
des EEproms sondern über normale PORT's.

Hast du denn schon was in Assembler gemacht?

Dein vorlage Programm stammt ja aus dem Buch von Kainka,
dort ist auch die Assemblerroutine veröffentlicht.

Wenn du das Buch nicht besitzt oder noch nichts in Asssembler gemacht
hast helfe ich dir gerne weiter. Kann aber einige Tage dauern.

mfg
Harald

19.09.2004, 21:30
Hallo Harald,
grundsätzlich weiß ich in Etwa wie Assembler funktioniert, habe auch das Buch von Kainka hier, allerdings komm ich mit einer Sache nicht ganz zurecht: Und zwar benutzt Kainka in seinen Routinen in dem Listing I2C.Bas die Ports 9 und 10.

Ich möchte gerne die Ports 1 + 2 benutzen, jedoch bedeutet dies doch eigentlich, daß ich auch in dem dazugehörigen SYSCODE I2C.ASM die Ports ebenfalls ändern muß,oder? Warum sind die Ports überhaupt in dem Basic Listing definiert, ich dachte immer, das passiert über die Assembler Subroutinen....?

Außerdem hätte ich da noch eine Verständnisfrage zu dem Basic Listing von oben: Muß man immer erst I2CWrite aufrufen und den PCF beschreiben, bevor man von ihm lesen kann. Wenn ich diesen Aufruf nämlich weglasse tut sich bei meinem Hyperterminal nämlich nicht viel..



Ich weiß, Fragen über Fragen, aber ich wills halt immer irgendwie wissen.

Gruß Jens

19.09.2004, 22:43
hallo jens

Richtig. Wenn du von Port 9+10 auf Port 1+2 willst must du das im Basic
und Assemblerprogramm ändern. Mit den Basiczeilen
SDA = On
SCL = On
werden nicht nur die PORTs auf HIGH gesetzt sondern automatisch
auch als Ausgang definiert. Kann man auch in der Assemblerroutine
programieren, geht in Basic aber einfacher.

Der I2C-Bus ist wie der Name schon sagt ein Bussystem.
Wenn du mehrere Bausteine an SDA und SCL hast welcher soll sich melden? Jeder Baustein hat also seine eigene Adresse. Diese legst
du mit dem 1.Write-Befehl auf den Bus und nur der Baustein mit
dieser Adresse antwortet. Alle anderen sind ruhig. Die Adresse mußt
du halt auch senden wenn nur ein Baustein(PCF8574) vorhanden ist.

mfg
Harald

20.09.2004, 13:54
Ach so läuft das ganze mit der Bausteinadressierung. Werde das ganze mal in den nächsten Tagen per Assembler versuchen, laut Kainka soll das ganze dann ja um den Faktor 1000 schneller laufen, da bin ich mal gespannt.
Rätst Du mir denn von der Benutzung der internen I²C Bus Routinen des 68HC05B6 ab? Das wäre ja dann die lösung um die Ports für SDA und SCL einzusparen, allerdings steht in dem Buch von Kainka, das man da erst das EEprom abschalten muß oder so, daß hieße ja das die Geschwindigkeitsvorteile (gesetz dem Fall das man Daten im EEprom sammeln will) dadurch ja wieder zunichte gemacht werden, oder? Oder is das unter Assembler kein Problem?

Gruß Jens

20.09.2004, 14:01
ASM-COde findet man hier
https://www.roboternetz.de/phpBB2/dload.php?action=file&file_id=2

20.09.2004, 17:43
Hallo Jens

Die C -control öffnet das EEprom zum Lesen. Diese verbindung ist immer
aktiv. Du müßtest den zeiger der aktuellen Speicherstelle retten und
die Verbindung mit dem Stoppbefehl beenden. Dann deinen PCF8574
auslesen. Anschließend den EEprom wieder Adressieren und den
Speicherzeiger neu setzen. Ist Zeitlich kein Problem, kann
aber schnell zu Systemabstürzen führen.
Ich habe es so noch nicht verwendet.

Vieleicht hat ja schon jemand Erfahrungen gesammelt.

mfg
Harald