Expander: Digitaleingänge

Gast #1822145
Lesenswert?

Moin Leute,

ich habe einen ATmega324P20PU und führe damit mehrere Sachen durch, wo 
ich 10 Digitaleingänge benötige. Da ich jedoch nur 7 zur Verfügung habe, 
muss ich noch welche hinzufügen.

Nun habe ich den PCF8574AP in der Hand und versuche mich gerade in das 
Thema TWI und Expander einzulesen.

Momentan stellen sich mir 2 Fragen:

1. Für meine Anwendung (ich brauche ja noch 3-4 Digitaleingänge) ist 
diese Logik nicht ganz korrekt oder?

http://www.mikrocontroller.net/articles/Port-Expander_PCF8574

Die Pins 4-7 kann ich eh weglassen (?) und bei den Pins 0-3 muss ich 
nach dem ACK ein 0xFO als Schreibzugriff senden und dann die internen 
PullUps aktivieren. Habe ich dann einen digitalen Eingang?

2. Zum Thema TWI: 
http://www.mikrocontroller.net/articles/AVR_TWI#Aufbau_des_TWI

An welcher Stelle kommt denn da nun die Abfrage des Wertes, sprich wo 
kann ich da meine IF-Abfrage einbauen, die überprüft, ob an dem 
Digitaleingang ein Signal anlag.


Vielen Dank im Voraus!
#1822164
Lesenswert?

Wo ist das Problem? Du kannst jeden I/O des PCF8574 als Eingang 
definieren. Es wird einfach via I2C konfiguriert.

Du solltest dir eine fertige I2C-Master-Library zu Hilfe nehmen, um dir 
das Leben nicht unnötig schwer zu machen, z.B. von Peter Fleury: 
http://www.jump.to/fleury

Ob am Digitaleingang etwas anliegt, erfährst du über den Interrupt vom 
PCF8574.
Gast #1822198
Lesenswert?

Habe die Libary kopiert und mir angeschaut. Ist die Abfrage dann so 
richtig?
1
  i2c_init();                //initialisieren
2

3
  if (!(i2c_start()))        //was muss ich da übergeben?
4
    {
5
    i2c_write(0x01);
6

7
    i2c_rep_start();//was muss ich da übergeben?
8

9
    uchk = i2c_readNak(); //wertzuweisung
10

11
    i2c_stop();      //terminierung
12
  }
13
if (uchk)      //wenn uchk wahr, dann ...
14
[...]
#1822280
Lesenswert?

Lies dich erstmal in die I2C-Problematik ein. Bei der Library ist auch 
ein Beispiel dabei (für EEPROM glaube ich).

Merke folgendes:
- I2C ist ein Master-Slave Protokoll!
- Dein Atmega ist der Master!
- Die Deviceadresse ist eine 7-Bit Adresse (wird aber häufig als 8-Bit 
Wert angegeben, das letzte bit ist das read/write flag)
- Die oberen 4 Bit sind fest (0x70), die unteres sind frei wählbar 
(A[2:0]),
- Wenn du A[2:0] auf Masse legst is deine Deviceadresse 0x70 (+ 
R/W-Flag)
- Du mußt immer zuerst eine Start-Condition + Device-Adresse senden 
bevor du i2c_write oder ...read machen kannst

Also etwa so:
1
i2c_init();
2
i2c_start_wait(0x70+I2C_WRITE);   
3
i2c_write(irgendeinwert);
4
i2c_stop();

was genau gesetzt werden muß steht eindeutig im Datenblatt des 
PCF8475...
so nu aber los...
Gast #1822790
Lesenswert?

Ich habe alles soweit verstanden,mir ist klar welchen Device der 
Expander nun hat.Desweiteren habe ich A0-A2 auf GND gelegt und SDA, CLP, 
INT an meinen Prozessor angeschlossen(dazu parallel auf 5V gezogogen)

Allerdings: wie kann ich genau einen der 8 verschiedenen Ports am 
Expander auslesen?

