Erledigt Proplem mit PCF8574 Port in Bascom Ansteuern

Thorsten_Sch

Mitglied
31. Okt. 2010
152
0
16
47
HH
Sprachen
  1. BascomAVR
Hallo Forum gemeinde und bastler

Ich benutze als I2C(Master) einen ATmega8 und möchte gern 8 Realis über einen PCF8574 Ansteuern ich habe mal einen Code sehe unten reingestellt

Code:
$regfile "m8def.dat"
$crystal = 10000000
$hwstack = 32
$swstack = 10
$framesize = 40

Const Pcf8574_r = &H7E                                      'I2C Adresse &H7E
Config I2cdelay = 15                                        'delay von 5=20µs=50kHz,10=10µs=100kHz;5=5µs=200KHz
Config Scl = Portc.5                                        'I2C SCL Pin
Config Sda = Portc.4                                        'I2C SDA Pin

Config Portb.2 = Output

Dim Realis_1 As Byte
Dim Realis_2 As Byte
Dim Realis_3 As Byte
Dim Realis_4 As Byte
Dim Realis_1a As Byte
Dim Realis_2a As Byte
Dim Realis_3a As Byte
Dim Realis_4a As Byte
Dim Alles_aus As Byte
Realis_1 = &B00000001                                       'AUS
Realis_2 = &B00000010                                       'AN
Realis_3 = &B00000100
Realis_4 = &B00001000
Realis_1a = &B00000000                                      'AUS
Realis_2a = &B00000000                                      'AN
Realis_3a = &B00000000
Alles_aus = &B11111111

Do
I2csend &H7E , Realis_1
Wait 1
I2csend &H7E , Realis_2
Wait 1
I2csend &H7E , Realis_3
Wait 1
I2csend &H7E , Led_1
Wait 1
I2csend &H7E , Realis_3
Wait 1
I2csend &H7E , Realis_2
Wait 1
I2csend &H7E , Realis_1
Wait 1
I2csend &H7E , Realis_4
Wait 1
I2csend &H7E , Alles_aus
Wait 1
Loop
Return

so nu zu meine frage wie kann man die ports von PCF8574 Noch ansprechen in Bascom ausher (
Code:
I2csend &H7E , Realis_1
)
oder geht das auch irgendwie Ander ich bitte um rat.......

Ach Ja und wie geht das mit einen PCF8574 Als Taster benutzen Möchte bitte auch hierfür rat

Mit Freundtlichen Grüßen
Thorsten Sch.
 
Hi Thorsten,

stell dir deinen PCF8574 wie ein externes Register in der Größe von einem Byte vor. Du kannst dort nur das gesamte Byte auf einmal beschreiben oder auch nur das gesamte Byte auf einmal lesen. Du kannst kein einzelnes Bit verändern ohne die restlichen Bits dabei anzufassen.

Über den Sendebefehl auf die I2C-Adresse schreibst du das gesamte Byte in diesen Baustein und damit auf seine 8 Anschlußpins und mit einem Lesebefehl für den I2C-Bus liest du alle 8 Anschlußpins des Bausteins auf einmal aus.

So wie du es in deinem Programm machst, schaltest du einen Pin ein und damit alle anderen aus. Du kannst also mit deiner Version nicht mehrere Relais unabhängig voneinander an- oder abschalten.

Mach es so das du eine Bytevariable nimmst die die 8 Ausgangspins des PCF8574 darstellen soll. In dieser Bytevariable "schaltest" kannst du dann die "Pins" (Bits) mit SET und RESET einzeln ein und ausschalten. Um es dann auch wirklich passieren zu lassen schreibst du diese Bytevariable mit I2CSEND zum PCF8574.

Gruß
Dino
 
I2c PCF8574 geht das so

Hallo Cassio und forum Bastler

so ich habe mich mal hingesetzt und soweit geht es hiermal der code
Code:
$regfile = "m8def.dat"
$crystal = 8000000

Config Sda = Portc.4
Config Scl = Portc.5

Const Pcf8574_schreib_adresse = &H7E                        '&H40 = 64 IC2 Adresse des PCF8574
I2cinit

Dim Pcf8574_aus0 As Byte
Dim Pcf8574_ausgabe1 As Byte
Dim Pcf8574_ausgabe2 As Byte
Dim Pcf8574_ausgabe3 As Byte
Dim Pcf8574_ausgabe4 As Byte
Dim Pcf8574_ausgabe24 As Byte

Pcf8574_aus0 = &B00000000
Pcf8574_ausgabe1 = &B00001000
Pcf8574_ausgabe2 = &B00000100
Pcf8574_ausgabe24 = &B00001010
Pcf8574_ausgabe3 = &B00000010
Pcf8574_ausgabe4 = &B00000001

