Wiedereinschaltung des Beifahrerairbags
     

Problembeschreibung
Schriftliche Problemlösung
Technische Aspekte zur Problemlösung
Grafische Problemlösung (PAP)
Interrupt0 + register shown (Master-Shit)
Interrupt des Atmega 8
Quelltext
Serielle Datenübertragung vom Board zum PC - Ausblick

inhalt

ownd by Lindner



inhalt
Problembeschreibung

Drucksensoren im Beifahrersitz melden Änderungen der aktuellen Belegung der Sitzfläche, z. B. das Herausheben des Babysafes.

In diesem Falle soll sich der Airbag automatisch wieder einschalten.
Dem Fahrer wird der Zustandswechsel angezeigt.

  
Bildquelle:Römer
  ownd by Lindner



inhalt
Schriftliche Problemlösung

Eine rote Leuchtdiode zeigte den Status des deaktivierten Airbags an. Das Programm wurde an dieser Stelle mit einer while ( 1 )- Schleife
"festgehalten" - es würde somit "unendlich" weiterlaufen.

Der durch den Sensor angezeigte Lastwechsel soll dieses Programm unterbrechen, den Airbag aktivieren und den wieder eingeschalteten Zustand des Airbags mit einem dreimaligen Blinken derselben roten Leuchtdiode quittieren.

Derartige Programmunterbrechungen werden mit so genannten Interrupts bewerkstelligt. Das Schließen des Ports D2 mit dem zweiten Taster löst den hardwaremäßigen Interrupt0 aus. Das zur Zeit laufende Programm wird sofort unterbrochen und das Interrupt-Unterprogramm (ISR Interrupt Service Routine) abgearbeitet, hier das Unterprogramm SIGNAL (SIG_INTERRUPT0), das die LED dreimalig blinken läßt.
Nach Abarbeiten des Interrupt-Unterprogrammes wird das Programm an der Stelle weitergeführt, wo es verlassen wurde.

Tipps:
 - Wikipedia
 - Sicherheitsschaltung mit Not-Aus über Interrupt - ELI05
 - Vorüberlegung zum Interrupt

  
 Kleine Krawczyk



inhalt


Technische Aspekte







Der Eingabe soll wiederum über einen der Taster erfolgen. Damit ist für den gewählten Port der Pull-Up-Widerstand zu aktivieren. Die Ausgabe erfolgt an eine LED. Bei offenem Taster liegt an Port D.2 ein High-Pegel ( Pull Up, logisch 1 ) an. Wird der Taster geschlossen, zieht er den Pegel auf Low ( logisch 0 ). Wird der Taster losgelassen, öffnet dieser sich und der Pegel geht wieder auf High ( Pull-Up, logisch 1 ).







Der LO-Pegel löst fortlaufend Interrupts aus
ISCx0/x1
=00
Jede Pegeländerung löst einen Interrupt aus
ISCx0/x1
=01
Die fallende Flanke löst einen Interrupt aus
ISCx0/x1
=10
Die steigende Flanke löst einen Interrupt aus
ISCx0/x1
=11


Weiterer hilfreicher Links zu Interrupts.
 Franzen Kneip



inhalt

Interrupt0 - verwendete Register

-----------------------> Link <------------------------

 

Interrupt0 - verwendete Register

-----------------------> Link <------------------------

  
 Permesang Spang
Interrupts des Atmega 8

Der Atmega 8 hat mehrere Interrupts. Die können sie hier nachlesen.
  
 Diwo Pfeifer

inhalt

Grafische  Problemlösung - Programmablaufplan
Zum Downloaden des PAP [->HIER<-] klicken. 
(Download als*.pdf)
Zum Downloaden des PAP [->HIER<-] klicken. 
(Download als*.odg)


[zum Vergrößern aufs Bild klicken!]
 
  
 Bach Lauten ...

Schriftgröße an das Seitenlayout anpassen: 

eventuell anschaulicher?

(Komplette Beschreibung von Anfang bis Ende)

Mainfunktion

Der Motor startet, anschließend werden die Ports und der Interrupt0 initialisiert.

Der User drückt den Taster und die while Schleife zählt bis die 2 Sekunden Wartezeit vom Taster erreicht sind.

µController: Der Taster wird noch mal abgefragt.

µController: Jetzt schaltet der Kontroller die LED an.

Die LED leuchtet nun durchgehend, wegen der while (1) Schleife.

        Wartefunktion

Der Interrupt wird gestartet.

Die Zählschleife wird abgefragt.

Wenn der Taster länger als 2s gedrückt wird, wird die Funktion gestartet, wenn nicht wird die Funktion abgebrochen.

Die LED wird angeschaltet und bekommt den Befehl 2s in diesen Zustand zu bleiben.

Jetzt wird die LED ausgeschaltet und bekommt ein Befehl in diesem Zustand 2s zu verbleiben.

Danach wird eine while -Schleife gestartet, welche diesen Vorgang noch zweimal wiederholt, bevor die LED im Zustand „off“ verbleibt.

Interruptfunktion


Nachdem die Funktion „Warte“ im Hauptprogramm aufgerufen wurde, startet diese.

Die Zählvariable wird zunächst auf ihren Startwert i = 1 gesetzt.

Nun folgt die Abfrage ob i kleiner dem Endwert ist. Dieser ist in der While-Schleife der Funktion definiert.
Mit der Operation i++ wird die Zählvariable bei jedem Durchlauf der Schleife um Eins erhöht.
Dies wird so lange wiederholt bis der Endwert erreicht ist.

