Selbstverständlich müssen in C genauso wie in Assembler (ASM) die Konfiguration für den PIC bestimmt bzw. eingestellt werden. Wenn dies vergessen wird, kann der Mikrocontroller / PIC nicht arbeiten. In diesem (letzten) Kapitel konzentrieren wir uns auf Aspekte der Sprache C die in direkte Beziehung zu unseren PIC Mikrocontrollern stehen.
Konfiguration
Nun unterscheidet sich die Einstellung der einzelnen Einheiten etwas. Hier ein beispiel wie Ihr in C, die Konfiguration für einen PIC vornehmen könnt:
#pragma config FOSC=HS // Taktbereich #pragma config PWRT=ON // Power on timer #pragma config BOR=OFF // Brown out reset #pragma config WDT=OFF // Watchdog timer #pragma config LVP=OFF // Low voltage progr. #pragma config MCLRE=ON // Master clear reset
Durch die Einleitung #pragma
weiß der Compiler, dass es sich um Konfigurationsinformationen für den Prozessor handelt. Natürlich könnt ihr das Konfigurationswort bzw. die Konfigurationsbits auch komfortabel über die IDE einstellen. Auf diese Weise müsst ihr euch mit der genauen Schreibweise nicht auseinandersetzen. So werden die Konfigurationsbits mit MPLABX erstellt (siehe auch separaten Artikel zur MPLABX IDE):
Eingänge / Ausgänge
Als nächstes ein Beispiel, wie ihr in der Sprache C Zustände von einzelnen GPIOs oder ganzen Ports einlesen und wie ihr Pins/Ports (Ausgang/Ausgänge) setzten oder löschen können:
// GPIO RA4 auf low setzen LATAbits.LATA4 = 0; // GPIO RA4 auf high setzen LATBbits.LATB0 = 1; // RB7 auf Eingang und den Rest auf Ausgang setzen TRISB = 0x80; // RB0 auf Eingang setzen TRISBbits.RB0 = 1; // Abfrage des vollständigen Port B if (PORTB == 0xFF) { //... } // Abfrage eines einzelnen GPIOs auf low if (PORTBbits.RB0 == 0); { //... }
Dabei darf man natürlich nicht vergessen die TRIS
Bits dementsprechend einzustellen. Wir erinnern uns, dass eine 1
im TRIS
Register den jeweiligen GPIO auf Eingang und eine 0
als Ausgang schaltet. Im obigen Beispiel seht ihr ebenfalls wie ihr die TRIS
Register beschreiben könnt.Dies ist ein Beispiel, wie man in Abhängigkeit vom Zustand eines Einganges den Programmablauf steuern kann!
Wann PORT und wann LAT?
Ein weiterer wichtiger Punkt ist zu wissen, wann man mit PORT
und wann mit LAT
arbeiten muss. Ganz kurz und knapp: LAT
bei Ausgängen und PORT
bei Eingängen. Wer sich noch etwas mehr mit den Vorteilen der LAT
Register beschäften möchte kann mal hier rein schauen.
Interrupts
PIC-Mikrocontroller unterscheiden zwei Interrupt Prioritäten: High
und low
. Wenn ihr einen Interrupt programmiert habt und ein entsprechendes Event diesen auslöst, so wird der PIC in die so genannte Interrupt-Service-Routine (ISR
) springen. Im Grunde genommen ist die ISR
eine spezielle Art Funktion. Diese wird enteggen normaler Funktionen jedoch nicht vom Programmierer selbstständig aufgerufen, sondern vom PIC selber, wenn ein entsprechendes Ereignis eintritt.
void __interrupt() highPrio (void) { // ... } void __interrupt(low_priority) lowPrio (void) { // ... }
Häufige Fehler
Hier entsteht eine Sammlung von Fragen mit Antworten, welche sehr häufig gestellt werden. Außerdem wird eine Liste mit Fehlern erstellt, welche immer wieder vorkommen.
GLEICH = ist nicht gleich GLEICH ==
Ein Fehler der immer wieder gern gemacht wird ist, dass man bei einem Vergleich das falsche Zeichen wählt. Ein einfaches geschriebenes =
Zeichen ist dafür da um z.B. Variablen einen Wert zu zuweisen aber nicht als Vergleichsoperator (==
), dies würde einen Syntax Fehler nach sich ziehen und das Compilieren beenden. Siehe:
Falsch:
if (A=B) {..} else {..}
Richtig:
if (A==B) {..} else {..}
Funktionen anmelden (Prototypen)
Eine Funktion muss bekannt sein bevor sie aufgerufen werden kann. Wir haben diese Notwendigkeit bereits zuvor im Kaptiel der Funktionen und Prototypen behandelt.
Falsch (Funktionsaufruf vor dem Funktionskopf):
void main (void) { function_a(); } void function_a (void) {..}
Richtig (Funktionsaufruf nach dem Funktionskopf):
void function_a(void) {..} void main (void) { function_a(); }
Oder aber man meldet Sie vorher an (Funktionsaufruf vor dem Funktionskopf aber nach dem Prototypen):
void function_a (void); void main (void) { function_a(); } void function_a (void) {..}
Schlusswort
Ich hoffe dieser kleine C Kurs hat euch etwas geholfen mit PIC-Mikrocontrollern und der Verwendung der Sprache C umzugehen. Sollten ihr dennoch Fragen haben zögert nicht diese über die Kommentarfunktion zu stellen. Jedenfalls wünsche ich euch nun viel Spaß beim Programmieren. Wenn ihr Fragen oder Probleme habt, kommt gerne im Forum vorbei 😉