-         

Ergebnis 1 bis 9 von 9

Thema: MCP23017 - I2C ansprechen ohne Erfolg

  1. #1
    RN-Premium User Fleißiges Mitglied
    Registriert seit
    19.05.2012
    Ort
    Sigmaringen
    Beiträge
    169

    MCP23017 - I2C ansprechen ohne Erfolg

    Anzeige

    Tja... ich versuche den MPC23017 per I2C an einem ATmega328 zu betreiben.
    Leider komm ich nun seit 2 Tagen nichtmehr vorwärts.
    Schaltungstechnisch scheint soweit alles ok.
    Verwenden möchte ich das Hardware-TWI/I2C an C4/C5.
    Die 3 Adresspinns vom MCP liegen an Masse und SCL/SDA sind jeweils mit 1k-Pullup auf VCC gelegt.
    Den Resetpin hab ich vorbeugend mit einem kleinen 104 kondensator belegt, damit er bei jedem Start für einmaligen Reset sorgt.
    5V und GND kommen auch am MCP an.
    Das SCL-Signal scheint korrekt am Pin 12 des MCP anzukommen.

    Allerdings rührt sich auf SDA garnichts... der scheint dauerhaft auf Low zu bleiben

    Kann also nurnoch an einem Falschen Testprogramm liegen ??

    Könnte da bitte mal jemand drüber schauen ob das soweit funktionieren sollte ?
    Falls nicht muss ich mich wohl um einen Neuen Portexpander bemühen.

    Code:
    $regfile = "M328pdef.dat"
    $crystal = 16000000
    $baud = 38400
    
    Const Mcp_write = &B01000000
    Const Mcp_read = &B01000001
    $lib "i2c_twi.lbx"                                          'Hardware I2C/TWI auf Pins C4/C5
    Config Scl = Portc.5
    Config Sda = Portc.4
    Config Twi = 400000
    I2cinit
    
    '''''''''''''''''
    'Initialisierung
    '''''''''''''''''
       I2cstart
       I2cwbyte Mcp_write                                       ' IODIRA
       I2cwbyte &H00                                            'Als Ausgänge definieren
       I2cwbyte &B00000000
       I2cstop
    
       Waitus 25
    
       I2cstart
       I2cwbyte Mcp_write                                       ' IODIRB
       I2cwbyte &H10                                            'Als Ausgänge definieren
       I2cwbyte &B00000000
       I2cstop
    
       Waitus 25
    
    '''''''''''''''''''
    'Ausgänge schalten
    '''''''''''''''''''
    Do
    
       I2cstart
       I2cwbyte Mcp_write
       I2cwbyte &H1A                                            ' alle B-Ausgänge  auf 0
       I2cwbyte &B00000000
       I2cstop
    
    
       Waitus 25
    
       I2cstart
       I2cwbyte Mcp_write
       I2cwbyte &H1A
       I2cwbyte &B11111111                                      'Alle B-Ausgänge auf 1
       I2cstop
    
    
       Waitus 25
    
    Loop
    
    End
    EDIT: einige kleine Änderungen... zumindest sind die Datenpakete auf SDA nun vorhanden...
    der MCP scheint allerdings nicht reagieren zu wollen.

    Evtl. ist die Adresse oder das Ansprechen der Register falsch ??
    Das Datenblatt verwirrt mich eh unheimlich.

    Falls jemand Tips hätte wäre ich sehr dankbar!
    Geändert von JoeM1978 (21.12.2013 um 16:27 Uhr)
    JAAAA... Microchips kann man essen... aber der Geschmack ist furchtbar.

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    31.05.2009
    Beiträge
    251
    Schau mal hier:

    http://www.mcselec.com/index.php?opt...=107&Itemid=57

    ...das hat mir auch geholfen !
    mfG
    Willi

  3. #3
    RN-Premium User Fleißiges Mitglied
    Registriert seit
    19.05.2012
    Ort
    Sigmaringen
    Beiträge
    169
    Danke...
    bin momentan nicht zu hause.
    Werde es mir aber im neuen Jahr genauer ansehen.
    Das scheint tatsächlch ein "Tutorial" zu sein, wie ich es gesucht habe.

    MfG,... JoeM
    JAAAA... Microchips kann man essen... aber der Geschmack ist furchtbar.

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    28.10.2004
    Ort
    Baoding
    Alter
    37
    Beiträge
    687
    Versuch erst mal ne Adresse zu finden mit dem Software I2C, da kann man zumindest erst mal schauen ob ein Teilnehmer am Bus ist.



    Code:
    $regfile = "M32DEF.DAT"
    $crystal = 16000000
    $baud = 9600
    
    Config Sda = Portc.1
    Config Scl = Portc.0
    Config I2cdelay = 10
    
    Dim Busaddress As Byte
    Dim Busaddress_read As Byte
    Dim Chipaddress As Byte
    Dim Erkannt As Bit
    
    :
    'Scan bus for valid I2C addresses on bus
    ' ( test for ACK to come back from Busaddress )
    Print "Scan start"
    For Busaddress = 0 To 255
    'for all even addresses
      I2cstart
      I2cwbyte Busaddress
        If Err = 0 Then
        Erkannt = 1
          Print "Slave at address: " ; Busaddress ; " Dezimal, = " ; Hex(busaddress) ; " hex"
          'Chipaddress = Busaddress \ 2
          'Print " with chip address " ; Hex(chipaddress) ; "hex"
        End If
      I2cstop
    'free bus
    Next
    Print "End Scan"
    If Erkannt = 0 Then Print "Keine I2C Teilnehmer gefunden!!"
    Do
    Loop
    Müsste natürlich noch ein bischen angepast werden von dir
    Signatur??? kann ich mir nicht leisten!!!

  5. #5
    RN-Premium User Fleißiges Mitglied
    Registriert seit
    19.05.2012
    Ort
    Sigmaringen
    Beiträge
    169
    So... neues Jahr, neues Glück. (Hoffe ich)

    Ich habe mir nun ein Testprogramm aus den Vorschlägen erstellt, das zumindest bestätigt, das der MCP am Bus verfügbar ist.

    Hex40 und Hex41 passt als Adresse und anscheinend wird alles soweit korrekt gesendet.
    Leider bleiben GPA und auch GPB trotzdem stumm.
    Theoretisch sollten aber jeweils alle Ausgänge auf 1 sein und nur ein Ausgang jeweils auf 0. (ähnlich Lauflicht)



    Code:
    $regfile = "M328pdef.dat"                                   
    $crystal = 16000000                                        
    $baud = 38400                                              
    
    '**********************************************************************
    '**  I2C pins **
    '**********************************************************************
    Config Sda = Portc.4                                        ' I2C Data.
    Config Scl = Portc.5                                        ' I2C Clock.
    Config I2cdelay = 10
    
    '**********************************************************************
    '** Declare subroutines **
    '**********************************************************************
    
    Declare Sub I2c_mcp23016_write(byval Cmd As Byte , Byval Lsb As Byte , Byval Msb As Byte)
    
    Declare Sub I2c_mcp23016_read
    
    '**********************************************************************
    '** Define working variables and constants  **
    '**********************************************************************
    Dim Busaddress As Byte
    Dim Busaddress_read As Byte
    Dim Chipaddress As Byte
    Dim Erkannt As Bit
    
    Dim Mcp23016_adress_w As Byte
    Mcp23016_adress_w = &H40 'Write Adress: 0 1 0 0 _0 0 0_ 0
    
    Dim Mcp23016_adress_r As Byte
    Mcp23016_adress_r = &H41 'Read Adress: 0 1 0 0 _0 0 0_ 1
    
    Dim Counter_1 As Byte
    Dim Lsb As Byte
    Dim Msb As Byte
    
    'This is for the Microchip MCP23016 initialization, some examples below
    
    'Call I2c_mcp23016_write(&H04 , &Hff , &Hff) 'Invert All Input Polarities
    'Call I2c_mcp23016_write(&H0a , &H01 , &H01) 'Initialize Iares , For Fast Input Scan Mode
    'Call I2c_mcp23016_write(&H06 , &H00 , &HFF) 'Initiallize It So The Lsbs Outputs Are & Msbs Are Inputs
    'Call I2c_mcp23016_write(&H06 , &Hff , &Hff) 'Initiallize It So That Both Lsbs & Msbs Are Inputs
    'Call I2c_mcp23016_write(&H02 , &HFF , &HFF) 'Initiallize The Ouput Latch
    'Call I2c_mcp23016_write(&H06 , &H00 , &H00) 'Initiallize It So That Both Lsbs & Msbs Are Outputs
    
    '**********************************************************************
    '** Main-Programm  **
    '**********************************************************************
    'Scan bus for valid I2C addresses on bus
    '( test for ACK to come back from Busaddress )
    
    Do
    
    Print "Scan start"
    For Busaddress = 0 To 255 'for all even addresses
      I2cstart
      I2cwbyte Busaddress
        If Err = 0 Then
        Erkannt = 1
          Print "Slave at address: " ; Busaddress ; " Dezimal, = " ; Hex(busaddress) ; " hex"
          Chipaddress = Busaddress \ 2
          Print " with chip address " ; Hex(chipaddress) ; "hex"
        End If
      I2cstop
    Next
    
    Print "End Scan"
    If Erkannt = 0 Then Print "Keine I2C Teilnehmer gefunden!!"
    Waitms 250
    
    Loop Until Erkannt = 1
    
    
    Main:
    
    Waitms 250 ' wait 250 ms for the MCP23016 powerup timer
    
    Call I2c_mcp23016_write(&H02 , &HFF , &HFF) 'Initiallize The Ouput Latch
    Call I2c_mcp23016_write(&H06 , &H00 , &H00) 'Initiallize It So That Both Lsbs & Msbs Are Outputs
    
    Lsb = &HFE '0 => Led is "on" FE => 11111110
    Msb = &HFE '0 => Led is "on" FE => 11111110
    
    Counter_1 = 0
    
    Do 'Chaser effect
     Print Bin(lsb) 'Ausgabe zur Kontrolle
     Print Bin(msb) 'Ausgabe zur Kontrolle
     Call I2c_mcp23016_write(&H02 , Lsb , Msb) 'Write Lsb & Msb to MCP23016
    
     Rotate Lsb , Left , 1 'Rotate the bits
     Rotate Msb , Left , 1
    
     Waitms 1000                                                 
     Counter_1 = Counter_1 + 1 'Increase the counter
    
    Loop                                                      
    
    End 
    
    '**********************************************************************
    '** Define Subroutines **
    '**********************************************************************
    Sub I2c_mcp23016_write(byval Cmd As Byte , Byval Lsb As Byte , Byval Data2 As Byte) ' Writes data to the I2C MCP23016.
    
     I2cstart 'Generate A Start Condition
     I2cwbyte Mcp23016_adress_w 'Transmit The "ADDRESS and WRITE" Byte
     I2cwbyte Cmd 'Transmit The Command Byte
     I2cwbyte Lsb 'Transmit First Data Byte
     I2cwbyte Msb 'Transmit Second Data Byte
     I2cstop 'Generate a STOP condition
     Waitus 50 'Some delay may be necessary for back to back transmitions
    
    End Sub
    
    Sub I2c_mcp23016_read
    ' Read data from the I2C MCP23016
    
     I2cstart 'Generate START condition
     I2cwbyte Mcp23016_adress_w 'Transmit The "ADDRESS and WRITE" Byte
     I2cwbyte &H00 'Transmit The Command Byte
     I2cstop 'Generate a STOP condition
     I2cstart 'Generate a START condition
     I2cwbyte Mcp23016_adress_r  'Transmit ADDRESS with READ command
     I2crbyte Lsb , Ack 'Receive first DATA byte (LSB) and acknowledge
     I2crbyte Msb , Nack 'Receive second DATA byte (MSB) and don't acknowledge
     I2cstop 'Generate a STOP condition
    
    End Sub
    Geändert von JoeM1978 (04.01.2014 um 16:39 Uhr)
    JAAAA... Microchips kann man essen... aber der Geschmack ist furchtbar.

  6. #6
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    31.05.2009
    Beiträge
    251
    Leider bleiben GPA und auch GPB trotzdem stumm.
    GPA sollte schon funktionieren.
    Steck' mal die Kontrolle in die Sub.


    Sub I2c_mcp23016_write(byval Cmd As Byte , Byval Lsb As Byte , Byval Data2 As Byte) ' Writes data to the I2C MCP23016.
    Print Bin(lsb) 'Ausgabe zur Kontrolle
    Print Bin(msb) 'Ausgabe zur Kontrolle

    I2cstart 'Generate A Start Condition
    I2cwbyte Mcp23016_adress_w 'Transmit The "ADDRESS and WRITE" Byte
    I2cwbyte Cmd 'Transmit The Command Byte
    I2cwbyte Lsb 'Transmit First Data Byte
    I2cwbyte Msb 'Transmit Second Data Byte
    I2cstop 'Generate a STOP condition
    Waitus 50 'Some delay may be necessary for back to back transmitions
    End Sub
    mfG
    Willi

  7. #7
    RN-Premium User Fleißiges Mitglied
    Registriert seit
    19.05.2012
    Ort
    Sigmaringen
    Beiträge
    169
    Dieses Programm hab ich bisher zusammengestellt.

    Es erkennt bisher die Busteilnehmeradresse und Schaltet am MCP23017 alle auf Ausgang.
    Die Ausgänge Toggeln im Sekundentakt zur Kontrolle.

    Ob es an der "falschen" busgeschwindigkeit lag (jetzt auf delay=10) oder ob das ansprechen der Register
    falsch war werde ich wohl noch genauer testen.



    Code:
    '**********************************************************************
    '** Programmbeschreibung **
    '**********************************************************************
    
    $regfile = "M328pdef.dat"
    $crystal = 16000000
    $baud = 38400
    
    '**********************************************************************
    '** Data Direction Registers und Ports - Do this before defining I2C pins!
    '**********************************************************************
    
    '**********************************************************************
    '**  I2C-Pins **
    '**********************************************************************
    
    Config Sda = Portc.4                                        ' I2C Data.
    Config Scl = Portc.5                                        ' I2C Clock.
    Config I2cdelay = 10
    
    
    '**********************************************************************
    '** Subroutinen **
    '**********************************************************************
    '
    ' This subroutine writes data to the I2C MCP23016.
    '
    Declare Sub I2c_mcp23016_write(byval Cmd As Byte , Byval Abyte As Byte , Byval Bbyte As Byte)
    
    
    '**********************************************************************
    '** Variablen **
    '**********************************************************************
    Dim Busaddress As Byte
    Dim Busaddress_read As Byte
    Dim Chipaddress As Byte
    Dim Erkannt As Bit
    Dim Abyte As Byte                                           '
    Dim Bbyte As Byte
    
    Dim Mcp23016_adress_w As Byte
    Mcp23016_adress_w = &H40                                    'Write Adresse des MCP23017: 0 1 0 0 _0 0 0_ 0
    
    Dim Mcp23016_adress_r As Byte
    Mcp23016_adress_r = &H41                                    'Read Adresse des MCP23017: 0 1 0 0 _0 0 0_ 1
    
    Dim Counter_1 As Byte
    
    
    '**********************************************************************
    '** Main-Programm **
    '**********************************************************************
    
    Waitms 250
    'Warte 250ms auf den MCP23016 Powerup-Timer
    
    'I2C-Bus nach allen verfügbaren Adressen (Dezimal 0-255) scannen
    
    Do
    Print "Scan gestartet"
    Waitms 250
    For Busaddress = 0 To 255
      I2cstart
      I2cwbyte Busaddress
        If Err = 0 Then                                         'wird kein Bus-Fehler gemeldet, ist die Adresse aktiv
        Erkannt = 1
          Print "Slave at addresse gefunden! Dezimal=" ; Busaddress ; " Hexadezimal=" ; Hex(busaddress)
        End If
      I2cstop                                                   'I2C-Bus durch "Stop" wieder frei machen für nächste Übertragung
    Next
    Print "Scan Beendet"
    If Erkannt = 0 Then Print "Keine I2C Teilnehmer gefunden!!"
    Waitms 100
    Loop Until Erkannt = 1
    
    '
    'Folgende Zeilen sind für den MCP23017 !!!
    'Alle GPA und GPB werden auf Ausgang eingestellt und im Sekundentakt getoggelt
    '
    
    Call I2c_mcp23016_write(&H00 , &H00 , &H00)                 'IODIRA und IODIRB alle auf Ausgänge einstellen
    
    Counter_1 = 1
    Do
    
     Call I2c_mcp23016_write(&H14 , &HFF , &HFF)                'OLATA und OLATB alle auf 1 stellen
     Waitms 1000
    
     Call I2c_mcp23016_write(&H14 , &H00 , &H00)                'OLATA und OLATB alle auf 0 Stellen
     Waitms 1000
    
    Counter_1 = Counter_1 + 1
    Loop
    
    End
    
    
    '**********************************************************************
    '** Define Subroutines **
    '**********************************************************************
    Sub I2c_mcp23016_write(byval Cmd As Byte , Byval Abyte As Byte , Byval Bbyte As Byte)
    ' Daten auf MCP23017 schreiben/senden
     I2cstart                                                   'Generate A Start Condition
     I2cwbyte Mcp23016_adress_w                                 'Transmit The "ADDRESS and WRITE" Byte
     I2cwbyte Cmd                                               'Transmit The Command Byte
     I2cwbyte Abyte                                             'Transmit First Data Byte
     I2cwbyte Bbyte                                             'Transmit Second Data Byte
     I2cstop                                                    'Generate a STOP condition
     Waitus 50                                                  'Some delay may be necessary for back to back transmitions
    
    End Sub
    ist das richtig, das ich hierbei...
    Code:
    Call I2c_mcp23016_write(&H14 , &HFF , &HFF)
    jeweils die Bytes für A und auch für B sende,
    da der IC die Registeradresse automatisch beim zweiten gesendeten Byte inkrementell erhöht?

    Wasmich auch noch etwas verwirrt... warum muss ich die Ausgänge auf das Register OLATx, und nicht auf GPIOx schreiben. bzw warum haben die Ausgänge überhaupt 2 Register?
    Geändert von JoeM1978 (05.01.2014 um 15:22 Uhr)
    JAAAA... Microchips kann man essen... aber der Geschmack ist furchtbar.

  8. #8
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    31.05.2009
    Beiträge
    251
    Zitat Zitat von JoeM1978 Beitrag anzeigen
    Ob es an der "falschen" busgeschwindigkeit lag (jetzt auf delay=10) oder ob das ansprechen der Register
    falsch war werde ich wohl noch genauer testen.
    Funktioniert jetzt ?

    Dann sind die Register doch verschieden !

    http://support2.microchip.com/KBSear...=SQ6UJ9A00DRP9

    ...man sollte sich sich nicht voreilig auf solche Aussagen verlassen...........
    mfG
    Willi

  9. #9
    RN-Premium User Fleißiges Mitglied
    Registriert seit
    19.05.2012
    Ort
    Sigmaringen
    Beiträge
    169
    Ich werd mal sehen, ob ich nen 16er irgendwo herbekom. dann kann ich das direkt in der Praxis vergleichen.

    Sobald ich etwas Zeit finde und erstmal selbst alles kapiert habe (von wegen IOCON und BANK usw.)
    versuche ich ein ordentliches Beispielprogramm oder ein "Tutorial" fürs Forum zu erstellen.

    Mich verwirrt an dem IC lediglich, das es ganz unterschiedliche Register bzw Tabellen gibt und mir noch nicht ganz klar ist,
    welche Tabelle nun wirklich wann zu verwenden ist.
    Einmal wird wohl Autoinkrementell gearbeitet, einmal wiedrr nicht... dann scheint es wohl noch ein Bit zu geben mit dem
    man die ganze Adressierungsreienfolge
    umstellt... wozu auch immer.
    JAAAA... Microchips kann man essen... aber der Geschmack ist furchtbar.

Ähnliche Themen

  1. LCD über I2C ansprechen
    Von Reissdorf im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 30.12.2012, 20:48
  2. PCA9635 per i2c ansprechen
    Von Sven2010 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 21.01.2010, 21:19
  3. MD22 via i2c vom Arduino ansprechen
    Von kywalda im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 01.04.2009, 20:48
  4. I2c-Bus ansprechen..aber wie???
    Von Goliath im Forum Software, Algorithmen und KI
    Antworten: 7
    Letzter Beitrag: 27.12.2007, 10:32
  5. RAMs / EEPROMs ansprechen (I2C)
    Von Zarathustra im Forum C - Programmierung (GCC u.a.)
    Antworten: 3
    Letzter Beitrag: 01.04.2007, 12:27

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •