PIC-Lernbeispiel: Blink-LED

mit C18 und PIC18F8720

zurück zu 18F-Lernbeispiele , PIC-Prozessoren , Elektronik , Homepage


Eine blinkende LEDs am RD0
Das ist ein "Hello World"-Programm für den C18-Compiler.
 

Schaltung
Programmieren in C
Programmablauf
Der PIC-Typ
Mit einem Port LEDs ansteuern
Konfiguration des PIC
Warteschleife
Das Blinken
Das gesamte Programm - Download

zurück zu 18F-Lernbeispiele


Schaltung
 
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:

  1. PORTD auf 0 setzen
  2. RD0 in Ausgabe-Mode schalten
  3. RD0 auf "1" setzen (LED ist an)
  4. eine feste Zeit in einer Warteschleife warten
  5. RD0 auf "0" setzen (LED ist aus)
  6. eine feste Zeit in einer Warteschleife warten
  7. ab Schritt 3 wird alles wiederholt

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

All diese Einstellungen könnte man auch später im Brennprogramm P18 oder  US-Burn vornehmen, es ist aber bequemer, wenn sie schon im HEX-File stehen.
 
...
/** 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);
...


Das Blinken

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 ********************************************************/
#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
 

/** D E C L A R A T I O N S **************************************************/
#pragma code
void main(void)
{
  LATD = 0x00; 
  TRISD = 0xFE;

  while(1)
  {
    LATD = 1;
    Delay10KTCYx(100);
    LATD = 0;
    Delay10KTCYx(100);
  }//end while
}//end main
 


zurück zu 18F-Lernbeispiele , PIC-Prozessoren , Elektronik , Homepage

Autor: sprut
erstellt: 24.03.2006
letzte Änderung 24.03.2006