Beim read Befehl gebe ich ja den Device an(sprich auf welches Element er 
zugreifen soll; in meinem Fall 0x70+I2C_READ. Doch wie sage ich ihm, 
dass er PIN0 auslesen soll?
Gast #1822856
Lesenswert?

i2c_init();                                // init I2C interface
    i2c_start_wait(0x70+I2C_READ);
    i2c_readNak();                       // wie lese ich z.B.PIN 4 am 
Expander??
    i2c_stop();


Der Expander hat 8 Ausgänge, von P0-P7. Diese befinden sich an den Pins 
4 - 7 und 9 - 12.

Ich verstehe noch nicht ganz, wie das machen soll T.T...sry

zumal ich dann ja noch eine IF-Abfrage machen möchte, sprich, wenn an 
dem Eingang Spannung anliegt, dann blabla
Gast #1823504
Lesenswert?

okay ich will euch nicht weiter verärgern mit meiner dummheit :/

Daher sagt mir einfach nur ob ich das richtig verstanden habe (Ja oder 
nein genügt). Ich lese den Expander aus. Wenn an Pin 0-4 eine Spannung 
anliegt und an den Pin 5-8 keine, dann werden die 8 bit 11111000 
übertragen/ausgelesen mit dem Readbefehl. Falls ich nun prüfen möchte, 
ob an einem Eingang etwas anliegt muss ich mit Bitmanipulation z.b. mit 
00001000 verunden. Falls das dann ungleich null ist, liegt an Pin 4 
Spannung an.
Gast #1823544
Lesenswert?

1
#define Dev_Address  0x70      // device address
2
//[...] P.Fleury auch included
3
int main(void)
4
{
5
  // Portsettings
6
  DDRA  = 0x00;  // PORT A as Input
7
  DDRB  = 0x00; // PORT B0 as Input
8
  DDRD  = 0xFF;  // PORT  D as Output
9
  PORTD  = 0x00; // LEDs PORT D red ON
10

11
uint8_t bla;
12

13
    DDRB &=~ (1<<PB0);                 /* PIN PB0 auf Eingang (Taster)            */
14
    PORTB = (0<<PB0);                 /* Pullup-Widerstand aktivieren            */
15

16
while(1)
17
{
18
      if (PINB & (1<<PB0))// Falls Taster an PIN PB0 gedrueckt...
19
      {
20
            i2c_init();         // init I2C interface
21
       
22
     if(!(i2c_start(Dev_Address+I2C_WRITE)))
23
     {
24
         i2c_write(0xF);    //PIN 0:3 = Eingang
25
                i2c_rep_start(Dev_Address+I2C_READ);        
26
                bla = i2c_readNak();                            
27
                i2c_stop();
28
            }       
29
       }
30
       if(bla & 0x08)                                 PORTD |=(1<<PD4);      //Horn an
31

32
}

also meine Abfrage funktioniert noch nicht. Aber soweit ist doch erstmal 
alles i.O. oder? Habe mit einem Multimeter nachgemgessen, an allen 
Eingängen liegen 5V an, an den Ausgängen jedoch auch.
Gast #1823693
Lesenswert?

hm ja hast recht, war ein Schreibfehler von mir.

Ich habe mal das Testprogramm von Peter Fleury laufen lassen.

Bei jedem Schritt habe ich eine LED eingefügt, die leuchten soll. 
Außerdem habe ich oben beim define die Adresse auf 0x70 geändert. 
Allerdings geht das nur solange, bis
1
ret = i2c_start(Dev24C02+I2C_WRITE);       // set device address and write mode

ausgeführt wird. Die LED die nach dem init gesetzt ist, leuchtet, die 
nach dem oben genannten Befehl nicht mehr. Woran könnte das liegen?
Angehängte Dateien:
Gast #1824658
Lesenswert?

Also, ich habe das ganze nochmal mit einem PCA9555D versucht und wieder 
ist es das gleiche. Er hängt bei der while Schleife in der 
Startfunktion.
1
//wait until transmission completed
2
while(!(TWCR &(1<<TWINT)));

Bitte helft mir ich bin voll am verzweifeln. Ich kopiere nur nochmal die 
main, die gesamte .c Datei kommt ini den Anhang.
1
int main(void){
2

3
  // Portsettings
4
  DDRA  = 0x00;  // PORT A as Input
5
  DDRB  = 0x00; // PORT B0 as Input
6
  DDRC  = 0x00;
7
  PORTC  = 0x00;
8
  DDRD  = 0xFF;  // PORT  D as Output
9
  PORTD  = 0x00; // LEDs PORT D red ON
10

11
uint8_t bla;
12

13
    DDRB &=~ (1<<PB0);                 /* PIN PB0 auf Eingang (Taster)            */
14
    PORTB = (0<<PB0);                 /* Pullup-Widerstand aktivieren            */
15

16
while(1)
17
{  
18

19
    if (PINB & (1<<PB0))
20
    {
21
  i2c_init();
22
 
23
  if(!(i2c_start(Dev_Address+I2C_WRITE)))
24
  {   
25
    PORTD |=(1<<PD4);     //LED an
26
      i2c_start_wait(Dev_Address+I2C_WRITE);
27
         
28
     i2c_write(0xF);
29

30
          i2c_rep_start(Dev_Address+I2C_READ);       // set device address and read mode
31
       
32
    bla = i2c_readNak();                    // read one byte
33
          i2c_stop();
34
         } 
35
}
36

37
return 0;
38
}

Die LED an PD4 geht nicht wenn ich sie hinter die Startfunktion setze.

Zur Hardware: Ich habe einen ATmega324P20PU und daran habe ich einmal 
einen PCA9555 und einen PCF8574A getestet. Bei beiden tritt das gleiche 
Problem auf. Ich habe SCL, INT und SDA per 10k Pullup Widerstand auf 5V 
gezogen.SDA und SCL sind am ATmega auf PC0 und PC1. INT habe ich mit 
INT0(PD2) verbunden. Es liegen ca 1,5V dauerhaft an SDA und SCL an. Der 
Rest ist eigentlich auch i.O. Ich nutze einen 16 Mhz Quarz, wobei ich es 
auch schon ohne versucht habe....ohne Erfolg.

Bitte helft mir. Ich bin echt mies drauf das das nicht klappt T.T

Grüße und danke schonmal!
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren