Schau mal hier:
http://www.mcselec.com/index.php?opt...=107&Itemid=57
...das hat mir auch geholfen !
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.
EDIT: einige kleine Änderungen... zumindest sind die Datenpakete auf SDA nun vorhanden...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
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.
Schau mal hier:
http://www.mcselec.com/index.php?opt...=107&Itemid=57
...das hat mir auch geholfen !
mfG
Willi
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.
Versuch erst mal ne Adresse zu finden mit dem Software I2C, da kann man zumindest erst mal schauen ob ein Teilnehmer am Bus ist.
Müsste natürlich noch ein bischen angepast werden von dirCode:$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
Signatur??? kann ich mir nicht leisten!!!
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.
GPA sollte schon funktionieren.Leider bleiben GPA und auch GPB trotzdem stumm.
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
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.
ist das richtig, das ich hierbei...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 Subjeweils die Bytes für A und auch für B sende,Code:Call I2c_mcp23016_write(&H14 , &HFF , &HFF)
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.
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
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.
Lesezeichen