Hi,
ich versuche mich gerade an einem MCP23017 (i2c) und habe etwas
Schwierigkeiten beim setzen des IOCON-Registers.
Folgendes funktioniert hervorragend:
1 | // reset ic
|
2 | PORTB |= (1 << PORTB1);
|
3 | _delay_ms(100);
|
4 | PORTB |= (1 << PORTB1);
|
5 |
|
6 | // GPIOA as OUTPUT
|
7 | i2c_start(MCP23017_ADDR + I2C_WRITE);
|
8 | i2c_write(0x00);
|
9 | i2c_write(0x00);
|
10 | i2c_stop();
|
11 |
|
12 | // GPIOB as OUTPUT
|
13 | i2c_start(MCP23017_ADDR + I2C_WRITE);
|
14 | i2c_write(0x01);
|
15 | i2c_write(0x00);
|
16 | i2c_stop();
|
17 |
|
18 | while (1) {
|
19 | i2c_start(MCP23017_ADDR + I2C_WRITE);
|
20 | i2c_write(0x00);
|
21 | i2c_write(0xFF);
|
22 | i2c_write(0xFF);
|
23 | i2c_stop();
|
24 |
|
25 | _delay_ms(100);
|
26 |
|
27 | i2c_start(MCP23017_ADDR + I2C_WRITE);
|
28 | i2c_write(0x00);
|
29 | i2c_write(0x00);
|
30 | i2c_write(0x00);
|
31 | i2c_stop();
|
32 |
|
33 | _delay_ms(100);
|
34 | }
|
Um sicherzugehen, dass nach jedem Flash keine Werte in dem IC überleben,
resette ich ihn vorher. Danach setze ich x00 == GPIOA und x01 == GPIOB
auf OUTPUT.
http://ww1.microchip.com/downloads/en/devicedoc/21952b.pdf
Ich möchte nun zusätzlich zum oben gezeigten Beispiel das IOCON Register
verändern. Ersteinmal möchte ich es auf 0x00 setzen, damit es identisch
ist zum Defaultwert.
Im Datenbatenblatt ist das Register standardmäßig gesetzt auf IOCON =
0x00. Dadurch ist IOCON.BANK = 0x00 und das wiederum bedeutet laut
Datenblatt:
"0 = The registers are in the same bank (addresses are sequential)"
Durch IOCON.BANK kann man die Adressen der Register anders anordnen.
IOCON.BANK = 1 bedeutet, die Adressen liegen in zwei Blöcken. IOCON.BANK
= 0 bedeutet, die Adressen liegen nacheinander (0x00, 0x01 = GPIOA,
GPIOB, ..). Laut dem Datenblatt sollte das IOCON Register auf 0x0A oder
0x0B liegen, da IOCON.BANK = 0. In der Überschrift dagegen steht:
"IOCON – I/O EXPANDER CONFIGURATION REGISTER (ADDR 0x05)"
Welche ist nun die richtige Adresse? Meiner Meinung nach 0x0A und 0x0B,
da eben IOCON.BANK = 0 durch IOCON = 0x00. Im Anhang der Abschnitt. Aber
warum steht dann in der Überschrift 0x05, was auf IOCON.BANK = 1
hindeuten würde? Das verstehe mal einer!
Um nun testweise das IOCON-Register mit 0x00 zu setzen (was es
eigentlich lt. Datenblatt schon haben sollte), schreibe ich:
1 | i2c_init();
|
2 |
|
3 | i2c_start(MCP23017_ADDR + I2C_WRITE);
|
4 | i2c_write(0x05); // oder auch 0x0A, geht beides nicht
|
5 | i2c_write(0x00);
|
6 |
|
7 | // ...
|
Danach ist nur noch Port A (0x00) auf OUTPUT gesetzt, Port B bleibt auf
INPUT. Auch das schreiben auf Port B klappt nicht mehr.
Da ich aber den gleichen Wert für das Register setze, welcher im
Register bereits gesetzt ist, sollte sich doch eigentlich nichts ändern?
Ich überschreibe 0x00 mit 0x00. Warum verhält er sich da nun anders, wie
davor?
Für jeder Hilfe bin ich dankbar.
Gruß,
Kevin