Forum: Mikrocontroller und Digitale Elektronik ATMega168 Master SPI mit SS als Ausgang?


von Manuel K. (draradech)


Lesenswert?

Hallo,

laut Datenblatt sollte es doch problemlos möglich sein, SS als Ausgang 
zu nutzen, während SPI im Master Mode aktiv ist. Bei mir funktioniert 
das irgendwie nicht. In meiner Verzweiflung setze ich jetzt an vier 
Stellen während der SPI initialisierung den SS als Ausgang (und auf 1 um 
sicherzustellen, dass Master SPI erhalten bleibt, auch das sollte ja 
wohl unnötig sein). Trotz alledem ist SS danach Eingang, SPI 
funktioniert dementsprechend nicht als Master und ich kann PB2 nicht 
schalten. Irgendeine Idee was hier schiefläuft?
1
    // SPI
2
    DDRB |= (1 << PB3);         // MOSI out
3
    DDRB |= (1 << PB5);         // SCK out
4
5
    DDRB |= (1 << PB2);         // SS out
6
    PORTB |= (1 << PB2);        // SS to 1
7
8
    SPCR |= (1 << SPE);         // SPI enable
9
10
    DDRB |= (1 << PB2);         // SS out
11
    PORTB |= (1 << PB2);        // SS to 1
12
13
    SPCR |= (1 << MSTR);        // SPI Master mode
14
15
    DDRB |= (1 << PB2);         // SS out
16
    PORTB |= (1 << PB2);        // SS to 1
17
18
    SPCR |= (1 << SPR0);        // 1,25 MHz SPI clock
19
20
    DDRB |= (1 << PB2);         // SS out
21
    PORTB |= (1 << PB2);        // SS to 1

von (prx) A. K. (prx)


Lesenswert?

Woran ist erkennbar, dass es nicht funktioniert?

von Manuel K. (draradech)


Lesenswert?

Hallo,

PB2 hat einen externen pull-down, damit im reset der Pegel definiert auf 
0 ist. Nach obiger initialisierung sind 0,3V an PB2 zu messen. (Interner 
Pull-up gegen externer Pull-down). Ausserdem funktioniert SPI nicht. 
Nach schreiben eines Bytes nach SPDR wird SPIF in SPSR nicht gesetzt, 
was bei mir in einer Endlosschleife resultiert.
1
static uint8_t spiSendRecv(uint8_t byte)
2
{
3
    SPDR = byte;
4
    while(!(SPSR & (1 << SPIF)));
5
    return SPDR;
6
}

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Bei mir sieht's so aus (ATmega8, SPI out-only):
1
void serpa_init()
2
{
3
  MAKE_OUT (PORT_SER); 
4
  MAKE_OUT (PORT_SCK);
5
  MAKE_OUT (PORT_RCK); SET (PORT_RCK);
6
  // !!! SS must be OUT to prevent SPI switching to Slave Mode !!!
7
  MAKE_OUT (PORT_SS);
8
  // pullup on MISO to avoid floating
9
  SET (PORT_MISO);
10
  // enable SPI as Master
11
  // high Bits first
12
  // SCK is high when idle
13
  SPCR = (1 <<  SPE) | (1 <<  MSTR) | (1 <<  CPOL);
14
  
15
  // max speed: F_CPU / 2   
16
  SPSR |= (1 <<  SPI2X);
17
}

SER steht bei mir für MOSI, und RCK brauchst du nicht (isn normaler 
I/O). Allerdings setze ich SPCR in einem Stück, nicht bitweise. Sollte 
auf einem ATmega618 ähnlich gehen. SS wird in der Anwendung übrigens als 
PWM betrieben, hat also nix mit SPI zu tun -- ausser, daß es OUT sein 
muß.

Johann

von (prx) A. K. (prx)


Lesenswert?

Manuel Kasten wrote:

> PB2 hat einen externen pull-down, damit im reset der Pegel definiert auf
> 0 ist.

Was hängt denn da an dem Pin dran? Alle SPI-Slaves, die ich bisher 
verwendet habe, werden bei 0 aktiviert. Weshalb eher Pullup als Pulldown 
üblich ist.

Was für einen Wert hat der Pulldown denn? Wobei ich nicht den Wert 
meine, den er laut Plan hat, oder was du drauf erkennst, sondern welchen 
er wirklich hat.

Wie gross ist der gemessene Stromverbrauch des Controllers?

von Manuel K. (draradech)


Lesenswert?

