Testprogramm 3 - Verwendung beider Slaves
|
|
Bild 0-1: Zustand von Master, Slave1 und Slave2 nach mehrmaligem Drücken des Tasters PB0
#include <avr/io.h>
int main(void)
{
uint8_t akku;
//MOSI / PB5 als Output
DDRB |= 0b00100000;
//MISO / PB6 als Input
DDRB &= 0b10111111;
//SCK / PB7 als Output (für den Synchronisationstakt)
DDRB |= 0b10000000;
//SPI-Schnittstelle als Master ohne Interrupts konfigurieren und starten:
SPCR = (0<<SPIE) | (1<<SPE) | (0<<DORD) | (1<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);
//Slave Select Ausgänge PA1 und PA2 als Ausgänge:
DDRA |= 0b00000110;
PORTA |= 0b00000110; //Slave-select auf High setzen
//8-Bit-Parallel-Verbindung zu erstem Mikrocontroller (muecA), also PORTC als Ausgang:
DDRC = 0b11111111;
//Null anzeigen lassen, solange Taster nicht das erste mal gedrückt wurde.
PORTC = 0;
while(1)
{
if(PINB & (1<<PINB0)) //Wenn Taster PB0 gedrückt
{
//Kommunikation mit Slave 1
//PA1 auf Low, d.h. Slave 1 anwählen:
PORTA &= 0b11111101;
//Zu sendende Zahl 15 für den Sende/Empfangszyklus in das SPI-Datenregister schreiben:
SPDR = 15;
//Warten, bis Flag für erfolgreiche Datenübertragung gesetzt ist:
while( (SPSR & (1<<SPIF)) == 0);
akku = SPCR; //Durch Auslesen der Register SPCR und SPDR Interrupt wieder freigeben
//Empfangenes Byte nach Port C schicken, um es dezimal anzeigen zu lassen:
akku = SPDR;
PORTC = akku;
//Slave-select beider Slaves wieder auf high-Pegel:
PORTA |= 0b00000110;
//Kommunikation mit Slave 2
//PA2 auf Low, d.h. Slave 1 anwählen:
PORTA &= 0b11111011;
//Zu sendende Zahl 15 für den Sende/Empfangszyklus in das SPI-Datenregister schreiben:
SPDR = akku;
//Warten, bis Flag für erfolgreiche Datenübertragung gesetzt ist:
while( (SPSR & (1<<SPIF)) == 0);
akku = SPCR; //Durch Auslesen der Register SPCR und SPDR Interrupt wieder freigeben
//Empfangenes Byte nach Port C schicken, um es dezimal anzeigen zu lassen:
akku = SPDR; //In diesem Fall nichts mit der empfangenen Zahl tun.
//Slave-select beider Slaves wieder auf high-Pegel:
PORTA |= 0b00000110;
//Warten, bis Taste bei PB0 wieder losgelassen wird
while(PINB & (1<<PINB0));
}
}
return 0;
}
Code 0-6: Quellcode vom Master für Testprogramm 3
#include <avr/io.h>
#include <avr/interrupt.h> //Library für Interrupts
volatile uint8_t akku;
volatile uint8_t zahl=1;
SIGNAL(SIG_SPI) //Empfang über SPI vollständig, sollte auf Flag SPIF in SPSR reagieren!
{
akku = SPCR; //Durch Auslesen der Register SPCR und SPDR Interrupt wieder freigeben
akku = SPDR;
PORTC = akku; //Empfangenes Byte dezimal anzeigen. In diesem Fall die 15
zahl++; //Zu sendende Zahl um 1 erhöhen
SPDR = zahl; //Zusendende Zahl in das SPI-Datenregister legen.
}
int main(void)
{
//MOSI / PB5 als Input
DDRB &= 0b11011111;
//MISO / PB6 als Output (genau umgekerht wie beim Master)
DDRB |= 0b01000000;
//SCK / PB7 als Input (für den Synchronisationstakt)
DDRB &= 0b01111111;
DDRC = 0b11111111; //PORTC als Ausgang
PORTC = 0; //PORTC mit Null vorinitialisieren
//SPI-Datenregister mit der zu sendenden Zahl füllen:
SPDR = zahl;
//SPI-Schnittstelle als Slave und mit Interrupt aktivieren:
SPCR = (1<<SPIE) | (1<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);
//Interrupts allgemein aktivieren:
sei();
while(1) //Im Hauptprogramm nichts tun
{
}
return 0;
}
Code 0-7: Quellcode von Slave 1 für Testprogramm 3
#include <avr/io.h>
#include <avr/interrupt.h> //Library für Interrupts
volatile uint8_t akku;
SIGNAL(SIG_SPI) //Empfang über SPI vollständig, sollte auf Flag SPIF in SPSR reagieren!
{
akku = SPCR; //Durch Auslesen der Register SPCR und SPDR Interrupt wieder freigeben
akku = SPDR;
PORTC = akku; //Empfangenes Byte dezimal anzeigen. In diesem Fall die 15
SPDR = 255; //Zusendende Dummy-Zahl in das SPI-Datenregister legen.
}
int main(void)
{
//MOSI / PB5 als Input
DDRB &= 0b11011111;
//MISO / PB6 als Output (genau umgekerht wie beim Master)
DDRB |= 0b01000000;
//SCK / PB7 als Input (für den Synchronisationstakt)
DDRB &= 0b01111111;
DDRC = 0b11111111; //PORTC als Ausgang
PORTC = 0; //PORTC mit Null vorinitialisieren
//SPI-Datenregister mit der zu sendenden Dummy-Zahl füllen:
SPDR = 255;
//SPI-Schnittstelle als Slave und mit Interrupt aktivieren:
SPCR = (1<<SPIE) | (1<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);
//Interrupts allgemein aktivieren:
sei();
while(1) //Im Hauptprogramm nichts tun
{
}
return 0;
}
Code 0-8: Quellcode von Slave 2 für Testprogramm 3
spi5_komplett.zip - Projekt zu Testprogramm 3.