Nun springt das Programm aus der Schleife (False → Ende) und führt die Main-Funktion fort.


 

  
 Jajo Broll Quenteux
inhalt
Quelltext

bitte kein Fett, Kommentare in grün formatiert

"dauerhaftes Drücken" des Tasters sicherstellen!!!

#include <avr/io.h>                           // Einbinden der Headerdatei io.h
#include <avr/interrupt.h>                    // Einbinden der Headerdatei interrupt.h    
#include <avr/signal.h>                       // Einbinden der Headerdatei signal.h   

#define time 167504                           // time wird als 167504 Einheiten definiert          


                                    



long i;                                       // Festlegung des Datentyps long

warte_2sec (  long endwert  )                 // Wartefunktion wird deklariert; Variable = Endwert

               
{
    for ( i  =  0 ; i < endwert ;  i++)       // Festlegen der Zählerschleife          
    {   if ( bit_is_clear ( PINC,3 ) )        // Tasterabfrage noch gedrückt?
        {
            asm volatile ( "nop":: );         // "tue nichts" bis Endwert erreicht ist
        }          

    }

}                     

warte_blink (  long endwert  )                // Wartefunktion wird deklariert; Variable = Endwert
               
{
    for ( i  =  0 ; i < endwert ;  i++)       // Festlegen der Zählerschleife          
    {   
        
        asm volatile ( "nop":: );             // "tue nichts" bis Endwert erreicht ist
                  

    }

}

SIGNAL (SIG_INTERRUPT0)                       // Starten der INTERRUPT 0 Befehle

{
    while (1)
    {
        PORTB   =   0b00000001;               // Port B0 auf 1 LED an
        warte_blink ( time );                 // warten für die für time definierte Zeit
        PORTB   =   0b00000000;               // Port B0 auf 1 LED an
        warte_blink ( time );                 // warten für die für time definierte Zeit
        PORTB   =   0b00000001;               // Port B0 auf 1 LED an
        warte_blink ( time );                 // warten für die für time definierte Zeit
        PORTB   =   0b00000000;               // Port B0 auf 1 LED an
        warte_blink ( time );                 // warten für die für time definierte Zeit
        PORTB   =   0b00000001;               // Port B0 auf 1 LED an
        warte_blink ( time );                 // warten für die für time definierte Zeit
        PORTB   =   0b00000000;               // Port B0 auf 1 LED an
        while (1)                             // Bedingung immer wahr... "tue nichts"
        {
             ;
        }
    }
}



main (  void  )                                                   
{
    DDRD    =   0b00000000;                   // Datenrichtung D2 auf Eingang
    PORTD   =   0b00000100;                   // Port D2 auf 1 (Pull up)

    GICR    =   0b01000000;                   // hex: 0x40; Interrupt 0 aktivieren (INT0 Bit 7);
    MCUCR   =   0b00000010;                   // hex: 0x02; fallende Flanke für Interrupt 0
    sei();



    DDRB    =  0b00000001;                    // Datenrichtung B0 auf Ausgang und B1 auf Eingang 
    PORTB   =  0b00000010;                    // Port B0 auf 0 Led aus; Port B1 auf 1 (Pull up Taster)  

       

    while ( 1 )                               // Bedingung immer wahr                  
    {                                                         

 
        if ( bit_is_clear ( PINB,1 ) )        // Erste Abfrage ob Taster gedrückt
        {
            warte_2sec ( time );              // Wartefunktion 167504 Einheiten ~ 2sec
            if ( bit_is_clear ( PINB,1 ) )    // Zweite Abfrage: Taster immer noch gedrückt?         
            {
                while (1)                     // Bedingung immer wahr kann nur durch Interrupt unterbrochen werden
                {
                    PORTB   =  0b00000001;    // Port B0 auf 1 LED an


                }
            }
           


                           
                                                  
                    
            }

       
    }
}




                    
 


 

  
 Krempel

 Serielle Datenübertragung vom Board zum PC - Ausblick

UART ist die Abkürzung für "Universal Asynchronous Receiver Transmitter".

Ein UART ist ein Kommunikationsbaustein in Mikrocontrollern oder Computern, der als eigenständiger Chip, als Teilfunktion in Chipsätzen oder in PLDs realisiert wird.

Er arbeitet als universeller asynchroner Sender und Empfänger, der die Datenumsetzung zwischen einem parallelen Bus und einer seriellen Schnittstelle vornimmt.

Bei der seriellen Datenübertragung werden Daten bitweise Übertragung. Dies setzt vorraus, dass bei Sender und Empfänger die selbe Übertragungsgeschwindigkeit eingestellt ist, sonst "verstehen" sie sich nicht.

baudrate
 
Beispiel für den Empfang von Daten mit dem Windows Programm " Hyperterminal"


Auf dem Atmega 8 wird die Übertragungsgeschwindigkeit über das Register UBRR ( UART Baud Rate Register) eingestellt.
Die optimale Baudrate lässt sich berechnen.



Der UART ermöglicht die Kommunikation zwischen einzelner Komponenten eines Embedded System , zwischen mehreren Mircocontrollern oder auch zuwischen Pc und Microcontroller.

Die Kommunikation zwischen Pc und Microcontroller ermöglicht z.B. die Auswertung und Darstellung von Messwerten. Dies kann z.B. mit Excel realisiert werden.

Excel Diagramm

Dateien mit Rechtsklick, "Ziel Speichern unter" herunterladen

Download der Hyperterminal Datei 

Download der Excel Datei