ATMega168 Master SPI mit SS als Ausgang?

#1184386
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
#1184393
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
}
Persönliche Seite #1184397
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
#1184400
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?
#1184405
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...
Persönliche Seite #1184408
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
#1184428
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.
#1184435
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.
#1184444
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)
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren