Forum: Mikrocontroller und Digitale Elektronik Mega8, SPI, SCK tut nichts


von Markus R. (maggus)


Lesenswert?

Hallo,
ich kämpfe gerade mit dem Hardware-SPI eines Mega8. Auf der Datenleitung 
spuckt der AVR zwar was aus, allerdings bleibt die CLK-Leitung völlig 
stumm. Ich komm einfach nicht auf den fehler, die Hardware scheint 
vollkommen i.o. zu sein (muss man bei den Fusebits was beachten 
bezüglich SPI?).
1
MOSI = output
2
SCK = output
3
4
//main:
5
SPCR |= ((1<<SPE)|(1<<MSTR)|(1<<SPR0)); 
6
SPSR &= ~(1<<SPI2X);
7
8
while(1)
9
{
10
    sd_write_byte(0x53);
11
}
12
13
14
15
//sub:
16
void sd_write_byte(unsigned char byte)
17
{
18
  SPDR = byte;   //Sendet ein Byte
19
  while(!(SPSR & (1<<SPIF))); //Wartet bis Byte gesendet wurde
20
  SPDR;
21
}

Gruß Markus

von Jean P. (fubu1000)


Lesenswert?

Hi,
im Master mode muss der SS Pin als Ausgang geschaltet sein. In deinem 
Fall PB2.

Gruß

von Bensch (Gast)


Lesenswert?

> im Master mode muss der SS Pin als Ausgang geschaltet sein. In deinem
Fall PB2.

Das ist falsch, siehe Datenblatt.

von Stefan E. (sternst)


Lesenswert?

Fabian Ostner wrote:
> im Master mode muss der SS Pin als Ausgang geschaltet sein.

Nein.
Im Master Mode ist SS einfach nur ein ganz normaler I/O-Pin.

von Markus R. (maggus)


Lesenswert?

Mit dem SS-Pin habe ich auch schon alles mögliche ausprobiert, aber 
daran liegts nicht (egal ob Ausgang oder Eingang, low oder high).

DDRB |= ((1<<PB1) | (1<<PB2) | (1<<PB3) | (1<<PB5));
PORTB |= ((1<<PB2));      // SS auf 1
PORTB &= ~(1<<PB1);

PB1 soll mal CS werden, spielt beim jetzigen Problem aber noch keine 
Rolle.

von holger (Gast)


Lesenswert?

1
void sd_write_byte(unsigned char byte)
2
{
3
  SPDR = byte;   //Sendet ein Byte
4
  while(!(SPSR & (1<<SPIF))); //Wartet bis Byte gesendet wurde
5
6
  SPDR; //<<<--- was soll das bezwecken? Weg damit.
7
}

von Jean P. (fubu1000)


Lesenswert?

Da die Herren so aufs Datenblatt pochen, hier ein kleiner Ausschnitt für 
euch:

>If SS is configured as an output, the pin is a general output pin which >does not 
affect the
>SPI system. Typically, the pin will be driving the SS pin of the SPI Slave.
>If SS is configured as an input, it must be held high to ensure Master SPI 
>operation.

Also falls Eingang muss er High gehalten werden, für Master mode. 
Sinnfrei für Master Betrieb. Also auf Ausgang schalten.

Gruß

von Markus R. (maggus)


Lesenswert?

@holger

Das ist dazu da, um das SPIF Flag zu clearen, wenn ich es weglasse 
wackelt der SCK Pin allerdings trotzdem nicht.

von holger (Gast)


Lesenswert?

>Das ist dazu da, um das SPIF Flag zu clearen, wenn ich es weglasse
>wackelt der SCK Pin allerdings trotzdem nicht.

  SPDR = byte;   //Sendet ein Byte

macht das auch schon. Es wird also auch beim schreiben
in SPDR gelöscht.

Kannst du SCK als einfachen IO-Pin noch toggeln?

von Markus R. (maggus)


Lesenswert?

> Kannst du SCK als einfachen IO-Pin noch toggeln?

Nein geht nich. Selbst wenn ich den SPI ausschalte (SPE = 0) kann ich 
den pin nicht toggeln.

while(1)
{
  PORTB ^= (1<<PB5);
  _delay_us(2);
}

mit PB1 z.B. geht die Sache aber.
Woran liegt das?

Es ist übrigens ein ATmega8L8 @3,0V 4mhz, falls das was zur Sache tut.

von holger (Gast)


Lesenswert?

>> Kannst du SCK als einfachen IO-Pin noch toggeln?

>Nein geht nich. Selbst wenn ich den SPI ausschalte (SPE = 0) kann ich
>den pin nicht toggeln.
>Woran liegt das?

Kurzschluss auf der Leitung?

von Markus R. (maggus)


Lesenswert?

> Kurzschluss auf der Leitung?

Nein, habs grade nochmal durchgemessen.

Auf einem Mega162 @5V 8mhz(interner osc) wackelt der SCK Pin brav bei 
gleichen Registereinstellungen.

von Michael K. (mmike)


Lesenswert?

Versuch mal nen anderen Pin wackeln zu lassen und schau's Dir auf dem 
Scope an. Prüf auch mal die Einstellungen beim kompilieren (richtiger 
Controller ausgewählt, ...). Mit was wird denn kompiliert? Winavr, 
AVRStudio?

Poste auch mal den kompletten Quellcode.

von Markus R. (maggus)


Lesenswert?

Wie gesagt, wenn ich z.B. PB1 wackeln lasse funktioniert das gut, es 
gibt auch ein sauberes Rechteck auf dem Scope.

Hier mal der komplette code für den Mega8:
1
#include <avr/io.h>
2
#include <stdlib.h>
3
#include <util/delay.h>
4
#include <util/uart_mega.h>
5
6
7
8
void sd_write_byte(unsigned char byte);
9
10
11
12
13
int main(void)
14
{  
15
  DDRB |= ((1<<PB2) | (1<<PB3) | (1<<PB5));
16
  PORTB |= (1<<PB2);      // SS auf 1
17
  
18
  uart_init();
19
  
20
  SPCR |= ((1<<SPE)|(1<<MSTR)|(1<<SPR0)); //Enable SPI, SPI in Master Mode, presc = 16
21
22
  
23
  _delay_ms(100);  
24
  
25
  while(1)
26
  {
27
    sd_write_byte(0x53);
28
    _delay_us(10);
29
  }
30
}
31
32
33
void sd_write_byte(unsigned char byte)
34
{
35
  SPDR = byte;   //Sendet ein Byte
36
  while(!(SPSR & (1<<SPIF)));  //Wartet bis Byte gesendet wurde
37
}

Compiler ist WinAVR, geflasht wird mit PonyProg.

von holger (Gast)


Lesenswert?

Hast du direkt am Chip gemessen oder irgendwo
auf der Platine? Vieleicht steckt das Beinchen
ja nicht im Sockel, oder falls SMD, gar nicht angelötet.

von Markus R. (maggus)


Lesenswert?

So, hab jetzt noch 2 andere ATmega8L-8PU getestet, einer mit internem 
OSC und einer mit externem Quartz, diese funktionieren mit exakt dem 
gleichen Code wunderbar. Die Fusebits sind auch gleich.
Ich nehme also an, dass genau dieser eine AVR wohl (teilweise?) kaputt 
ist...

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.