@Johann
Ja, mein ursprünglicher Code sah so aus:
1
    // SPI
2
    DDRB |= (1 << PB3);         // MOSI out
3
    DDRB |= (1 << PB5);         // SCK out
4
    DDRB |= (1 << PB2);         // SS out
5
    
6
    SPCR |= (1 << SPE)          // SPI enable
7
         |  (1 << MSTR)         // SPI Master mode
8
         |  (1 << SPR0);        // 1,25 MHz SPI clock
Leider hat auch das schon nicht funktioniert, deshalb die Experimente 
oben.

@A. K.
Ich habe mehrere SPI Slaves, keiner hängt an SS :)

Pulldown hat 1K - Es ist auch nicht der einzige, andere Ausgänge haben 
ebenfalls Pulldowns - die funktionieren wunderbar.

Gesamtstromverbrauch liegt bei 90mA (inklusive Sensoren und Bluetooth)

edit: Ich würde ja einfach SS freimachen und einen anderen Pin 
verwenden, allerdings bin ich voll belegt...

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Manuel Kasten wrote:

> PB2 hat einen externen pull-down, damit im reset der Pegel definiert auf
> 0 ist. Nach obiger initialisierung sind 0,3V an PB2 zu messen. (Interner
> Pull-up gegen externer Pull-down). Ausserdem funktioniert SPI nicht.
> Nach schreiben eines Bytes nach SPDR wird SPIF in SPSR nicht gesetzt,
> was bei mir in einer Endlosschleife resultiert.

Womöglich ist der PullDown zu klein, also mal ein paar Ticks warten bis 
sich der Pegel angepasst hat und überprüfen, ob der Pegel mit SS=1 hoch 
genug ist.

Johann

von (prx) A. K. (prx)


Lesenswert?

Manuel Kasten wrote:

> Pulldown hat 1K - Es ist auch nicht der einzige, andere Ausgänge haben
> ebenfalls Pulldowns - die funktionieren wunderbar.

Hat er 1K, oder sollten das 1K sein? Stell den Pin mal auf Eingang und 
zieh ihn extern mit 100 Ohm auf 5V. Wenn er dann immer noch nicht oben 
ist, dann liegt der Hund in dem was da dranhängt begraben. Wenn es geht, 
hast wohl irgendwann den Pin erlegt.

von (prx) A. K. (prx)


Lesenswert?

Manuel Kasten wrote:

> Ich habe mehrere SPI Slaves, keiner hängt an SS :)

Und deshalb gehört es zu den leider seltenen aber immer wieder gern 
gesehenen Gesten, solche Threads mit einem Schaltbild zu bereichern.

von Manuel K. (draradech)


Lesenswert?

Er hat 1K - und der Pin ist auch noch ok. Wenn ich SPI nicht aktiviere, 
funzt er als output. Bin gerade ziemlich ratlos.

Schalbild folgt - mal eben auf den aktuellen Stand bringen.

von (prx) A. K. (prx)


Lesenswert?

Manuel Kasten wrote:

> Er hat 1K - und der Pin ist auch noch ok. Wenn ich SPI nicht aktiviere,
> funzt er als output. Bin gerade ziemlich ratlos.

Dann sind wie also bei folgender Logik:
- Alles richtig angeschlossen.
- Programm korrekt (mangels Code nicht kontrollierbar).
- Controller ok.
- Funktioniert nicht.

Jetzt such dir aus, welche dieser Aussagen falsch ist. Mindestens eine 
ist es.

von Manuel K. (draradech)


Angehängte Dateien:

Lesenswert?

OK, hier erstmal das Schaltbild. Code: Ich werds auf ein minimales 
Beispiel herunterbrechen, entweder finde ich dabei den Fehler, oder ich 
poste das dann hier.

Zum Schaltbild: An SPI 2 und 3 hängen SPI-sprechende Sensoren (Gyro und 
Beschleunigung). Am "SS" von SPI1 soll später 1/3 VDD hängen, um den 
Ladungszustand der Batterie zu überwachen (Derzeit an Labornetzteil)

von Sven K. (Gast)


Lesenswert?

Wie wäre es damit ?

SPCR = (1 << SPE)          // SPI enable
         |  (1 << MSTR)         // SPI Master mode
         |  (1 << SPR0);        // 1,25 MHz SPI clock.

und nicht SPCR |=
....

Gruß Sven

von Manuel K. (draradech)


Lesenswert?

Ohh! Das geht! Wie kommts?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.