Mega8, SPI, SCK tut nichts

OP #1147300
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
OP #1147342
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.
#1147350
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ß
Gast #1147370
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?
OP #1147390
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.
OP #1147416
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.

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