Schaltung
Programmieren in C
Programmablauf
Der PIC-Typ
Mit einem Port LEDs
ansteuern
Konfiguration des
PIC
Warteschleife
Das Blinken
Das gesamte Programm
- Download
Wer
anstelle des
großen 18F8720 lieber den kleinen 18F242 benutzen möchte,
der
wechsle bitte auf dieses
Beispiel.
Das Pin RD0 des Port D wird mit einer Leuchtdiode versehen, die über 1 kOhm mit Masse verbunden ist. Damit zeigt die LED den Pegel des Bits 0 von PORTD an. Es eignet sich dafür das PIC18F-TQFP-Demo-Board. |
Programmieren in C
Eine allgemeine
Einleitung
für
das Programmieren in C steht an anderer Stelle.
Auch ist dieses Programmbeispiel
im
Zusammenhang mit dem C18 noch einmal erläutert worden.
Programmablauf
Um am RD0 eine LED blinken zu lassen,
muss man:
Der PIC-Typ
Beim Anlegen
des Projektes in MPLAB stellt man den PIC-Typ ein. Will man aber
später
im Programm die aus dem Assembler gewohnten Bezeichner verwenden (z.B.
TRISD, PORTD ...) dann muss man noch das zum PIC gehörende
Header-File
einbinden.
... /** I N C L U D E S **********************************************************/ #include <p18cxxx.h> ... |
Für den PIC18F8720 wäre das
z.B.
p18f8720.h. Die Datei p18cxxx.h erledigt das automatisch. Sie
prüft,
welcher Prozessortyp im Projekt ausgewählt wurde, und bindet dann
selbständig das dazu passende C-Header-File ein. Ich hätte
aber
auch schreiben können:
#include <p18f8720.h>
Ob man spitze Klammern oder
Anführungszeichen
benutzt ist übrigens egal.
Mit einem Port
LEDs
ansteuern
(hier
ist
eine
detaillierte Beschreibung der I/O-Pins)
Port-Pins sind entweder als Eingänge
oder als Ausgänge nutzbar. Nach dem Einschalten des PIC (oder
einem
Reset) sind alle Port-Pins als Eingänge konfiguriert. Um sie als
Ausgänge
nutzbar zu machen, muss man sie zunächst auf die Ausgangsfunktion
umschalten. Dazu muss man bestimmte Steuerbits setzen bzw.
löschen.
Jedes Port-Pin hat so ein Steuerbit. Ist es auf '1' gesetzt, dann
funktioniert
das Pin als Eingang, ist es aber auf '0' gesetzt, so ist es ein
Ausgang.
Die 8 Steuerbits für das PortD sind die 8 Bits des Registers
TRISD.
Für RD0 ist das Bit0 von TRISD verantwortlich.
Mit dem Befehl LATD = 0x00
schreibt
man 0 in das PortD. Man hätte genauso gut PORTD = 0x00
schreiben
können.
Anschließend mache ich RD0 zu einem
output-Pin, indem ich das Bit 0 des Registers TRISD auf 0
setze.
... LATD = 0x00; TRISD = 0xFE; ... |
Konfiguration
des
PIC
Ich möchte folgende
Konfigurationseinstellungen
im HEX-File abspeichern
... /** Configuration ********************************************************/ #pragma config OSC = HS //CPU=20 MHz #pragma config PWRT = ON #pragma config BOR = OFF #pragma config WDT = OFF //Watchdog Timer #pragma config LVP = OFF //Low Voltage ICSP ... |
Die #pragma-Direktive sagt dem Compiler, wohin im PIC das Folgende geschrieben werden soll. In diesem Fall handelt es sich also um Configurations-Einstellungen. Microchip hat die Vorgehensweise beim Einfügen von Configurationsdaten in den Quelltext überarbeitet. Das alte Verfahren sollte für die PIC18-Typen nicht mehr benutzt werden. Dafür gibt es jetzt für jeden PIC eine Reihe von Configurationseinstellungen, die im Dokument PIC18-Config-Settings-Addendum_51537d.pdf aufgelistet sind. Dieses Dokument wird bei der Installation von C18 in das doc-Unterverzeichnis geschrieben.
Warteschleife
Zum Blinken muss man die LED ja nur
an- und ausschalten. Dazwischen muss man aber etwas Wartezeit einlegen,
damit das menschliche Auge überhaupt das Blinken wahrnehmen kann.
Dafür
braucht man eine Wartezeit-Routine - eine Warteschleife. Die
könnte
man natürlich schnell programmieren, aber das wäre
Zeitverschwendung.
Zum C18-Compiler gehören einige Bibliotheken mit fertigen
Funktionen.
Darunter sind auch Warteschleifen, die in der delay-Bibliothek
enthalten
sind.
Damit C18 diese Bibliothek verwenden kann,
müssen wir sie dem Projekt hinzufügen. Dazu bindet man die
Header-Datei
der Bibliothek mit einer include-Direktive in das Programm ein. Dieser
Include-Befehl muss vor dem ersten Aufruf der Warteschleifenroutine
stehen.
... /** I N C L U D E S **********************************************************/ ... #include "delays.h" // für die Warteschleife ... |
Wir benutzen die Funktion Delay10KTCYx()
aus der delay-Library. Da wir am Programmanfang die Header-Datei dieser
Library eingebunden haben, kennt der Compiler diese Routine, und ihren
Übergabeparameter. Die delay-Library ist eine fertig compilierte
Lib-Datei
im lib-Unterordner.
Die Funktion Delay10KTCYx() ist
eine Warteschleife, ihre Laufzeit ist 10000 Zyklen x
übergebenem
Wert. Da wir 100 als Wert übergeben, ergibt sich eine Laufzeit
von 100x10000=1000000 Zyklen. 1 Million Zyklen sind 4 Millionen Takte.
Bei 20 MHz Takt ergibt sich 1/5 Sekunde Wartezeit.
... Delay10KTCYx(100); ... |
Zum Blinken benötigen wir eine
Endlosschleife.
Die lässt sich mit einer While(1)-Schleife leicht realisieren.
Mit LATD=1 wird die LED
eingeschaltet
und mit LATD=0 wieder ausgeschaltet. Dazwischen rufe ich
die
Warteroutine auf.
... while(1) { LATD = 1; Delay10KTCYx(100); LATD = 0; Delay10KTCYx(100); }//end while }//end main |
Das war's auch schon. Die LED blinkt.
Das gesamte Programm - Download
Folgendes kleine Progrämmchen lässt also eine LED am Pin RD0 blinken.
Im folgenden Listing ist echter Code ist grün. Alle Kommentare habe ich grau eingefärbt./** I N C L U D E S
**********************************************************/
#include <p18cxxx.h> #include "delays.h" // für die Warteschleife /** Configuration
********************************************************/ /** D E C L A R A T I O N S
**************************************************/ while(1) |
Autor: sprut
erstellt: 24.03.2006
letzte Änderung 24.03.2006