Ich habe zwei MCP23S17, jeweils die Eingänge 0-7 von GPIOA und die
Eingänge 0-1 von GPIOB beschaltet. Die Eingänge 2-7 von GPIOB sind somit
ungenutzt und liegen auf Masse.
Als Mikrocontroller verwende ich einen ATmega2560 vom Arduino-Board,
wobei ich den Controller direkt mit einem ISP-Programmer vom Atmel
Studio 7 aus beschreibe und nicht die Arduino-IDE dafür verwende.
Die beiden MCP23S17 liegen zusammen auf dem SPI-Bus und haben einen
gemeinsamen Slave-/Chip-Select (welcher mit einem 10 kOhm
Pull-up-Widerstand auf High gezogen wird), da ich für die beiden ICs
Hardware-Adressen (0x01 und 0x02) verwende. Der SPI-Bus ist über 330 Ohm
Widerstände auf den Leitungen CLK, MOSI und MISO vom Mikrocontroller
getrennt, da der Mikrocontroller ja über den ISP programmiert wird.
Wenn ich nun den ISP-Programmer vom Mikrocontroller trenne, werden keine
Daten von den beiden MCPs ausgelesen (auch nicht nach einem Reset). Wenn
der ISP-Programmer wieder angeschlossen wird, erhalte ich Daten. Aber
auch in diesem Fall treten merkwürdige Phänomene auf.
Wenn alle Eingänge auf Low sind, erhalte ich von den beiden GPIOs den
Wert 0 (lasse ich mir auf eine LCD-Anzeige ausgeben). Wenn alle
verwendeten Eingänge auf High sind erhalte ich von GPIOA auch den Wert
255 (0xFF) und von GPIOB 3 (0x03). Soweit scheint es ja zu passen.
Wenn alle GPIOs auf High sind (GPIOA Wert 255 und GPIOB Wert 3) und ich
das Bit 0 an GPIOA auf Low ziehe, wird dieses korrekt erkannt. Wird das
Bit 0 wieder auf High gesetzt und das Bit 1 auf Low gezogen, werden
sowohl das Bit 1 (korrekt) als auch das Bit 0 (falsch) als Low erkannt.
Wenn nun das Bit 2 auf Low ist, werden das Bit 2 (korrekt) und Bit 0
(falsch) als Low erkannt usw. Wenn also irgendeins der Bits 1 bis 7 an
GPIOA auf Low gezogen wird, wird fälschlicherweise das Bit 0 ebenfalls
als Low erkannt.
Dazu kommt dann noch zusätzliches Phänomen: Wenn ich das Bit 7 von GPIOA
auf Low ziehe, wird das Bit 1 von GPIOB ebenfalls als Low erkannt,
obwohl ich am GPIOB nichts verändert habe.
Ich vermute, dass entweder der SPI-Bus nicht sauber arbeitet oder aber
die Register von den GPIOs nicht ganz korrekt ausgelesen werden.
Zunächst wird im Main der SPI als Master initialisiert:
1
voidSPI_Master_Init(void)
2
{
3
4
DDRB|=(1<<PB2);// MOSI out
5
DDRB&=~(1<<PB3);// MISO in
6
DDRB|=(1<<PB1);// SCK out
7
DDRB|=(1<<PB0);// SS out
8
9
PORTB|=(1<<PB0);
10
11
SPCR&=~(1<<DORD);// erst MSB senden
12
SPCR|=(1<<MSTR);// SPI Master
13
14
// SPI-Mode 0
15
SPCR&=~(1<<CPOL);// Takt Polarität
16
SPCR&=~(1<<CPHA);// Takt Phase
17
18
// CLK-Teiler (128) // 16 MHz / 128 = 125 kHz
19
SPCR|=(1<<SPR1);// CLK-Teiler
20
SPCR|=(1<<SPR0);// CLK-Teiler
21
22
SPCR|=(1<<SPE);// SPI aktivieren
23
}
Dann werden die MCPs initialisiert, da diese ja nach dem Reset "dumm"
sind, haben die noch die Adresse 0x00.
1
voidmcp_init(void)
2
{
3
mcp_write(0x00,0x0A,0x28);// BANK = 0, MCP_SEQOP = 1, MCP_HAEN = 1
4
}
Zum Lesen und Schreiben habe ich folgende Funktionen:
> da der Mikrocontroller ja über den ISP programmiert wird
Also Frage, am Rande: dieser uC hat 4 USARTs, warum nicht einen davon
als SPI-Master verwenden?
Hallo,
> Wenn ich nun den ISP-Programmer vom Mikrocontroller trenne, werden keine> Daten von den beiden MCPs ausgelesen (auch nicht nach einem Reset). Wenn> der ISP-Programmer wieder angeschlossen wird, erhalte ich Daten. Aber> auch in diesem Fall treten merkwürdige Phänomene auf.
Daher vermute ich Probleme mit der Resetbeschaltung und/oder
Spannungsversorgung des µC und/oder MCP. Dem MCP muss man nach jedem
Reset seine Registereinstellungen neu mitteilen.
Wilfried S. schrieb:> Der SPI-Bus ist über 330 Ohm> Widerstände auf den Leitungen CLK, MOSI und MISO vom Mikrocontroller> getrennt, da der Mikrocontroller ja über den ISP programmiert wird.
Das ist übertrieben und überflüssig: solange RESET aktiv ist (das ist
beim Programmieren so), werden alle Kontroller-Ausgänge passiv. D.h. IC
auf SPI können Programmieren nicht stören.
Solche Schutz kann eigentlich nur dann helfen, wenn SPI in Slave-Modus
sein kann, d.h. von einem anderen Controller als Slave angesprochen.
Hätte er kein RESET, so könnte er nicht programmieren. So sollte hier
alles in Ordnung sein.
Wenn Reset von MCP23S17 nicht angeschlossen ist, dann arbeitet POR.
Wilfried S. schrieb:> Ich vermute, dass entweder der SPI-Bus nicht sauber arbeitet
So sieht das aus. Die Wege zu MCP23S17 sollten geprüft werden, bei SCK,
MISO und MOSI. Vielleicht irgendwo schlechte Kontakt. Hilfreich wäre SPI
auf verschiedenen Frequenzen und sogar mit Programm-SPI versuchen zu
steuern.
Wilfried S. schrieb:> _delay_ms(1);
Ich verstehe den Sinn dieses Befehls nicht.
Wilfried S. schrieb:> Wenn ich nun den ISP-Programmer vom Mikrocontroller trenne, werden keine> Daten von den beiden MCPs ausgelesen (auch nicht nach einem Reset). Wenn> der ISP-Programmer wieder angeschlossen wird, erhalte ich Daten. Aber> auch in diesem Fall treten merkwürdige Phänomene auf.
Das ist klare Indiz dafür, daß man Hardwarenverbindung prüfen sollte.
Vielen Dank für eure Antworten, die mich nochmal dazu veranlasst haben,
die elektrische Geschichte zu überprüfen. Manchmal sieht man den Wald
vor lauter Bäumen nicht und in diesem Fall fehlte eine gemeinsame
Masse-Verbindung zwischen der Einheit mit dem Mikrocontroller und der
Einheit mit den beiden MCPs.
Die Einheit mit dem Mikrocontroller versorge ich nämlich über ein
kleines USB-Netzteil und die Einheit mit den MCPs über ein anderes
Netzteil. Durch den ISP-Programmer über USB -> PC -> Steckdose ->
Netzteil kam scheinbar halbwegs eine Masse-Verbindung zustande, sodass
es zusammen mit dem ISP-Programmer zumindest teilweise (aber auch nicht
korrekt) funktionierte. Ohne ISP-Programmer ging ja gar nichts, das
würde immerhin dieses Phänomen erklären.
Mit der nun bestehenden Masse-Verbindung scheint nun alles wie gewünscht
zu funktionieren. Danke nochmal für eure Anstubser. Da ich zuvor noch
nichts mit SPI gemacht habe und beim Recherchieren auch nicht auf
derartige Probleme gestoßen bin, war ich echt verzweifelt. Umso
peinlicher, dass die Ursache nun etwas Grundlegendes war.
S. Landolt schrieb:> Also Frage, am Rande: dieser uC hat 4 USARTs, warum nicht einen davon> als SPI-Master verwenden?
Gute Frage - da habe ich noch nicht drüber nachgedacht.
Maxim B. schrieb:> Das ist übertrieben und überflüssig
Naja, diese "Empfehlung" habe ich aus der Application Note zu den "AVR
Microcontroller Hardware Design Considerations" (AN2519) von Microchip.
Christian S. schrieb:> bisher haben wir noch nichts über die Beschaltung der> Reset-Anschlüsse der MCPs erfahren
Die Reset-Pins von den beiden MCPs habe ich standardmäßig mit einem
Pull-up-Widerstand auf High gezogen.
Wilfried S. schrieb:> Naja, diese "Empfehlung" habe ich aus der Application Note
Sie ist "allgemein" gedacht, für alle mögliche Fälle. Und wirklich, wenn
SPI als Slave arbeiten sollte, oder teilweise als Slave, dann sind diese
Widerstände wirklich notwendig, da SCK und MOSI von anderen Controller
gesteuert sein können auch, wenn Reset von zu programmierenden
Controller aktiv ist. Wenn aber SPI ausschließlich als Master in der
Schaltung arbeitet, so gibt es niemand außer zu programmierenden
Controller und Programmator, der diese Leitungen aktiv bedienen kann.
Laut Datenblatt ist garantiert, daß bei Reset alle Pins hochimpedant
sind. Deshalb Widerstand an ~CS absolut richtig,anderen aber nicht
notwendig.
Wilfried S. schrieb:> Die Reset-Pins von den beiden MCPs habe ich standardmäßig mit einem> Pull-up-Widerstand auf High gezogen.
Die darfst du auch ohne Widerstand an Vcc schalten. Noch besser, vor
allem wenn Platine als Versuchsplatine gedacht ist, die mit System-Reset
zu verbinden. Dann werden die beiden MCP garantiert auch bei dem
Neustart von Controller in Anfangszustand. Jetzt werden sie resettet nur
wenn Vcc aus- und dann eingeschaltet wird.