Forum: Mikrocontroller und Digitale Elektronik mcp23008 funktioniert nicht


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von pete (Gast)


Lesenswert?

Hallo Forum,


ich hab ein Problem mit dem MCP23008.

Ich würde gerne LEDs zum Leuchten bringen, was jedoch nicht klappt.


Hier ist der Code:
1
 TWI_M_init(F_CPU, 100, TWIE_DISABLE);
2
3
 TWI_M_start(MCP_ADDRESS, WRITE, MCP23008_OPTION); // MCP23008_OPTION 0x40
4
                
5
          
6
                
7
 TWI_M_write(0x00); // IODIR register
8
                
9
          
10
                
11
 TWI_M_write(0x00); // all output
12
        
13
                          
14
 TWI_M_stop();
15
  
16
              
17
 TWI_M_start(MCP_ADDRESS, WRITE, MCP23008_OPTION);
18
                
19
                  
20
 TWI_M_write(0x09); // GPIO register
21
                
22
            
23
 TWI_M_write(0xFF);
24
                        
25
                
26
 TWI_M_stop();


Das ist der Code für start, write und stop, die Funktionen 
funktionieren. Ich erhalte auch ein Ack nach write und start. Aber es 
regt sich nichts.

Ich verwende 0x40 für den mcp, da ich in TWI_M_start es mit OR 
manipuliere.

Hier sind nochmals die verwendeten Funktionen.
1
//////////////////////////////////////////  TWI_M_start  //////////////////////////////////////////
2
  
3
  /*
4
   starting TWI with slave's address and choosing mode between MT and MR
5
6
   read_or_write=1: MR      read_or_write=0: MT    option is for first sending (initialization)
7
   
8
   returns TWI_M_START_FAILED_1, TWI_M_START_FAILED_2 or START_SUCCEED
9
  */
10
  int8_t TWI_M_start(uint8_t address, uint8_t read_or_write, uint8_t option)
11
  {
12
    
13
    TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // enable interrupt flag, send start, enable TWI
14
    
15
      while( ! ( TWCR & (1 << TWINT) ) ); // wait for operation 
16
      
17
        if( ( (TW_STATUS) != M_START ) && ( (TW_STATUS) != M_REPEADED_START ) ) // checking error
18
        {
19
          
20
          TWI_M_stop();
21
          return TWI_M_START_FAILED_1;  // return error
22
          
23
        }
24
    
25
    TWDR =  ( (address << 1) + read_or_write) | option; // choosing slave showing if MR or MT mode starts
26
    //TWDR = (address) + read_or_write; // choosing slave showing if MR or MT mode starts
27
    TWCR = (1 << TWINT) | (1 << TWEN); // TWINT bit has to be set for transmission  
28
    
29
      while( ! ( TWCR & (1 << TWINT) ) ); // wait for operation 
30
      
31
        //if( ( (TW_STATUS & 0b11111000) != MT_SLA_W_TRANS_ACK_REC ) && ( (TW_STATUS & 0b11111000) != MR_SLA_R_TRANS_ACK_REC ) ) // checking error // TWSR // 0x18 // 0x40
32
        if( ( (TW_STATUS) != MT_SLA_W_TRANS_ACK_REC ) && ( (TW_STATUS) != MR_SLA_R_TRANS_ACK_REC ) )
33
        {
34
        
35
          TWI_M_stop();
36
          return TWI_M_START_FAILED_2;
37
        
38
        }
39
40
    return START_SUCCEED;
41
  
42
  }
43
44
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
45
46
47
//////////////////////////////////////////  TWI_M_write  //////////////////////////////////////////
48
  
49
  /*
50
   writes in TWI data register
51
   
52
   returns MT_DATA_TRAMS_FAILED or MT_DATA_TRANS_SUCCEED
53
  */
54
  int8_t TWI_M_write(uint8_t data)
55
  {
56
        
57
    TWDR = data; // send data
58
    
59
    TWCR = (1 << TWINT) | (1 << TWEN); // TWINT bit has to be set for transmission
60
    
61
      while( ! ( TWCR & (1 << TWINT) ) ); // wait for operation
62
    
63
        if( ( (TW_STATUS) != MT_DATA_TRANS_ACK_RETURN ) && ( (TW_STATUS) != MT_DATA_TRANS_NACK_RETURN ) ) // checking error
64
        {
65
          
66
          TWI_M_stop();      
67
          return MT_DATA_TRANS_FAILED;    
68
              
69
        }
70
71
    return MT_DATA_TRANS_SUCCEED;
72
  
73
  }
74
75
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
76
77
78
79
80
81
//////////////////////////////////////////  TWI_M_stop  //////////////////////////////////////////
82
  
83
  /*
84
   stops TWI
85
   
86
   no return
87
  */
88
  void TWI_M_stop()
89
  {
90
    
91
    TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
92
  
93
  }
94
95
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

von pete (Gast)


Lesenswert?

weiß keiner rat?

von Harald (Gast)


Lesenswert?

Scope oder Logic Analyzer vorhanden?

von pete (Gast)


Lesenswert?

ja, gucke es mir dann auf dem oszi an

von pete (Gast)


Lesenswert?

Ich hab den Beispielcode von der Seite
https://github.com/adafruit/Adafruit-MCP23008-library
 auf dem Arduino aufgespielt und es hat funktioniert. Jedoch mit dem 
Atmega32 nicht...

Und ich kriege die ACK's, aber es leuchtet nicht am Port vom MCP.

von Harald (Gast)


Lesenswert?

Könntest Du keine Vergleichsmessung machen? Einmal mit dem Arduino, 
Screenshot machen und das mit dem akt. Ergebnis vergleichen? Ist 
schwierig aus der Ferne, ansonsten müsste man wirklich mal step-by-step 
die Bits auswerten und prüfen...
Es wird auch nicht so ganz klar aus deinem Beitrag, ob die Hardware 
identisch ist.

von pete (Gast)


Lesenswert?

danke für den vorschlag, das werde ich mal machen

von pete (Gast)


Lesenswert?

Hab das Problem gefunden.

Man muss zuerst das Register senden, dann lesen, dann start repeat, 
register schreiben und erst dann den gewünschten Wert senden.

von pete (Gast)


Lesenswert?

Hi, ich hab heute es noch hingekriegt.

Ist es wirklich nötig ein delay von ungefähr 50 µs dazwischen zu haben?

Ohne dem hat es bei mir nicht funktioniert.

Hab 16Mhz beim atmega32

von Harald (Gast)


Lesenswert?

Ein Delay von 50us sollte evtl. auf andere Probleme hindeuten, z.B. 
verschliffene Flanken durch falsche Pull-Ups oder andere Probleme. Lässt 
sich ebenfalls aus der Ferne schlecht beurteilen.

von Harald (Gast)


Lesenswert?

P.S. Vielleicht auch I2C zu schnell eingestellt? Siehe Datenblatt.

von pete (Gast)


Lesenswert?

ist 100 khz und auf dem oszilloskop sieht alles gut aus

von pete (Gast)


Lesenswert?

die widerstände sind 6,8 kR

von pete (Gast)


Lesenswert?

und das minimalste delay, mit dem es funktioniert, ist 20 µs

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.