kramann.info
© Guido Kramann

Login: Passwort:










Mikrocontroller
1 Einfuehrung
..1.1 Entwicklungsgeschichtliches
..1.2 Maschinensprache
..1.3 Assemblerbeispiel
..1.4 Sprachwahl
..1.5 Praxis
....1.5.1 Digital_IO
....1.5.2 Byteoperationen
....1.5.3 AVR_Studio
....1.5.4 Testboard
....1.5.5 Aufgaben
....1.5.6 Do_it_yourself
......1.5.6.1 Ampel
......1.5.6.2 Programmierer
..1.6 Literatur
..1.7 Programmierer
....1.7.1 Bauverlauf
....1.7.2 KurzreferenzLow
....1.7.2 Kurzreferenz_16PU
..1.8 Uebung1
..1.9 BoardAtHome
....1.9.1 Software
....1.9.2 Hardware
....1.9.3 Knoppix
....1.9.4 Aufbau
....1.9.5 LED
2 Oszillator
..2.1 Assembler
..2.2 Interner_RC
..2.3 Quarz
..2.4 Taktgenerator
3 DigitalIO
..3.1 Elektrische_Eigenschaften
..3.2 Pullup_Widerstaende
..3.3 Bitmasken_Eingang
..3.4 Bitmasken_Ausgang
..3.5 Tic_Tac_Toe
....3.5.1 DuoLEDs
....3.5.2 Schaltplan
....3.5.3 Spielfeld
....3.5.4 Anwahl
....3.5.5 Kontrolle
..3.6 Laboruebung2
..3.7 Laboruebung2_alt
4 PWM
..4.1 Prinzip
..4.2 Nutzen
..4.3 Generierung
..4.4 Programmierung
..4.5 Servos
..4.7 Laboruebung3
..4.8 LoesungUE3
..4.9 Uebung6
5 LichtKlangKugeln
..5.1 LED
..5.2 RGB
..5.3 Sensoren
..5.4 lautsprecher
..5.5 tonerzeugung
6 UART
..6.1 Bussysteme
..6.2 UART
..6.3 RS232
..6.4 Hardware
..6.5 Senden
..6.6 Hyperterminal
..6.7 Empfangen
..6.8 Broadcast
..6.9 Uebung4
7 Infrarot
..7.1 schalten
..7.2 seriell
..7.3 Uebung
8 OOP
..8.1 Probleme
..8.2 Konzept
..8.3 Statisch
..8.4 Datentypen
..8.5 RS232
....8.5.1 Prozedural
....8.5.2 Analyse
....8.5.3 Umsetzung
....8.5.4 Vererbung
....8.5.5 Statisch
....8.5.6 Performance
..8.6 Fahrzeug
9 ADW
..9.1 ADW
..9.2 Zaehler
10 Peripherie
..10.1 RS232Menue
..10.2 ASCIIDisplay
..10.3 Tastenmatrix
..10.4 Schrittmotor
..10.5 Zaehler
..10.6 Uebung7
11 SPI
..11.1 Testanordnung
..11.2 Register
..11.3 Test1
..11.4 Test2_Interrupt
..11.5 Test3_2Slaves
..11.6 Laboruebung
12 EEPROM
13 I2C
..13.1 MasterSendByte
..13.2 MasterSend2Bytes
..13.3 MasterReceiveByte
..13.4 MasterReceive2Bytes
14 Anwendungen
..14.1 Mechatroniklabor
....14.1.1 Biegelinie
....14.1.2 Ausbruchsicherung
....14.1.3 Einachser
....14.1.4 AV
....14.1.5 Vierradlenkung
....14.1.6 Kommunikation
..14.2 Sinuserzeugung
....14.2.1 Variante1
....14.2.2 Variante2
....14.2.3 Variante3
....14.2.4 Variante4
..14.3 Laboruebung8
..14.4 Loesung_Ue8
..14.5 SPI_Nachtrag
20 Xubuntu

11.4 Testprogramm 2 - Verwendung eines Interrupts bei Slave 1

  • Das folgende Programm erfüllt die gleiche Aufgabe wie Testprogramm 1.
  • Am Quellcode für den Master wird auch gar nichts geändert.
  • Beim Slave 1 - Quellcode wird die Warteschleife durch Verwendung eines Interrupt-Mechanismus ersetzt.
  • Durch die Funktion sei() wird die Interrupt-Fähigkeit des Mikrocontrollers aktiviert.
  • Durch Setzen des Bits SPIE im Register SPCR wird der Interrupt der SPI-Schnittstelle aktiviert.
  • In diesem Fall bewirkt die Aktivierung der Interruptfähigkeit, dass jedesmal wenn über SPI ein Byte vollständig empfangen und parallel gesendet wurde, automatisch das Hauptprogramm in der main-Methode verlassen wird und die Funktion SIGNAL(SIG_SPI) aufgerufen wird.
  • Anstatt also ständig das Flag SPIF zu beobachten, um einen Datentransfer nicht zu verpassen, sorgt nun der Interrupt dafür.
  • Damit ist das Hauptprogramm offen dafür andere Aufgaben zu bewältigen, solange kein Datentransfer stattfindet.
  • Nach Ausführen der Funktion SIGNAL(...) springt der Programmzähler wieder genau an die Stelle, an der die Abarbeitung des Hauptprogramms unterbrochen wurde und die zum Unterbrechungszeitpunkt vorliegende Belegung der Arbeitsregister wird wieder hergestellt.
  • Erst durch die Verwendung des Interrupt-Mechanismus, kann der SPI-Bus wirklich sinnvoll eingesetzt werden.
#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 11.4-5: Quellcode für Slave 1 in Testprogramm 2 (Quellcode für Master wie bei Testprogramm 1)

spi4_mitInterrupt_slave1.zip - Projekt zu Testprogramm 2