Do
'----PCF8574 schreiben:-----
  I2cstart
  I2cwbyte Pcf8574_schreib_adresse                          'IC2 Adresse des PCF8574
  I2cwbyte Pcf8574_ausgabe1                                 'LEDs nach Muster an
  Wait 2
  I2cstart
  I2cwbyte Pcf8574_schreib_adresse                          'IC2 Adresse des PCF8574
  I2cwbyte Pcf8574_aus0                                     'LEDs nach Muster an
  Wait 2
  I2cwbyte Pcf8574_schreib_adresse                          'IC2 Adresse des PCF8574
  I2cwbyte Pcf8574_ausgabe4                                 'LEDs nach Muster an
  Wait 2
  I2cwbyte Pcf8574_schreib_adresse                          'IC2 Adresse des PCF8574
  I2cwbyte Pcf8574_aus0
  Wait 2
  I2cwbyte Pcf8574_schreib_adresse                          'IC2 Adresse des PCF8574
  I2cwbyte Pcf8574_ausgabe2
  I2cwbyte Pcf8574_ausgabe24
  Wait 2                                                    'LEDs nach Muster an
  I2cwbyte Pcf8574_schreib_adresse                          'IC2 Adresse des PCF8574
  I2cwbyte Pcf8574_ausgabe3                                 'LEDs nach Muster an
  Wait 2
  I2cwbyte Pcf8574_schreib_adresse                          'IC2 Adresse des PCF8574
  I2cwbyte Pcf8574_aus0                                     'LEDs nach Muster an
  Wait 2
  I2cwbyte Pcf8574_schreib_adresse                          'IC2 Adresse des PCF8574
  I2cwbyte Pcf8574_ausgabe1                                 'LEDs nach Muster an
  Wait 2
  I2cwbyte Pcf8574_schreib_adresse                          'IC2 Adresse des PCF8574
  I2cwbyte Pcf8574_aus0
  Wait 2
  I2cwbyte Pcf8574_schreib_adresse                          'IC2 Adresse des PCF8574
  I2cwbyte Pcf8574_ausgabe4                                 'LEDs nach Muster an
  I2cstop
  Waitms 60
  Loop
End

so und wie mache ich das das ich mit den PCF8574 taster schalten kann?????

Hierfür bitte um rat habe mal ein beispiel aus meinen buch gefunden sehe unten
BEISPIEL CODE TASTER
Code:
'PCF8674 Portexpander mit IC2 (C4 und C5)
'Ausgabe (Blinken) und Eingabe (Taster)
'
'IN /OUT: IC2 (C4 und C5) Jeweils 4,7k-Widerstände nach Plus
'
'IN  am PCF8574: P0 taster gegen GND
'OUT am PCF8574: P1 bis P7 LEDs ( +5 -- Rv - >I -- PCF8574
'
$regfile = "m8def.dat"
$crystal = 1000000

Config Sda = Portc.4
Config Scl = Portc.5

Const Pcf8574_schreib_adresse = &H7E                        '=&H40 = 64 IC2 Adresse des PCF8574
Const Pcf8574_lese_adresse1 = &H7F                          '=&H41 = 65 IC2 Adresse des PCF8574

I2cinit

Dim Pcf8574_ausgabe As Byte
Dim Pcf8574_eingabe As Byte


Do
'----PCF8574 schreiben:-----
  I2cstart
  I2cwbyte Pcf8574_schreib_adresse                          'IC2 Adresse des PCF8574
  I2cwbyte &B00001100                                       'ausgabe P6 u. P7 auf 0
  I2cstop                                                   '-> LEDs leuchten
  Wait 5
'----PCF8574 schreiben:-----
  I2cstart
  I2cwbyte Pcf8574_schreib_adresse                          'IC2 Adresse des PCF8574
  I2cwbyte &B11111111                                       'Alle Pins auf 1
  I2cstop                                                   '-> LEDs aus
  Wait 5
'----PCF8574 Lesen:-----
I2cstart
I2cwbyte Pcf8574_schreib_adresse                            'IC2 Adresse des PCF8574
I2cwbyte &B11111111                                         'Alle Pins auf 1
I2cstop

I2cstart
I2cwbyte Pcf8574_lese_adresse1
I2crbyte Pcf8574_eingabe , Nack                             'Port Lesen
I2cstop

If Pcf8574_eingabe.0 = 0 Then
'----PCF8574 schreiben:-----
  I2cstart
  I2cwbyte Pcf8574_schreib_adresse                          'IC2 Adresse des PCF8574
  I2cwbyte &B00000001                                       'Alle LEDs Leuchten
  I2cstop
    Wait 5
End If

Loop
End

Mit Freundtlichen Grüßen
Thorsten Sch.
 
I2c PCF8574 geht das auch mit als taster schalten?????

Hallo ich nochmal

