Bergwanderer
1 Infos Lauflicht
WLAN-Repeater

Bewegung tut uns Menschen gut. Sei es beim Wandern oder Joggen, Schuhe an und raus in die Natur, treu nach dem Motto: "Wer was tut, fühlt sich gut."

Heute wollen wir die LEDs in Bewegung setzten. In der Praxis tun wir das bspw. bei einer LED-Uhr oder wie hier bei einem WLAN-Repeater.

Denn unsere Augen sprechen auf Bewegung besonders an. Bei Hunden kann man das so schön beobachten, wenn sie eine Bewegung wahrnehmen, lange noch bevor wir reagieren und sie reflexartig aufstehen.

Dazu werden wir eine neue Programmierstruktur kennenlernen: die Funktionen. Sie werden immer dann eingesetzt, wenn Programmteile ausgelagert werden sollen.

2 Zeitablaufplan eines Lauflichts
Zeitablaufdiagramm Lauflicht

Wir starten mit der LED L1, warten 200 ms und schalten dann LED L3 wobei wir nicht vergessen dürfen LED L1 auszuschalten. Nach erneutem Warten von 200 ms schalten wir LED L5 u.s.w.

Eigentlich ganz einfach, jedoch müssen wir jedes mal die Wartezeit programmieren. Und spätestens hier wird es einem Programmierer zu langweilig und er sehnt sich nach einer intelligenten Programmierstruktur, welche ihm die lästige Wiederholungsarbeit abnimmt.

Genau dies machen Funktionen möglich. Durch einen einfachen Aufruf wird ein und derselbe Quelltext immer wieder abrufbar. Dadurch schaffen Funktionen Struktur und Übersichtlichkeit. Sie sind mehrfach verwendbar und ermöglichen die Aufteilung großer Projekte.

3 Funktionen in C
Struktogramm Funktionen

Hier sieht man den Programmausschnitt mit den mehrfachen Funktionsaufrufen:
DelayMS( 200 );

Die eigentliche Funktion mit dem Funktionsnamen DelayMS kann dann am Ende des Programms stehen. Hier hat sie einen Übergabewert (int zeit) und keinen Rückgabewert (void):
void DelayMS( int zeit ){
     int i, j;
     for( i=0, i<zeit, i++ ){
          for( j=0, j<459, j++);      }
 }

4 Einbinden von Headerdateien
Bibliotheken

Headerdateien ermöglichen das Auslagern von Funktionen in eigene Dateien. Typischerweise lagert man die Hardwarekonfiguration in eine solche Headerdatei aus. Dabei geht man folgendermaßen vor: Man legt im Projektverzeichnis die Headerdatei LIMExconfig.h und die zugehörige C-Datei LIMExconfig.c an. Einbinden tut man sie wie in der Abbildung gezeigt wird.

In der LIMExconfig.h schreibt man Makros und die sogen. Prototypen der Funktionen. Der Prototyp besteht aus der Funktionsdefinition gefolgt von einem Semikolon. Wirf doch mal einen Blick in die Dateien.

In der zugehörigen C-Datei schreibt man dann den Quelltext der Funktion. Kommentiert man in den Dateien die Funktion, erhalten alle Nutzer einen schnellen Überblick über deren Aufgabe.

5 Funktionen mit Rückgabewert
Limettenpresse

Stellen wir uns eine Zitruspresse als Funktion vor: Der Übergabewert - die Limette, die Funktion - Herstellung von Limettensaft und der Rückgabewert - Limettensaft. Vielleicht fällt Euch gar nicht auf, dass für den Limettensaft ein Behälter bereit steht, aber sobald ich einen Rückgabewert habe brauche ich auch dies beim Programmieren. Und hierfür verwenden wir eine Variable:
int wert;
 wert = rechnen ( 2 , 3 );

Die eigentliche Funktion sieht dann bspw. folgendermaßen aus:
int rechnen ( int a, int b ){
     return a+b;
 }



Aufgabe 1 Zeitverzögerungsfunktion

Skizze Lauflicht

