Um die Übungen in diesem Tutorial nachvollziehen zu können benötigen wir folgende Hard- und Software:
Für die Programmierung von Microcontrollern ist es sinnvoll, dass wir uns vorerst einige Datentypen definieren, welche den Zugriff auf die verschiedenen Komponenten des Controllers vereinfachen oder wenigstens das Programm lesbarer machen können.
typedef unsigned char BYTE;
typedef unsigned short WORD;
Der Datentyp BYTE definiert eine Variable mit 8 Bit Breite zur Darstellung von ganzen Zahlen im Bereich zwischen 0 ... 255.
Der Datentyp WORD definiert eine Variable mit 16 Bit Breite zur Darstellung von ganzen Zahlen im Bereich zwischen 0 ... 65535.
Wir können aber auch die von der AVR-Umgebung des Compiler in der Headerdatei <inttypes.h> definierten Datentypen verwenden. Ich persönlich finde dieselben allerdings nicht sehr leserlich.
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef int int16_t;
typedef unsigned int uint16_t;
typedef long int32_t;
typedef unsigned long uint32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
typedef int16_t intptr_t;
typedef uint16_t uintptr_t;
Beim Programmieren von Microcontrollern muss auf jedes Byte oder sogar auf
jedes Bit geachtet werden. Oft müssen wir in einer Variablen lediglich den
Zustand 0 oder 1 speichern. Wenn wir nun zur Speicherung eines einzelnen Wertes
den kleinsten bekannten Datentypen, nämlich unsigned char, nehmen, dann
verschwenden wir 7 Bits, da ein unsigned char ja 8 Bit breit ist.
Hier bietet uns die Programmiersprache C ein mächtiges Werkzeug an, mit dessen
Hilfe wir 8 Bits in einer einzelnen Bytevariable zusammen fassen und (fast) wie
8 einzelne Variablen ansprechen können.
Die Rede ist von sogenannten Bitfeldern. Diese werden als Strukturelemente
definiert. Sehen wir uns dazu doch am besten gleich ein Beispiel an:
struct {
unsigned char bStatus_1:1; // 1 Bit für
bStatus_1
unsigned char bStatus_2:1; // 1 Bit für
bStatus_2
unsigned char bNochNBit:1; // Und hier noch
mal ein Bit
unsigned char b2Bits:2; //
Dieses Feld ist 2 Bits breit
// All das hat in einer einzigen Byte-Variable Platz.
// die 3 verbleibenden Bits bleiben ungenutzt
} x;
Der Zugriff auf ein solches Feld erfolgt nun wie beim Strukturzugriff bekannt über den Punkt- oder den Dereferenzierungs-Operator:
x.bStatus_1 = 1;
x.bStatus_2 = 0;
x.b2Bits = 3;
Wir unterscheiden zwischen 2 verschiedenen Methoden, um ein Microcontroller-Programm zu schreiben, und zwar völlig unabhängig davon, in welcher Programmiersprache das Programm geschrieben wird.
Bei dieser Programmiertechnik wird eine Endlosschleife programmiert, welche im Wesentlichen immer den gleichen Aufbau hat:
Bei dieser Methode werden beim Programmstart zuerst die gewünschten
Interruptquellen aktiviert und dann in eine Endlosschleife gegangen, in welcher
Dinge erledigt werden können, welche nicht zeitkritisch sind..
Wenn ein Interrupt ausgelöst wird so wird automatisch die zugeordnete
Interruptfunktion ausgeführt.
|