Habe vergessen zu fragen ob es auch mit den PCF8574 als taster der schaltet???? hoffe ihr wist was ich damit meine

Gruß
Thorsten Sch.:D
 
Hi Thorsten,

also mal was zum PCF8574 ...

Ich beschreibe nun mal den ganzen internen Aufbau. Bitte lies es dir GENAU durch. Notfalls mehrere male. Überfliege es nicht sondern lese es langsam und sorgfältig.


Zuerst mal das interne Blockschaltbild.
PCF8574_Block.png
Wie man sieht werden immer 8 Bit (alle IO-Pins) auf einmal bearbeitet. Also entweder alle auf einmal gelesen oder geschrieben. Der rechte Block I/O-Port ist im nachfolgenden Bild noch einmal genauer zu sehen ...



EIN Pin vom I/O-Port. Also nur einer der 8 Anschlüsse weil es sonst unübersichtlich wird.
PCF8574_IO-Pin.png
Links kommen die ganzen Steuer- und Datenleitungen der internen Steuerlogik vom Chip. Rechts geht es bei "P0 to P7" zum I/O-Pin (also zum IC-Beinchen).
Nach Low (0, GND oder VSS) kann er direkt über den Transistor schalten. Dort verträgt der Pin laut Datenblatt maximal 25mA.
Wenn man nach High (1, +5V oder VDD) schaltet, dann ist dort am oberen Transistor eine Konstantstromquelle mit eingebaut. Nach High liefert der Pin also nur 100µA (Mikroampere) an den Ausgang. Diese Konstantstromquelle kann man auch als PullUp-Widerstand zweckentfremden.

Wenn man also etwas an den I/O-Pin anschließen will, dann sollte man das folgendermaßen machen ...
  • Eingänge von anderen ICs benötigen normalerweise wenig Strom und können direkt angeschlossen werden.
  • Eine LED legt man mit einem Vorwiderstand zwischen +5V und dem IC-Beinchen. Wenn man auf Low (0, GND) schaltet, dann leuchtet sie.
  • Wenn man mehr Strom benötigt, dann wird an dem IC-Beinchen ein Transistor (MIT Basisvorwiderstand) angeschlossen, der dann die Last schalten kann.
  • Wenn man einen Taster anschließen möchte, dann legt man den vom IC-Beinchen nach GND. Damit kann man dann die interne Konstantstromquelle als PullUp-Widerstand verwenden indem man bei einem Schreibzugriff eine 1 an diese Stelle setzt. Das MUSS man auch so tun. Wenn man den Taster drückt, dann liest man bei einem Lesezugriff auf das IC an der Stelle des Bytes eine 0 ein da der Taster ja den Pin auf GND zieht. Durch die Konstantstromquelle im IC kann nichts kaputt gehen.

WICHTIG! Wenn man von außen an das IC-Beinchen +5V anlegt (zB mit einem Taster nach Vcc/+5V) und dann eine Null (Low) an die entsprechende Stelle für den IO-Pin schreibt, dann hat man einen KURZSCHLUSS von Vcc, über den Taster, dann in das IC-Beinchen und den internen Transistor nach GND. Eine sichere Methode um ICs zu schrotten! :p Man sollte also bei einem Schreibzugriff bei allen Bits die als Eingang verwendet werden eine EINS reinschreiben! Das kann man auch im Datenblatt lesen ...
7.3 Quasi-bidirectional I/Os
A quasi-bidirectional I/O can be used as an input or output without the use of a control signal for data direction (see Fig.15). At power-on the I/Os are HIGH. In this mode only a current source to VDDis active. An additional strong pull-up to VDDallows fast rising edges into heavily loaded outputs. These devices turn on when an output is written HIGH, and are switched off by the negative edge of SCL. The I/Os should be HIGH before being used as inputs. A quasi-bidirectional I/O can be used as an input or output without the use of a control signal for data direction (see Fig.15). At power-on the I/Os are HIGH. In this mode only a current source to VDDis active. An additional strong pull-up to VDDallows fast rising edges into heavily loaded outputs. These devices turn on when an output is written HIGH, and are switched off by the negative edge of SCL. The I/Os should be HIGH before being used as inputs.



Hier nun ein Schreibzugriff (also eine Ausgabe)
PCF8574_Write.png
Das hast du ja soweit auch schon umgesetzt ...
Code:
I2cstart                         ' Startsignal auf dem I2C-Bus senden. Anfang vom Transfer

I2cwbyte PCF8574_Schreibadresse  ' Mit der Schreibadresse dem IC sagen das
                                 ' das nächste Byte ausgegeben werden soll

I2cwbyte Daten_Byte              ' Nun das Byte senden was ausgegeben werden soll

I2cwbyte Daten_Byte              ' und noch ein Byte in das Ausgaberegister senden

