Scrat1
01.09.2005, 16:44
Hallo,
habe ein Problem mit der SPI Schnittstelle.
Erstmal den Code für den Master
#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) {
TIMSK |= (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<<PB0) | (1<<PB5) | (1<<PB7); // setze SCK,MOSI,PB0 (SS) als Ausgang
DDRB &= ~(1<<PB6); // setze MISO als Eingang
PORTB = (1<<PB7) | (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) {
master_init ();
timer1 ();
sei ();
for (;;);
return 0;
}
Code für Slave:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
volatile unsigned char data;
unsigned char status;
SIGNAL (SIG_SPI) {
data = SPDR;
if (data == '1') PORTD = 0x00; //LEDs an
if (data == '0') PORTD = 0xff; //LEDs aus
}
void slave_init (void) {
DDRB |= (1<<PB6); //MISO als Ausgang, der Rest als Eingang
SPCR = (1<<SPE) | (1<<SPIE); //Aktivierung des SPI + Interrupt
status = SPSR; //Status löschen
}
int main (void) {
DDRD = 0xff;
slave_init ();
sei ();
for (;;);
return 0;
}
Ich habe diesen Code irgendwo im Internet gefunden, weil mein eigener nicht funktionieren wollte.
Wie schon im Titel beschrieben will ich mit der SPI Schnittstelle 2 Atmega 16 miteinender "verbinden".
Ich bin jetzt soweit, dass ich glaube, dass der Master immer an dieser Stelle hängen bleibt:
while (!(SPSR & (1<<SPIF)));
einmal kann diese Stelle passiert werden, dannach bleibt der Atmega stecken.
Und beim Slave wird nie das Interrupt ausgelöst.
Beide Schaltungen beinhalten einen 16 MHz Quarz.
Kann mir jemand helfen, bin am verzweifeln...
Gruß
Scrat1
habe ein Problem mit der SPI Schnittstelle.
Erstmal den Code für den Master
#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) {
TIMSK |= (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<<PB0) | (1<<PB5) | (1<<PB7); // setze SCK,MOSI,PB0 (SS) als Ausgang
DDRB &= ~(1<<PB6); // setze MISO als Eingang
PORTB = (1<<PB7) | (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) {
master_init ();
timer1 ();
sei ();
for (;;);
return 0;
}
Code für Slave:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
volatile unsigned char data;
unsigned char status;
SIGNAL (SIG_SPI) {
data = SPDR;
if (data == '1') PORTD = 0x00; //LEDs an
if (data == '0') PORTD = 0xff; //LEDs aus
}
void slave_init (void) {
DDRB |= (1<<PB6); //MISO als Ausgang, der Rest als Eingang
SPCR = (1<<SPE) | (1<<SPIE); //Aktivierung des SPI + Interrupt
status = SPSR; //Status löschen
}
int main (void) {
DDRD = 0xff;
slave_init ();
sei ();
for (;;);
return 0;
}
Ich habe diesen Code irgendwo im Internet gefunden, weil mein eigener nicht funktionieren wollte.
Wie schon im Titel beschrieben will ich mit der SPI Schnittstelle 2 Atmega 16 miteinender "verbinden".
Ich bin jetzt soweit, dass ich glaube, dass der Master immer an dieser Stelle hängen bleibt:
while (!(SPSR & (1<<SPIF)));
einmal kann diese Stelle passiert werden, dannach bleibt der Atmega stecken.
Und beim Slave wird nie das Interrupt ausgelöst.
Beide Schaltungen beinhalten einen 16 MHz Quarz.
Kann mir jemand helfen, bin am verzweifeln...
Gruß
Scrat1