Forum: Mikrocontroller und Digitale Elektronik PCA9555/PCA9535 Hilfe


von Hugo P. (portisch)


Lesenswert?

Hallo!

Ich versuche gerade mit einem Atmega168 mit dem DIO PCA9535 zu reden.

Den Status der Inputs kann ich auslesen - die ändern sich auch braf wenn 
ein Input sich ändert.

Nun zu meinen Problemen:

1.
Auf PIN1 ist ja ein Interruptausgang um eine Änderung der Eingänge 
anzuzeigen. Ich hab einen Pullup auf 5V und ein Oszi dran. Das Signal 
bleibt aber immer auf 0V. Egal ob sich ein Input ändert oder nicht.
Ich möchte gerne den INT auf dem AVR INT0 hängen um die Ports nicht 
dauernd abfragen zu müssen.

2.
Ich kann die Polarity der Eingänge nicht ändern. Das Einlesen der Bits 
vom Port funktioniert aber - das habe ich mit einem Taster überprüft.

Ich habe diese Funktionen mal zum Testen erstellt:
1
uint8_t SetPolarity(uint8_t device_address, uint8_t port, uint8_t polarity)
2
{
3
  if (TWIM_Start(device_address, TWIM_WRITE))
4
  {
5
    // write command byte
6
    switch (port)
7
    {
8
      case PORT0 : TWIM_Write(0x04);
9
            break;  
10
      case PORT1 : TWIM_Write(0x05);
11
            break;              
12
    }
13
14
    // restart to set polarity of port
15
    if (TWIM_Start(device_address, TWIM_WRITE))
16
    {
17
      TWIM_Write(polarity);  
18
      TWIM_Stop();
19
    }    
20
  }else
21
  {
22
    TWIM_Stop();
23
  }  
24
}
25
26
uint8_t ReadPort(uint8_t device_address, uint8_t port)
27
{
28
  static uint8_t port_status;
29
  
30
  if (TWIM_Start(device_address, TWIM_WRITE))
31
  {
32
    // write command byte
33
    TWIM_Write(port);
34
35
    // restart to read inputs of port
36
    if (TWIM_Start(device_address, TWIM_READ))
37
    {
38
      port_status = TWIM_ReadNack();  
39
      TWIM_Stop();
40
    }    
41
  }else
42
  {
43
    TWIM_Stop();
44
  }
45
  
46
  return port_status;    
47
}
48
49
uint8_t SetPort(uint8_t device_address, uint8_t port, uint8_t status)
50
{
51
  if (TWIM_Start(device_address, TWIM_WRITE))
52
  {
53
    // write command byte
54
    switch (port)
55
    {
56
      case PORT0 : TWIM_Write(0x06);
57
            break;  
58
      case PORT1 : TWIM_Write(0x07);
59
            break;              
60
    }
61
62
    // restart to set port to input/output
63
    if (TWIM_Start(device_address, TWIM_WRITE))
64
    {
65
      TWIM_Write(status);  
66
      TWIM_Stop();
67
    }    
68
  }else
69
  {
70
    TWIM_Stop();
71
  }
72
73
  return 1;    
74
}

Einstellen und lesen würde ich dann so:
1
  SetPort(I2C_Slave_Address, PORT0, 0xFF);  
2
  SetPort(I2C_Slave_Address, PORT1, 0xFF);
3
  SetPolarity(I2C_Slave_Address, PORT0, 0xFF); 
4
  SetPolarity(I2C_Slave_Address, PORT1, 0xFF);
5
  ReadPort(I2C_Slave_Address, PORT0);
6
  ReadPort(I2C_Slave_Address, PORT1);

Also alles Inputs und alle invertiert. Alle Eingänge liegen auf 5V und 
ich bekomme immer 255 als Status vom Port. Eigentlich sollte es 
invertiert 0 sein.

Ich habe die TWI_Master von Manfred Langemann hier im Board verwendet.

Bin ein wenig ratlos wegen diesen 2 Dingen. Ich hoffe mir hier jemand 
vielleicht weiterhelfen kann!

von holger (Gast)


Lesenswert?

Lass mal das Restart beim schreiben der Registerwerte weg.

von Hugo P. (portisch)


Lesenswert?

holger schrieb:
> Lass mal das Restart beim schreiben der Registerwerte weg.

Danke! Das war es! Ich habe übersehen, dass der Restart nur beim Read 
benötigt wird. Nun kann man die Polarität ändern und der Interrupt 
reagiert auch!
1
uint8_t InitPort(uint8_t device_address, uint8_t port, uint8_t status)
2
{
3
  static uint8_t res;
4
  
5
  if (TWIM_Start(device_address, TWIM_WRITE))
6
  {
7
    // write command byte
8
    switch (port)
9
    {
10
      case PORT0 : TWIM_Write(0x06);
11
            break;  
12
      case PORT1 : TWIM_Write(0x07);
13
            break;              
14
    }
15
    res = TWIM_Write(status);  
16
  }
17
  TWIM_Stop();
18
  
19
  return res;    
20
}
21
22
uint8_t SetPolarity(uint8_t device_address, uint8_t port, uint8_t polarity)
23
{
24
  static uint8_t res;
25
  
26
  if (TWIM_Start(device_address, TWIM_WRITE))
27
  {
28
    // write command byte
29
    switch (port)
30
    {
31
      case PORT0 : TWIM_Write(0x04);
32
            break;  
33
      case PORT1 : TWIM_Write(0x05);
34
            break;              
35
    }
36
    res = TWIM_Write(polarity);  
37
  }
38
  TWIM_Stop();
39
  
40
  return res;  
41
}
42
43
uint8_t SetOutput(uint8_t device_address, uint8_t port, uint8_t out)
44
{
45
  static uint8_t res;
46
  
47
  if (TWIM_Start(device_address, TWIM_WRITE))
48
  {
49
    // write command byte
50
    switch (port)
51
    {
52
      case PORT0 : TWIM_Write(0x02);
53
            break;  
54
      case PORT1 : TWIM_Write(0x03);
55
            break;              
56
    }
57
    res = TWIM_Write(out);  
58
  }
59
  TWIM_Stop();
60
  
61
  return res;  
62
}
63
64
uint8_t ReadInput(uint8_t device_address, uint8_t port)
65
{
66
  static uint8_t port_status;
67
  
68
  if (TWIM_Start(device_address, TWIM_WRITE))
69
  {
70
    // write command byte
71
    TWIM_Write(port);
72
73
    // restart to read inputs of port
74
    if (TWIM_Start(device_address, TWIM_READ))
75
    {
76
      port_status = TWIM_ReadNack();
77
    }    
78
  }
79
  TWIM_Stop();
80
  
81
  return port_status;    
82
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.