PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SPI bei Atmega 2560 will nicht



Kampfwurst_Hugo
05.10.2011, 18:33
Hallo

Ich habe von meinem Lehrer einen Code für SPI erhalten.
Der Atmega 2560 soll der Master sein. Als Slaves werden 2 AT90PWM316 oder 2 Atmega 16 verwendet.

Das Problem ist das ich nicht mal den Master zum laufen bekommen.
Warscheinlich ist nur eine Kleinigkeit falsch aber ich finde den Fehler nicht.

Hier der Code.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

unsigned char status = 0;
volatile unsigned char count;

void timer1 (void);
void master_init (void);
void master_transmit (unsigned char data);

SIGNAL (SIG_SPI) {
return;
}

SIGNAL (SIG_OVERFLOW1) { //Senderoutine
if (count == 1) {
master_transmit ('1');
count--;
return;
}
if (count == 0) {
master_transmit ('0');
count++;
}
}

void timer1 (void) {
TIMSK1 |= _BV(TOIE1); //Timer Overflow Interrupt enable
TCNT1 = 0; //Rücksetzen des Timers
TCCR1B = _BV(CS10) | _BV(CS11); //8MHz/65536/64 = 1,91Hz --> 0,5s
}

void master_init (void) {
DDRB = _BV(PB0) | _BV(PB3) | _BV(PB5); // setze SCK,MOSI,PB0 (SS) als Ausgang
DDRB &= ~_BV(PB4); // setze MISO als Eingang
PORTB = _BV(PB5) | _BV(PB0); // SCK und PB0 high (ist mit SS am Slave verbunden)
SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR0); //Aktivierung des SPI, Master, Taktrate fck/16
status = SPSR; //Status löschen
}

void master_transmit (unsigned char data) {
PORTB &= ~_BV(PB0); //SS am Slave Low --> Beginn der Übertragung
SPDR = data; //Schreiben der Daten
while (!(SPSR & (1<<SPIF)));
PORTB |= _BV(PB0); //SS High --> Ende der Übertragung
}

int main (void) {

master_init ();
timer1 ();
sei ();

for (;;);
return 0;
}

sternst
05.10.2011, 18:47
DDRB = _BV(PB0) | _BV(PB3) | _BV(PB5); // setze SCK,MOSI,PB0 (SS) als Ausgang
DDRB &= ~_BV(PB4); // setze MISO als Eingang
PORTB = _BV(PB5) | _BV(PB0); // SCK und PB0 high (ist mit SS am Slave verbunden)Nö.

Schau im Datenblatt nach, auf welchen Pins die jeweiligen Signale überhaupt liegen.

Kampfwurst_Hugo
05.10.2011, 21:06
ok habs abgeändert.


DDRB = _BV(PB0) | _BV(PB1) | _BV(PB2); // setze SCK,MOSI,PB0 (SS) als Ausgang
DDRB &= ~_BV(PB3); // setze MISO als Eingang
PORTB = _BV(PB1) | _BV(PB0); // SCK und PB0 high (ist mit SS am Slave verbunden)

müsste ich nicht am SCK ein Clock signal sehen können???

Kampfwurst_Hugo
06.10.2011, 17:57
keiner eine Idee?

Hier nochmal der ganze Code

/************************************************** ************
Es soll alle halbe Sekunde im Wechsel 0 bzw. 1 gesendet werden.
Am korrespondierenden Slave soll zur Indikation jeweils die
LEDs an bzw. aus gehen
Verdrahtung: MISO(Master) --> MISO(Slave)
MOSI(Master) --> MOSI(Slave)
SCK(Master) --> SCK(Slave)
PB0(Master) --> SS(Slave)
************************************************** ************/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

unsigned char status = 0;
volatile unsigned char count;

void timer1 (void);
void master_init (void);
void master_transmit (unsigned char data);

SIGNAL (SIG_SPI) {
return;
}

SIGNAL (SIG_OVERFLOW1) { //Senderoutine
if (count == 1) {
master_transmit ('1');
count--;
PORTL = 0xFF;
return;
}
if (count == 0) {
master_transmit ('0');
PORTL = 0x00;
count++;
}
}

void timer1 (void) {
TIMSK1 |= (1<<TOIE1); //Timer Overflow Interrupt enable
TCNT1 = 0; //Rücksetzen des Timers
TCCR1B = (1<<CS10) | (1<<CS11); //8MHz/65536/64 = 1,91Hz --> 0,5s
}

void master_init (void) {
DDRB = (1<<PB1) | (1<<PB2) | (1<<PB0); // setze SCK,MOSI,PB0 (SS) als Ausgang
PORTB = (1<<PB1) | (1<<PB0); // SCK und PB0 high (ist mit SS am Slave verbunden)
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); //Aktivierung des SPI, Master, Taktrate fck/16
status = SPSR; //Status löschen
}

void master_transmit (unsigned char data) {
PORTB &= ~(1<<PB0); //SS am Slave Low --> Beginn der Übertragung
SPDR = data; //Schreiben der Daten
while (!(SPSR & (1<<SPIF)));
PORTB |= (1<<PB0); //SS High --> Ende der Übertragung
}

int main (void) {
DDRL = 0xFF;
master_init ();
timer1 ();
sei ();

for (;;);
return 0;
}

sternst
06.10.2011, 18:43
müsste ich nicht am SCK ein Clock signal sehen können???Ja.

Allerdings stellt sich mir die Frage, wie du denn überhaupt feststellst, ob da was zu sehen ist. Ist dir überhaupt klar, dass (bei z.B. 1Mhz Systemtakt) nur in ca 0,03% der Zeit ein Takt zu sehen ist, und in den restlichen 99,97% nicht?

Kampfwurst_Hugo
06.10.2011, 19:30
hallo

habe einen Logikanalysator (zeroplus). Trotzdem sehe ich nichts. Dachte das das Clock Signal die ganze Zeit anliegt