Allgemeines 
- Download des Megacard Templates
Die Verwendung der Hardwareabstraktion (kurz HAL für engl. Hardware Abstraction Layer) wird im folgenden erläutert.
Folgende Hardwareeinheiten werden von der HAL angesteuert:
- LEDs (Port C)
- Taster S0-S3 (Port A0..3)
- Lautsprecher (Port A4)
- Timer0 für 800 Mikrosekunden Basis
- Timer1 für Soundausgabe
- LCD (Port A und Port B)
Die globale Interruptfreigabe wird bei der Initialisierung gesetzt (mittels sei()).
Ansteuerung der LEDs 
Zur Ansteuerung der LEDs gibt es zwei Funktionen.
Einzelne LED steuern 
void hal_led_set(uint8_t index, uint8_t value);
indexwählt die gewünschte LED aus (zwischen0und7)- Ist
indexgrößer 7 wird der Zustand der LEDs nicht verändert valueschaltet bei dem Wert0die LED aus, bei jedem anderen Wert ein
Alle LEDs steuern 
void hal_leds_set(uint8_t value);
- Der 8 Bit Wert
valuegibt das Muster vor, mit dem die LEDs leuchten sollen (z.B. 0xFF für alle ein)
Auswerten der Tasten 
Die Tasten S0 bis S3 werden durch die Hardwareabstraktion automatisch entprellt.
uint8_t hal_key_get();
- Diese Funktion gibt
0zurück, wenn keine Taste gedrückt wurde - Der Rückgabewert ungleich
0beschreibt die Taste, die gedrückt (genauer losgelassen) wurde - Wurden mehrere Tasten gleichzeitig losgelassen, wird beim ersten Aufruf die niedrigste Nummer zurückgegeben, danach die nächsthöhere usw.
Ausgabe von Tönen 
Zur Ausgabe von Tönen wird innerhalb der HAL der Timer 1 verwendet.
void hal_sound_play(uint16_t frequency);
- Die Frequenz wird über
frequencyin Hertz angegeben - Um die Ausgabe abzuschalten wird als Argument für
frequency0verwendet
Timerabstraktion 
Allgemeines 
Ein großer Teil der Funktionen innerhalb einer Anwendung sind durch Zeiten definiert. Da die Anzahl an hardwarebasierten Timern begrenzt ist müssen Timer mehrfachverwendet werden. Innerhalb der Hardwareabstraktion wird ein Timer verwendet, um für die Applikation beliebig viele abstrahierte Timervariablen zur Verfügung zu stellen.
Alle verwendeten Timervariablen werden in einem Array über Zeiger registriert. Die Timervariablen werden durch die Applikation auf eine gewünschte Zeit gesetzt (in Mikrosekunden). Die Hardwareabstraktion zählt diese Timervariablen entsprechend der vergangen Zeit herunter, bis sie schlussendlich auf 0 angekommen sind.
Verwendung 
Die Applikation kann die Timervariable auswerten, um zu überprüfen, ob die gewünschte Zeit bereits vergangen ist. Ist der Wert ungleich 0 ist die Zeit noch nicht vergangen.
Es gibt drei Makros, um das Setzen der Variable auf die gewünschte Zeitdauer lesbarer zu machen:
TIMER_MSEC(val)multipliziert den Wert mit Tausend (entspricht dann Millisekunden)TIMER_SEC(val)multipliziert den Wert mit einer Million (entspricht dann Sekunden)TIMER_MINUTE(val)multipliziert den Wert mit einer sechzig Million (entspricht dann Minuten)
Das folgende Beispiel zeigt die Verwendung:
#include "hal.h" timer_var_t timer_app=TIMER_SEC(3); void app_process(void) { if (timer_app) { return; // Zeit ist noch nicht abgelaufen } // ... }
Wird ein Timer nicht verwendet, gibt es den speziellen Wert TIMER_DISABLED (entspricht dem Wert -1). Damit wird signalisiert, dass die Timervariable im Moment nicht genutzt wird.
Registrierung 
Um die Timer in der Applikation zu registrieren wird das Makro TIMERS verwenden. Es ist im Template bereits in der Datei main.c vorbereitet.
Angenommen es gibt zwei Timer: timer_led und timer_off. Dann werden diese wie folgt registriert:
TIMERS(&timer_led, &timer_off);
LC Display 
Löschen der Anzeige 
Beim Löschen der Anzeige werden alle Zeichen des 8x2 Displays gelöscht (genauer gesagt wird überall ein Leerzeichen ausgegeben).
void hal_lcd_clear(void);
Ausgabe eines Textes 
void hal_lcd_printf(uint8_t line, uint8_t pos, char *fmt, ...);
linegibt die gewünschte Zeile an (0 oder 1)posgibt die gewünschte Position an (zwischen 0 oder 7)- Sind
lineoderposaußerhalb des Bereichs wird am Displayinhalt nicht verändert fmtund falls erforderlich die nachfolgenden Argumente entsprechen der Verwendung vonprintf
Folgende Platzhalter sind definiert:
%dgibt einen (16Bit) Integer mit Vorzeichen als Dezimalzahl aus%ugibt einen (16Bit) Integer ohne Vorzeichen als Dezimalzahl aus%xund%Xgeben einen (16Bit) Integer als Hexadezimalzahl aus (%xgibt Buchstaben als Kleinbuchstaben aus)%cgibt ein einzelnes Zeichen aus%sgibt einen String aus%%gibt das Prozentzeichen aus
Es kann auch eine fixe Breite definiert werden, so werden bei %4d vier Stellen reserviert. Ist die auszugebende Zahl von der Breite her kleiner werden links Leerzeichen eingefügt. Um 0 einzufügen wird eine 0 beim Platzhalter eingefügt: %04d.
Beispiele 
hal_lcd_printf(0, 0, "Test"); // gibt "Test" aus hal_lcd_printf(0, 0, "%d", -117); // gibt "-117" aus hal_lcd_printf(0, 0, "%3dX%3d", 2, 17); // gibt " 2X 17" aus
Die Ausgabe von Floatzahlen wird nicht direkt unterstützt, es kann aber emuliert werden:
float temperature=27.82; hal_lcd_printf(0, 0, "%d.%02d", (int16_t)temperature, (int16_t)((temperature*100)%100)); // gibt "27.82" aus
Alternativ kann in solchen Fällen auch ganz auf Float verzichtet werden, indem man einfach mit Integer in entsprechender Dezimaldarstellung rechnet. In diesem Beispiel wird statt in Grad Celsius in 1/100 Grad Celsius gerechnet
int16_t temperature=2782; // entspricht 27.82 Grad Celsius hal_lcd_printf(0, 0, "%d.%02d", temperature/100, temperature%100); // gibt "27.82" aus