I2cstop                          ' Stopsignal auf dem I2C-Bus senden. Transfer ist zu Ende
Du sagst dem PCF8574 also mit der Schreibadresse das er das nachfolgende Byte (Daten_Byte) in das Ausgaberegister schreiben soll.

Wenn du keine Stop-Bedingung sendest, dann schreibt der PCF8574 weiter jedes empfangene Byte vom I2C-Bus in sein Ausgaberegister und damit auf seine IC-Beinchen/IO-Pins. Erst durch die Stop-Bedingung weiß der PCF8574 das es nun zu Ende ist und er "wieder Ruhe" hat.



Und nun der Lesegrugriff (also eine Eingabe/Abfrage der IO-Pins)
PCF8574_Read.png
Das ist auch so ähnlich wie der Schreibzugriff. Nur das sich nach dem Senden der Adresse quasi "Master und Slave umdrehen". Der Atmel wird also beim Daten lesen nach dem Senden der Adresse quasi zum "Slave" (Nennt sich genau gesagt Masterreceiver). Das geht nun also folgendermaßen ...
Code:
I2cstart                         ' Startsignal auf dem I2C-Bus senden. Anfang vom Transfer

I2cwbyte PCF8574_Leseadresse     ' Mit der Leseadresse dem IC sagen das
                                 ' das er nun mit Daten senden dran ist

I2crbyte Daten_Byte , Ack        ' Ein Byte aus dem Eingaberegister (von den IO-Pins) lesen

I2crbyte Daten_Byte , Nack       ' Und nochmal die IO-Pins abfragen und mit NACK alles beenden

I2cstop                          ' Stopsignal auf dem I2C-Bus senden. Transfer ist zu Ende
Man sagt dem PCF8574 nun also mit der Leseadresse das er dran ist mit Daten senden. Der Atmel liest nun vom I2C-Bus das vom PCF8574 gesendete Byte ein. Das Byte zeigt Eins-zu-Eins den Zustand der IO-Pins vom PCF8574. Hier hab ich beim ersten Lesen ein ACK gesetzt (Acknowledge). Damit sagt der Atmel dem PCF8574 ... alles OK ich will weiterlesen. Dann lese ich ein zweites Mal die IO-Pins ein (einfach mal aus Spaß). Nun sage ich aber NACK (Negative Acknowledge). Das sagt dem PCF8574 ... der Atmel hat genug und ich kann aufhören. Der PCF8574 legt sich also nach diesem NACK dann zur Ruhe. Das folgende I2CSTOP gibt den I2C-Bus dann wieder frei.



Die 4 Grafiken sind eigentlich die wichtigsten aus dem gesamten Datenblatt. Ich habe, soweit wie in der Kürze möglich, alles nochmal genau erklärt. Normalerweise sollten keine Fragen mehr zum PCF8574 offen sein.

Als Beispiel noch ein kleiner Programmschnipsel ...
Code:
DIM PCF8574_Lesedaten AS BYTE
DIM PCF8574_Sendedaten AS BYTE
PCF8574_Sendedaten = &B1101_0111   ' Alle Pins auf High die Eingaenge sein sollen
' P0-P2 ist Eingang (Taster)
' P3    ist Ausgang (Relais ueber Transistor)
' P4    ist Eingang (Taster)
' P5    ist Ausgang (LED nach Vcc)
' P6-P7 ist Eingang (Taster)


RESET PCF8574_Sendedaten.5         ' Pin5 des PCF8574 auf 0 (GND) setzen (zB LED5 anschalten)
RESET PCF8574_Sendedaten.3         ' Pin3 des PCF8574 auf 1 (Vcc) setzen (zB Relais1 anschalten)
I2cstart                           ' Startsignal auf dem I2C-Bus senden. Anfang vom Transfer
I2cwbyte PCF8574_Schreibadresse    ' Mit der Schreibadresse dem IC sagen das
                                   ' das nächste Byte ausgegeben werden soll
I2cwbyte PCF8574_Sendedaten        ' Nun das Byte senden was ausgegeben werden soll
I2cstop                            ' Stopsignal auf dem I2C-Bus senden. Transfer ist zu Ende


I2cstart                           ' Startsignal auf dem I2C-Bus senden. Anfang vom Transfer
I2cwbyte PCF8574_Leseadresse       ' Mit der Leseadresse dem IC sagen das
                                   ' das er nun mit Daten senden dran ist
I2crbyte PCF8574_Lesedaten , Nack  ' Ein Byte aus dem Eingaberegister (von den IO-Pins) lesen
I2cstop                            ' Stopsignal auf dem I2C-Bus senden. Transfer ist zu Ende
' In der Variable PCF8574_Lesedaten findet man nun in den entsprechenden 
' Bits die Zustände der IO-Pins vom PCF8574

Gruß
Dino
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)