In dieser Aufgabe wird das Lauflicht mit einer Zeitverzögerungsfunktion programmiert.

  1. Erstelle das Projekt 05 Lauflicht und schreibe die Datei 05-Lauflicht-1.c, in der ein Lauflicht mit den LEDs L1L6 programmiert wird. Dabei sollen die Funktion void DelayMS200( void ) ohne Rück- und Übergabeparameter zum Einsatz kommen, die eine exakte Zeitverzögerung von 200 ms erzeugt. Hinweis: Die exakte Zeitdauer kann man mit dem Oszilloskop nachmessen.
  2. Ergänze die Datei 05-Lauflicht-1.c, mit der Bibliotheksfunktion void DelayMS( unsigned int zeit ) mit Übergabeparameter. Diese Funktion erzeugt je nach Übergabewert eine unterschiedliche Zeitverzögerung. D.h. beim Aufruf von DelayMS(500); beträgt die Zeitverzögerung 500 ms, beim Aufruf DelayMS(200); beträgt die Zeitverzögerung 200 ms.
  3. Für Fortgeschrittene : Ergänze das Programm durch eine Funktion, der zwei Parameter übergeben werden und teste anstelle eines konkreten Wertes, die Übergabe mit dem Wert einer Variablen.
  1. ...
     while(1){
         L1=1, L3=0;
         DelayMS200();
         L2=1, L1=0;
         DelayMS200();
         ...
         L3=1, L5=0;
         DelayMS200();
     }

     void DelayMS200( void ){
         int i, j;
         for( i=0, i<200, i++ ){
              for( j=0, j<459, j++);      }
     }

  2.  void DelayMS( unsigned int zeit ){
         int i, j;
         for( i=0, i<zeit, i++ ){
              for( j=0, j<459, j++);      }
     }


Aufgabe 2 Einbinden von Headerdateien

Headerdateien

In dieser Aufgabe wird das Einbinden von Headerdateien trainiert.

  1. Schreibe die Datei 05-Lauflicht-2.c, in der du die Headerdateie LIME2config.h und LIME2config.c aus der Bibliothek untersuchst.
  2. Schreibe eine eigene Headerdatei test.h und test.c und binde diese ein.

Schieben von Bits

Bei Mikrocontrollern gibt es die Möglichkeit in 16bit-Registern oder Variablen einzelne Bits nach links zu verschieben. Da auf unserem Board die LEDs L1L5 am Pin B10 – B15 angeschlossen sind, lässt sich mit dieser Möglichkeit einfach ein Lauflicht programmieren. Wir starten in dem wir die LED L5 an Pin B15 einschalten und 200 ms warten.

Dann schieben wir dieses Bit eine Position nach links (L6 geht an) und warten erneut. Sind wir am Pin B15 (L2) angekommen, starten wir von vorne. Der Quelltext für das Verschieben sieht folgendermaßen aus: LATB <<= 1;.

Aufgabe 3 Schieben von Bits

Gletscher
  1. Schreibe die Datei 05-Lauflicht-3.c, in der du mit dem Schieben von Bits ein Lauflicht erzeugst. Hinweis: Die Reihenfolge der LEDs unterscheidet sich aufgrund der Verdrahtung von unserem bisherigen Lauflicht.
  2. Für Profis : Ergänze das Programm mit einer for-Schleife, mit der die Geschwindigkeit nach jeder LED geändert wird.

Aufgabe 4 Funktion mit Rückgabewert

Im Gegensatz zu den Übergabeparametern gibt es maximal einen Rückgabeparameter. Deshalb wird hier nur der Datentyp festgelegt.

Zitruspresse

In der Funktion int S0Check ( unsigned int m ) soll überprüft werden ob ein Taster betätigt wurde. Falls ja wird der übergebene Wert der Variable invertiert (m = !m;) und dieser Wert zurückgegeben. Man beachte, dass es nur einen Rückgabewert geben kann. Übergabewerte gibt es beliebig viele, man unterscheidet sie durch die angegebene Reihenfolge. Des weiteren werden die Werte beim Funktionsaufruf immer wieder neu kopiert.

Schreibe die Datei 05-Lauflicht-4.c, in der du das Lauflicht mit Tastendruck S0 aktivierst, bzw. deaktivierst. Nutze hierzu die Funktion
int S0Check ( int m ){
     …
 }
.


Aufgabe 5 Funktionstest

Teste dein Wissen über Funktionen. Welche Paare gehören zusammen?

1. int add(int a, float b, int c);
 
2. int add(float j, int i, int k);
 
3. int summe;
 summe=add(2, 3.2, 88);
4. add(3, 10.2, 7);
 
5. int summe, a, b;
 summe=add(3.4, a, b);
6. int add(int i, float y);
 
7. int summe;
 summe=add(2, 'a', 88);
8. double erg, x;
 erg=cos(x);
9. void add(void);
 
10. void add(int x, float y, int i);
 
11. int summe;
 summe=add(3, 10.2);
12. int add(int i, char j, int k);
 
13. char zeichen(void);
 
14. add( );
 
15. float mix(int mul, float y);
 
16. char laenge;
 laenge=zeichen( );
17. char platz;
&nbps;platz=suche('g',10);
18. void berechne(double v);
 
19. double cos(double x);
 
20. float k, e;
 e=mix(12,k);
21. berechne(3.78);
 
22. char suche(char art, int pos);
 


© mylime.info