PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] MCP23017 - I2C ansprechen ohne Erfolg



JoeM1978
21.12.2013, 12:00
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.


$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 (http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf) verwirrt mich eh unheimlich.

Falls jemand Tips hätte wäre ich sehr dankbar!

WL
21.12.2013, 18:08
Schau mal hier:

http://www.mcselec.com/index.php?option=com_content&task=view&id=107&Itemid=57

...das hat mir auch geholfen !

JoeM1978
27.12.2013, 14:34
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

Rofo88
27.12.2013, 15:30
Versuch erst mal ne Adresse zu finden mit dem Software I2C, da kann man zumindest erst mal schauen ob ein Teilnehmer am Bus ist.





$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 :)

JoeM1978
04.01.2014, 09:34
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)





$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

WL
04.01.2014, 20:34
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

JoeM1978
05.01.2014, 14:14
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.





'************************************************* *********************
'** 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...
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?

WL
05.01.2014, 17:35
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/KBSearch/KB_StdProb.aspx?ID=SQ6UJ9A00DRP9

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

JoeM1978
07.01.2014, 07:15
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.