Inhaltsverzeichnis
- 1 Was ist ein Mikrocontroller?
- 2 Grundlagen
- 3 Hardware und Module
- 4 Interrupts
- 5 Das Konfigurationswort
- 6 Gut zu wissen
- 7 Schlusswort
- 8 Siehe auch
Was ist ein Mikrocontroller?
Ein Mikrocontroller ist im Grunde genommen ein kleiner PC. Und hier bedeutet klein, dass sich alles auf einem einzigen Chip befindet. Die Komponenten reichen von der CPU an sich über digitale sowie analoge Ein- und Ausgabe bis hin zu Timern/Countern und weiteren Hardware-Modulen. Außerdem ist alles wesentlich kleiner ausgelegt als man es von einem normalen PC gewohnt ist. So stehen einem Mikrocontroller natürlich keine GByte oder gar TByte an Speicher zur Verfügung. Ein Mikrocontroller befindet sich eher im Bereich von KByte. Aber das ist auch in Ordnung, da wir weder ein großes Betriebssystem noch irgendwelche großen “Programme” auf dem Controller laufen lassen. Ihr werden schnell feststellen, dass selbst die “wenigen” KByte eines Mikrocontrollers ganz schön viel sind und für eine ganze Menge Algorithmen ausreichen.
Das Foto zeigt beispielhaft ein Raspberry Pi 2 mit einem ARM Cortex
Wofür braucht man Mikrocontroller?
Der Verwendungsbereich für Mikrocontroller ist immens. Mikrocontroller sind aus unserer Welt nicht mehr weg zu denken. Heut zu Tage ist in fast jedem elektronischem Gerät ein oder sogar mehrere µC verbaut. Nur um mal ein paar Beispiele zu nennen: Toaster, Mp3-Player, Backofen, Handy, Kamera und noch vieles mehr.
Man kann mit µC viele Aufgaben erledigen, die sonst einen sehr großen Aufwand an entsprechend logischen Bauteilen hätten (vgl. diskreter oder gar analoger Aufbau). Daher verwenden wir Mikrocontroller für Steuerungen und Regelungen jeglicher Art. Das Foto (siehe oben) zeigt zum Beispiel einen Quadrocopter. Auch dieser wird selbstverständlich von einem Mikrocontroller gesteuert.
Was brauche ich alles
Um mit Mikrocontrollern, speziell PIC-Mikrocontrollern, arbeiten zu können, müsst Ihr ein paar Anschaffungen im Vorfeld tätigen. Dieses Tutorial beschäftigt sich mit Mikrocontrollern der Firma Microchip. Dabei liegt der Fokus vor allem auf der PIC18F-Familie, später dazu mehr.
Entwicklungsumgebung
Als Entwicklungsumgebung bezeichnen wir eine Art Texteditor, der uns beim Schreiben unserer zukünftigen Programme unterstützt. Sie werden auch als IDE (integrated development environment) bezeichnet. Es bietet sich für PIC Mikrocontroller besonders das Programm MPLABX IDE an. Die Software stammt direkt vom Chip-Hersteller Microhip und ist kostenlos verfügbar. In dieser IDE können Programme zum Beispiel in Assembler oder C geschrieben und mit einem Programmiergerät direkt in den PIC übertragen werden. Die folgende Grafik zeigt das Arbeitsfenster der Software. MPLAB X ist sowohl für Windows als auch für Linux und Mac OS erhältlich.
Ich habe für die Entwicklungsumgebung einen eigenen kleinen Artikel geschrieben, der Euch durch die ersten Schritte (Projekt anlegen, Dateien erzeugen, …) leitet.
Wenn Ihr beabsichtigt nur in Assembler (kurz ASM) zu programmieren müsst Ihr euch lediglich die IDE (MPLABX) herunterladen. Die Software ist direkt auf der Homepage von Microchip zu finden (siehe Link). Wenn Ihr die PICs hingegen in C programmieren wollt, so empfehle ich euch den Compiler XC8 zu benutzen. Hierbei handelt es sich um eine zusätzliche Software, die Ihr auf eurem PC installieren müsst. Die Reihenfolge spielt dabei keine Rolle. Der Compiler sorgt später dafür, dass das von euch erstellte C-Programm so übersetzt wird, damit es (nach einer We iterverarbeitung durch den Assembler) vom Mikrocontroller verstanden wird. Auch zu diesem Compiler findet Ihr einen kurzen Artikel, der vor allem Umsteigern von anderen Compilern dabei hilft Unterschiede zu finden.
Programmiergerät
Wenn Ihr ein Programm fertig geschrieben habt wird aus dessen Datei(n) eine HEX-Datei in Maschinensprache generiert. Diese hat dann die Dateiendung *.hex. Es handelt sich um eine Datei in der lauter Zahlen enthalten sind, denn nur diese Sprache versteht ein Computer bzw. Mikrocontroller. Und diese Hex-Datei muss schlussendlich in den PIC hinein. Diesen Vorgang bezeichnet man im Allgemeinen als brennen oder auch flashen. Das nachfolgende Foto zeigt ein Modul (das PICKit3 ), welches diese Aufgabe erledigen kann.
Euer Programm wird in den Speicher des PIC geschrieben. Ich empfehle Euch das PICKit3 (vgl. Foto). Es handelt sich hierbei um einen Brenner und Debugger in einem. Das bedeutet Ihr könnt nicht nur das Programm (Hex-Datei) in den PIC laden, sondern auch noch euren PIC in der fertigen Schaltung debuggen (Haltepunkte im Programmcode setzten und Variablen auslesen). Das ist beim Entwickeln von Software ein ganz wesentlicher Bestandteil und hilft extrem bei der Fehlersuche. Das PICKit3 ist das Tool für Einsteiger und Fortgeschrittene (sehr gutes Preis/Leistungsverhältnis*). Ein weiterer nicht zu unterschätzender Vorteil des PICkit3 ist, dass es zu 100% von MPLABX unterstützt wird. Sprich das Schreiben und das Brennen geschieht alles innerhalb von MPLABX und benötigt keine weitere Software.
* Zuletzt ließen sich große Preisschwankungen feststellen. Stand 2015 kostet das PICKit3 ca. 50€. Es war zwischenzeitlich für auch mal für 30…40€ zu bekommen. Vermutlich liegt das am aktuell schwachen Euro. Es lohnt sich also definitiv mal ein Blick auf eBay!
Mikrocontroller
Neben den ganzen bereits erwähnten Tools benötigt Ihr benötigt natürlich auch noch den PIC (Mikrocontroller) selber. Wie ich schon weiter oben erwähnt habe, würde ich euch für den Einstieg zum Programmieren in C die PIC18F empfehlen. Warum das so ist hat mehrere Gründe, doch vor allem, da es wesentliche Verbesserungen im Vergleich zu den PIC16F-Modellen gibt.
Wenn Ihr jedoch zunächst mit Assembler arbeiten möchtet um z.B. die “Innereien” des Controllers besser kennen zulernen, dann könnt Ihr auch mit den PIC16F anfangen (in dem Fall solltet Ihr die Webseite von Sprut unbedingt besuchen, da er besonders mit Assembler arbeitet). Als Bezugsquelle kann ich euch das Versandhaus Reichelt empfehlen.
Motivation
Zu guter Letzt eine ordentlich Portion Motivation. Es kann durch aus schon mal vorkommen, dass es mehrere Tage dauert bis ein Programm so arbeitet, wie Ihr euch das vorgestellt habt. Und das kann mitunter auch ganz schön Nerven kosten 🙂 Manchmal sind es die einfachsten Dinge die man wieder und wieder vergisst. Doch dann ist es um so schöner, wenn das Programm an Ende funktioniert 🙂 Man findet beim Stöbern im Internet immer wieder sehr interessante Projekte, die mit Hilfe von Mikrocontrollern umgesetzt wurden. Insofern sollte die Motivation euer kleinstes Problem sein 😉
Tipp für Anfänger
Wer es besonders einfach und schnell haben möchte, kann sich auch ein so genanntes Starterkit kaufen und sofort mit dem Programmieren loslegen. Diese Variante bietet sich besonders an, wenn Ihr zum Beispiel (noch) nicht die Möglichkeit habt zu Hause zu löten bzw. keine oder nur sehr wenig Grundlagen zur Elektrotechnik habt, die den Aufbau von mehr oder weniger komplizierten Schaltungen verhindern. Nachfolgend mal eine Auflistung verschiedener Entwicklungsboards:
- Ready for PIC von MikoElectronika*
- PIC18F Starterkit von Microchip
- PICKit3 Debug Express von Microchip
* Mit unter 30€ sehr günstig und ist für gewöhnlich sehr gut dokumentiert. Standardmäßig (Dokumentation, Beispielprogramme, …) wird hier mit einem anderen C-Compiler gearbeitet.
Meine Empfehlung
Gerne möchte ich Euch noch ein weiteres Einsteigerboard vorstellen, das StartPIC18. Beim StartPIC18 handelt es sich um ein von mir entwickeltes Enwticklungsboard für Anfänger und Fortgeschrittene.
In dem zugehörigen Artikel hier auf meiner Webseite beschreibe ich das Board im Detail und liefere zusätzlich jede Menge Starthilfe in Form von Programmbeispielen. Das Board bietet für vergleichsweise wenig Geld viele Möglichkeiten zum Austoben mit dem PIC18F25K22 Controller.
Welcher PIC ist der Richtige?
Es gibt eine sehr große Auswahl an verschiedensten PIC Controllern, da ist es zu Beginn erst einmal nicht so einfach den richtigen PIC zu finden. Daher solltet Ihr euch zu Beginn erstmal nur auf wenige PIC-Typen beschränken um nicht den Überblick zu verlieren. Der Rest kommt mit der Zeit von ganz allein. Im Datenblatt zu eurem PIC findet Ihr alles was Ihr zum jeweiligen PIC wissen müsst. Da die Datenblätter, wie Ihr vielleicht schon vermutet habt, in Englisch geschrieben sind, werdet Ihr nicht um Englisch herum kommen. Aber vieles erklärt sich mit der Zeit auch von allein. Und: Die Datenblätter von Microchip sind in der Regel sehr verständlich geschrieben, so dass man auch mit Grundkenntnissen ganz gut voran kommen sollte.
Hier einmal zwei PICs, welche ich zum Einstieg empfehlen möchte:
PIC18F14K22 | PIC18F45K22 |
Anwendung: Kleine Projekte | Anwendung: Größere Projekte |
Programmspeicher: 16 KByte | Programmspeicher: 32 KByte |
Pins: 20 | Pins: 40 |
I/O Pins: 18 | I/O Pins: 36 |
ADC Eingänge: 12 | ADC Eingänge: 28 |
Timer (Anzahl): 4 | Timer (Anzahl): 7 |
Preis bei Reichelt (2015): 2,35 € | Preis bei Reichelt (2015): 3,10 € |
Wenn Ihr später mal einen anderen PIC verwenden möchtet, vielleicht weil die Ein- und/oder Ausgänge nicht mehr ausreichen, dann könnt Ihr hier oder hier mal rein schauen. Dort könnt Ihr die Anforderungen an euren PIC eintragen und bekommt die in Frage kommenden Typen aufgelistet.
Es wird gerne gesagt: “Kennst du einen PIC, kannst du alle”. Der Spruch ist natürlich etwas überspitzt, trifft den Nagel jedoch auf den Kopf. Es gibt zwar sehr viele verschiedene PIC-Typen. Diese unterscheiden sich jedoch in der Regel nicht so gravierend. Oftmals hat ein PIC lediglich ein, zwei Funktionen mehr als ein anderer oder ist sogar identisch bis auf einen größeren bzw. kleineren Flash Speicher.
Peripherie
Ein PIC ist zwar ein hochkomplexes Bauteil, benötigt zum Arbeiten aber noch die ein oder andere Beschaltung (genannt Peripherie). Die normalen PICs von denen ich in diesem Tutorial reden werde, arbeiten mit einer Betriebsspannung von 5V Gleichspannung (DC). Weiterhin benötigt der PIC einen Takt damit er “weiß” wann er einen Arbeitsschritt durchführen soll. Die meisten PIC-Typen können sich diesen Takt selbst intern erzeugen. Jedoch gibt es auch Typen, die das nicht können und diese benötigen dann zwingend einen von extern zugeführten Takt. Des Weiteren ist zu entscheiden, ob man dem PIC eine Resetschaltung gönnt oder man den Pin MCLRE (master clear reset) als Eingang benutzen möchte. Wenn man den PIC während des Betriebs resetten können möchte, so wird eine Beschaltung mit Taster an diesem Pin benötigt. Würde man sich dafür entscheiden, keinen Reset Schalter benutzen zu wollen, so ist der freie Pin als Eingang nutzbar (siehe Datenblatt). In der Grafik ist einmal die Grundbeschaltung eines PICs angedeutet, wobei diese je nach Typ kleiner ausfallen kann. Immer erforderlich ist ein sogenannter Abblockkondensator an jedem Betriebsspannungspin (mehrere sind durchaus üblich) des Controllers.
Wie ich bereits oben erwähnt habe könnte z. B. bei dem PIC18F14K22 die Beschaltung des Taktgebers (Quarz) komplett entfallen, da dieser einen eigenen Takt intern erzeugen kann. Das bedeutet, dass die Bauteile XT2, C2 und C3 nicht benötigt werden. Außerdem können der Taster RES und R1 entfallen, da wir entscheiden können ob wir einen Resetschalter brauchen oder eben nicht. Man muss hierbei beachten, dass die MCLRE Beschaltung low aktiv ist. Das heißt, dass der PIC einen Reset durchführt, wenn an dem MCLR-Pin Low-Potemtial anliegt (TTL-Logik). Bei High-Pegel hingegen arbeitet er ganz normal seinen Programmcode ab. Die Beschaltung kann also einzig auf einen Abblockkondensator minimiert werden. PICs mit in größerer Bauform haben oftmals zwei Versorgungsanschlüsse in diesem Fall müssen auch jeweils beide angeschlossen werden sowie beide mit Abblockkondensatore versehen werden.
Wenn Ihr euch dafür entscheidet eine MCLRE Beschaltung nicht benutzen zu wollen, müsst Ihr das immer im Programm oder in der Konfiguration angeben. Dazu komme ich aber noch, wenn wir beim Kapitel Konfiguration angekommen sind. Achtet bei der Wahl des PIC immer auch auf den zulässigen Bereich für die Betriebsspannung – Nicht jeder PIC kann mit bis zu 5V betrieben werden.
Taktquelle
Die Taktquelle eines PIC kommt immer an seine Pins OSC1 und OSC2 (sofern er extern versorgt werden soll). Man kann als Taktgeber zwischen verschiedenen Quellen auswählen. In der angedeuteten Schaltung (siehe oben) ist ein Quarz verwendet worden. Dieser hat im Gegensatz zu einem Keramik Resonator den vermeintlichen Nachteil, dass er an seinen beiden Beinen jeweils noch einen Kondensator benötigt (das sind immerhin zusammen schon drei Bauteile). Den Wert für die Kondensatoren könnt Ihr übrigens im Datenblatt des jeweiligen PIC nachlesen. Er variiert je nach Frequenz des Quarzes. Der Keramikresonator hingegen hat die Kondensatoren bereits im Gehäuse integriert und spart somit Platz. Ich empfehle euch die Verwendung von Keramik Resonatoren, sofern Ihr überhaupt eine externe Taktquelle benötigt.
Wenn Ihr den internen Takt nutzen wollt, müsst Ihr dazu die Konfiguration entsprechend einstellen. Das geht entweder manuell über den Programmcode oder über die Einstellungen in MPLABX, siehe nachfolgende Abbildung.
Hinweis: Wenn man den PIC mit einem Bootloader (ein kleines Programm im PIC, welches die HEX-Files über z.B. USB entgegen nimmt) betreiben möchte, dann muss man eine externe Taktquelle verwenden. Ein PICKit3 oder ähnliches ist dann nicht mehr notwendig. Für Einsteiger ist diese Variante jedoch eher nicht zu empfehlen.
Programm erstellen
Ein Programm kann man auf verschiedene Weise schreiben. Grundsätzlich lassen sich Programmtexte in einem einfachen Texteditor schreiben. Dabei wird man jedoch wenig Freude haben, da einem der normale Texteditor selbstverständlich nicht großartig beim Entwickeln unterstützen wird. Wir werden daher die Entwicklungsumgebung MPLABX von Microchip verwenden, da diese ein paar entscheidende Vorteile hat.
Grundlagen
PIC Mikrocontroller gibt es in vielen verschiedenen Sorten. Wir beschäftigen uns hier vornehmlich mit den PIC18F Typen. Nachfolgend möchte ich Euch etwas in die Grundzüge und die wichtigsten Eigenschaften der PIC Mikrocontroller einführen. Wie Ihr die PIC dann wirklich (in C) programmiert, könnt Ihr dann in meinem PIC-C-Tutorial nachlesen.
Eingänge und Ausgänge
Das wichtigste an Mikrocontrollern sind die Ein- und Ausgänge (kurz engl. IOs). Mit ihnen wird gesteuert und mit der Außenwelt kommuniziert. Ein Mikrocontroller hat immer eine bestimmte Anzahl von IO-Pins zur Verfügung. Dabei darf man nicht den Trugschluss ziehen, dass die Anzahl der Pins des Gehäuses gleich der Anzahl der IO-Pins entspricht – Dies ist nicht der Fall! PIC-Mikrocontroller haben grundsätzlich ein 8 Bit breites IO-Register. Das bedeutet pro Register sind (maximal) acht Ein- und/oder Ausgänge vorhanden. Diese Register haben die Bezeichnung PORT. Mit einem folgenden Buchstaben für den Port (also z.B. PORTA oder PORTE) wird der jeweilige Port weitergehend bezeichnet. Der PIC betrachtet die PORT-Register wie jedes andere Register auch. Nun kann ein Pin natürlich nicht Aus- und Eingang gleichzeitig sein, sondern muss auf eines der beiden definiert bzw. eingestellt werden. Dieses geschieht in den zugehörigen TRIS-Registern. Jedes PORT-Register hat also ein zugehöriges TRIS-Register. Dabei entspricht eine logische “1” (also High) einem Eingang und eine “0” (Low) einem Ausgang. Das lässt sich relativ einfach merken: Die 1 sieht ähnlich aus wie ein groß geschriebenes I und steht folglich für Input. Anders herum ist eine 0 ähnlich einem großem O und steht demnach für Output. Hierzu eine Grafik zum Veranschaulichen:
Die Ein- und Ausgänge des PIC arbeiten i.d.R. mit TTL-Pegeln (Low = 0 Volt, High = 5 Volt). Teilweise werden mehrere Funktionen auf ein und den selben Pin gelegt. So können zum Beispiel bestimmte Eingänge auch als Analogeingang benutzt werden, während man andere Pins wiederum zum Ausgeben eines PWM-Signals verwenden kann. Es gibt eine Vielzahl von Funktionen, die sich von PIC zu PIC unterscheiden und beim Programmieren bzw. beim Entwerfen des Schaltplans zur Schaltung berücksichtigt werden müssen. Vergisst man z. B. bei einem PIC zu Beginn die Eingänge von Analog auf Digital umzuschalten, dann funktioniert unter Umständen das Programm nicht wie man es eigentlich erwarten würde.
Des Weiteren ist es wichtig zu beachten, dass ein Pin eines Mikrocontrollers nur einen begrenzt hohen Strom liefern kann. Am Beispiel des PIC16F62x liegt dieser Wert bei maximal 25 mA. Weiter gibt es einen Gesamt-Maximalstrom, der für den gesamtem PIC gilt (Summe aller Teilströme). Die Infos dazu findet ihr im Datenblatt unter Electrical Specification. Und genau aus diesen Gründen dürfen (relativ) große Lasten nicht direkt an den Mikrocontroller. Dieser Abschnitt sollte nicht falsch verstanden werden: Man kann eine Last schon mit einem Vorwiderstand direkt an einen IO des uC anschließen, man muss dabei aber beachten das der Strom, den die Last benötigt den maximalen Wert des Pins nicht überschreitet. Wenn Ihr in eurem Projekt zum Beispiel eine normale grüne/gelbe/rote LED ansteuern möchtet kann diese natürlich direkt (mit Vorwiderstand) an einen IO angeschlossen werden. Bei größeren Lasten bietet es sich an eine Treiberstufe zu verwenden. Hier wird die Last über einen Transistor oder wahlweise FET geschaltet. Der Strom wird somit direkt von der Spannungsversorgung bereit gestellt.
LEDs können je nach Strombedarf direkt vom Controller gespeist werden. Wenn Ihr jedoch stärkere LEDs ansteuern möchtet (z.B. Hochleistungs-LEDs), versteht es sich von selbst, dass der PIC diesen Strom nicht liefern kann.
In der Abbildung ist eine klassische Treiberstufe mit einem NPN-Transistor zu sehen. Sobald der Mikrocontroller seinen Ausgang auf 5 V anhebt, wird das Potential an der Basis positiver als das am Emitter. Es fließt ein geringer Basisstrom aus dem Controller in den Transistor hinein. Der Transistor beginnt zu leiten. Sobald der Mikrocontroller sein Potential auf Masse zieht (Low) wird die LED ausgeschaltet. Durch den µC fließt somit nur ein minimaler (Basis-)Strom. Wenn Ihr besonders sparsam arbeiten möchtet, dann könnt Ihr statt des Transistors auch einen MOSFET verwenden. Dieser wird nicht mit Strom, sondern mit Spannung gesteuert.
Alle PIC Typen in der Übersicht
Wir werden in diesem Tutorial lediglich die PIC16F und vor allem die PIC18F besprechen. Um einen Überblick über die Typen-Vielfalt zu erhalten, dient die nachfolgende Tabelle als Übersicht.
DATENBREITE | KERN | SPANNUNG | DSP | |
---|---|---|---|---|
PIC10F | 8 Bit | 12 Bit | 2,0 – 5,5V | Nein |
PIC12F | 8 Bit | 14 Bit | 2,0 – 5,5V | Nein |
PIC16F | 8 Bit | 14 Bit | 2,0 – 5,5V | Nein |
PIC18F | 8 Bit | 16 Bit | 1,8 – 5,5V | Nein |
PIC24F | 16 Bit | 24 Bit | 2,2 – 3,6V | Nein |
dsPIC30F | 16 Bit | 24 Bit | 2,5 – 5,5V | Ja |
dsPIC33F | 16 Bit | 24 Bit | 3,0 – 3,6V | Ja |
PIC32M | 32 Bit | 32 Bit | 2,3 – 3,6V | Nein |
Im folgenden wollen wir etwas Licht ins dunkle bringen. Was bedeuten folgende Begrifflichkeiten und worauf sollte man bei der Wahl des PIC achten?
Programm- Speicher
Gibt an wie viel Speicherplatz der PIC für Befehle, also euer eigentliches Programm, zur Verfügung hat. Hat ein PIC die Bezeichnung 4k, dann hat er 4096 Speicherplätze für Befehle mit der Größe seines Kernes. Bei der Auswahl des Controllers sollte man generell nie zu knapp planen. Lieber einen Typen mit etwas mehr Speicher auswählen und bei Bedarf die entsprechenden Reserven haben.
Pins
Gibt an wie viel Pins das Gehäuse des PIC insgesamt hat. Dieser Wert steht nur bedingt im Zusammenhang mit der zur Verfügung stehenden Anzahl an Ein- und Ausgängen. Diese Größe liefert also lediglich eine Auskunft über das Gehäuse.
I/O-Pins
Dies ist die Tatsächliche Angabe über die Anzahl an Ein- und Ausgängen die dem Anwender zur Verfügung stehen. Hier sollte man jedoch zusätzlich beachten, dass es vorkommen kann, dass ein Pin nur als sogenannter open collector ausgeführt ist und dann nur mit Hilfe eines Pull-up-Widerstandes als richtiger Ausgang arbeiten kann (Potential auch auf High möglich).
ADC
In der Regel besitzt ein PIC eine Einheit um analoge Spannungen in einen digitalen Wert umzusetzen. Die Angabe über die ADCs dient zur Orientierung an wie viel verschiedenen IO-Pins diese analoge Spannung dafür angelegt werden kann. Der Controller bzw. der Umsetzer greift sich die Spannung dann von diesem Pin ab.
USART (SCI)
Der Begriff USART (Universal Asynchronous Receiver Transmitter) beschreibt eine serielle Schnittstelle. Diese kann zum Beispielals RS232 verwenden werden um mit anderen Modulen zu kommunizieren.
SSP (MSSP)
Die synchrone serielle Schnittstelle, kurz SSP, bietet einem die Möglichkeit eine SPI (Seriel Peripheral Interface) oder I2C (Inter-Integrated Circuit) zu realisieren.
(E)CCP
Anzahl der Capture/Compare/PWM-Module. Mit diesen Modulen lassen sich Impulse messen und erzeugen. Außerdem können pulsweitenmodulierte (kurz PWM) Signale ausgegeben werden.
Timer
Timer sind so ziemlich das wichtigste Instrument bei der Softwareentwicklung auf Mikrocontrollern. Hier wird angegeben über wie viele Hardware-Timer der jeweilige PIC verfügt. Dabei wird zwischen verschiedenen Größen (8 oder 16 Bit) unterschieden.
nanoWatt XLP
Eine Bezeichnung für eine Stromspartechnologie. Diese PIC-Typen arbeiten üblicherweise mit einer Versorgungsspannung von deutlich unterhalb von 5 Volt (zum Beispiel 3,3 V). Die meisten XLP-Typen können jedoch auch nach wie vor mit 5V betrieben werden.
Hardware und Module
In diesem Kapitel gehe ich auf die grundlegendsten Hardwaremodule eines PIC ein und versuche diese zu grob zu erläutern. Dabei versteht es sich von selbst, dass Ihr das hier gelesene nur durch ausprobieren erlernen und verfestigen könnt. Es gilt: Learning by doing. Auf der folgenden Grafik seht Ihr zum Beispiel was ein PIC18F45K22 so alles an Hardware zu bieten hat.
Quelle: Datenblatt des PIC18F45K22
Die Timer
Ein PIC beinhaltet verschiedene Ausführungen von Timern. Was kann man mit Timern machen? Timer sind die wichtigste Peripherie die ein Mikrocontroller besitzt. Man kann mit ihnen zum Beispiel die Länge eines Impulses zählen, Impulse exakter Länge ausgeben, Zeitbasen erzeugen, Programmfunktionen ansteuern und so weiter und so fort. Das entscheidende an Hardware-Timern ist, dass sie völlig autark, unabhängig von der CPU arbeiten. Wird ein Timer einmal vom PIC gestartet läuft er ununterbrochen fort. Der PIC kann während dessen andere Aufgaben parallel bearbeiten. Und genau das ist der große Vorteil von Hardware-Timern. Betrachten wir die einzelnen Timer im Detail.
Timer0
Der Timer0 ist bei allen PIC vorhanden. Es handelt sich hierbei um einen einfachen 8 Bit Timer*. Was bedeutet 8 Bit Timer? Das bedeutet, dass dieser Timer von 0 bis 255 zählen kann. Das Zählregister ist also 8 Bit breit, siehe:
*Bei vielen PIC-Typen kann der Timer0 auch im 16-Bit-Modus betrieben werden.
Wertigkeit = |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
Bitnummer (x) | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Ein Bit kann ausschließlich die Werte 0 oder 1 annehmen. Wenn alle Bits mit einer 0 gefüllt sind, so ist der Zählerstand (im dezimalen Zahlensystem) also 0. Wenn alle Bits eine 1 beinhalten ergibt das einen Wert von 255 und dieser ergibt sich wie folgt:
Wer an dieser Stelle Schwierigkeiten hat das binäre Zahlensystem nachzuvollziehen, dem sei folgender Artikel ans Herz gelegt, der die verschiedenen Zahlensysteme sehr anschaulich erklärt. Das Verständnis zu den Zahlensystemen (vorrangig Binär, Dezimal und Hexadezimal) ist unabdingbar in der Mikrocontroller-Programmierung.
Der Timer0 kann teilweise auch als 16 Bit Timer verwendet werden. Außerdem hat man die Wahl zwischen Timer und Counter. Der Timer0 erhält seinen Takt entweder über den Pin RA4 oder er arbeitet mit ¼ des PIC Taktes. Wobei er diesen Takt durch einen Vorteiler in 8 Stufen teilen kann. Der Vorteiler lässt sich zwischen den Teiler mit bis zu und
wählen. Der Timer0 beginnt bei 0 zu zählen und zählt bis 255 rauf. Bei einem Überlauf, also wenn nach dem Zählerstand 255 wieder um eins hoch gezählt wird, wird das Bit T0IF im Register INTCON gesetzt. Durch das Setzen dieses Flags kann ein Interrupt vom Controller ausgelöst werden. Der aktuelle Zählerstand des Timer0 steht im Register TMR0 und kann gelesen sowie beschrieben werden. Der Timer0 wird im T0CON Register konfiguriert, siehe dazu das Datenblatt des jeweiligen PIC.
Quelle: Datenblatt des PIC18F45K22
Damit der Interrupt des Timer0 benutzt werden kann, muss das GIE Bit (global interrupt enable) gesetzt werden. Dieses Bit ist vorhanden um alle Interrupts zu erlauben oder zu verbieten. Wenn das GIE Bit gelöscht ist, kann kein Interrupt ausgeführt werden! Ausnahmen bestätigen die Regel: Wird im Programm das unterscheiden verschiedener Interrupt-Prioritäten erlaubt, so gibt es zwei globale Enable-Bits: Eines für niedrig priorisierte und eines für hoch priorisierte Interrupts. Der Timer0 wird mit folgenden Bits im T0CON Register eingestellt:
BIT 7 | BIT 0 | ||||||
---|---|---|---|---|---|---|---|
TMR0ON | T08BIT | T0CS | T0SE | PSA | T0PS<2:0> |
T0PS<2:0> (Timer0 Prescaler Select bits)
Mit den Bits PS0 bis PS2 wird der Vorteiler für den Timer0 eingestellt. Er lässt sich in acht Schritten von bis hin zu
einstellen, wobei PS2…PS0 = ‘000’ einem Vorteiler von
und ‘111’ einem Vorteiler von
entspricht. Die Zwischenstufen sind immer der halbe bzw. doppelte Teiler.
PSA (Prescaler Assignment bit)
Mit diesem Bit kann man den Vorteiler für den Timer0 einschalten PSA = ‘0’ oder ausschalten PSA = ‘1’. Wenn der Vorteiler ausgeschaltet ist, arbeitet der Timer0 direkt mit dem Takt des ¼ des PIC Taktes.
T0SE (Timer0 Source Edge Select bit)
Diese Option ist nur interessant, wenn Ihr den Timer0 mit einem Takt über den Pin RA4 versorgt. Mit diesem Steuerbit entscheidet Ihr wann der PIC den Timer0 um eins weiterzählen lässt. Und zwar wird zwischen dem Inkrementieren bei steigender (0) oder fallender Taktflanke (1) unterschieden.
T0SC (Timer0 Clock Source Select bit)
Hier wird zwischen den beiden Taktquellen unterschieden: Interner Takt (0), also ¼ des PIC Taktes oder externer Takt über RA4 (1).
T08BIT (Timer0 8-bit/16-bit Control bit)
Wird dieses Bit gesetzt, arbeitet der Timer0 im 8-Bit-Modus. Wird es hingegen gelöscht arbeitet der Timer0 einem 16 Bit breiten Zählerregister.
TMR0ON (Timer0 On/Off Control bit)
Der Name verrät es schon, mit diesem Bit kann der Timer0 gestartet (1) oder angehalten (0) werden.
Der Vollständigkeit halber möchte Ich an dieser Stelle auch noch das Blockschaltbild für den Timer0 im 16 Bit Modus angeben.
Quelle: Datenblatt des PIC18F45K22
Im 16 Bit Modus steht der Zählerstand in den Registern TMR0L und der höherwertige Teil in TMR0H. Zusammen ergibt sich somit der 16 Bit Zählerstand des Timers.
Timer1/3/5
Die Timer1, 3 und 5 sind 16 Bit Timer. Das heißt, dass diese von 0 bis 65535 zählen können. Oder in hexadezimaler Schreibweise: 0x0000 bis 0xFFFF. Die Timer können ihren Takt mit dem sie zählen, entweder über den internen Quarztakt beziehen oder aber wie der Timer0 über IO-Pin(s) (TxCKI oder SOSCI/SOSCO) des PIC. Sobald der Timer überläuft, setzt er das Bit TMRxIF im PIR1/2/5 Register, welches ein Interrupt auslösen kann. Damit die Timer überhaupt einen Interrupt auslösen können, müssen die entsprechenden Enable-Bits TMRxIE im PIE1/2/5 Register gesetzt werden. Des Weiteren haben die Bits PEIE/GIEL sowie GIE/GIEH im INTCON Register einen Einfluss auf den Interrupt. Da die Timer 16-Bit-Timer sind, der PIC aber nur 8-Bit-Register hat, werden für das Zählen zwei Register benötigt. Das sind die Register TMRxL und TMRxH. Im Register TMRxL steht dementsprechend der niederwertige Teil und in TMRxH der höherwertige. Man kann den Zählstand jederzeit auslesen oder mit einem gewünschten Wert beschreiben.
Die Timer werden mit folgenden Bits im Register TxCON eingestellt. Das Register findet Ihr im Datenblatt unter TxCON, da die Steuerung für die Timer1, 3 und 5 identisch ist.
BIT 7 | BIT 0 | ||||
---|---|---|---|---|---|
TMRxCS<1:0> | TxCKPS<1:0> | TxSOSCEN | TxRD16 | TMRxON |
TMRxON
Das Bit schaltet den TimerX ein (1) oder aus (0).
TxRD16
Hier könnt Ihr zwischen Lesen/Schreiben in einer 16 Bit Operation (1) oder in zwei 8 Bit Operationen (0) umschalten.
TxSYNC
Mit diesem Bit kann eine Synchronisation des externen Taktes mit dem internen durchgeführt werden. Dieses Bit hat folglich keine Funktion, wenn der Takt nicht von extern kommt. Dieses Bit ist also nur relevant, wenn TMRxCS<1:0> auf ‘1X’ steht, wobei X beliebig ist.
T1xSOSCEN
Wenn TMRxCS<1:0> auf ’10’ gesetzt ist, könnt Ihr zwischen Taktspeisung am Pin TxCKI (0) oder an SOSCI/SOSCO Pins (1) wählen.
TxCKPS<1:0>
Ähnlich wie beim Timer0 kann man dem Timer1 einen Vorteiler vorschalten, welcher den Takt zum Zählen entsprechend teilt. Der Vorteiler lässt sich in vier Stufen einstellen wobei T1CKPS0/1 = ’00’ einem Vorteiler von entspricht und ’11’ hingegen
.
TMRxCS<1:0>
Mit diesen beiden Bits wählt Ihr die Quelle des Taktes für den TimerX. Mit ’00’ arbeitet der jeweilige Timer mit ¼ des PIC Taktes, mit ’01’ bezieht er den direkten Takt des Systems ohne Teilung, mit ’10’ kommt der Takt vom Pin oder Oszillator (siehe TxSOSCEN) und die Einstellung ’11’ wird nicht verwendet bzw. ist reserviert.
Die Timer können verwendet werden um den PIC aus dem Sleep-Zustand zu holen. Damit der Timer1/3/5 den PIC aufwecken kann muss er im asynchronen Modus arbeiten, sprich er bekommt seinen Takt von extern. Sobald der Timer überläuft wird der PIC geweckt.
Sekunden Basis mit Timer1 erstellen
Da man dem Timer1 einen externen Takt anschließen kann, hat man mit einem Uhrenquarz die Möglichkeit eine 1 Sekunden Basis zu schaffen. Ein Uhrenquarz wird wie der normale Quarz (für die Taktversorgung des PIC) an die Pins T1OSO und T1OSI angeschlossen. Dann bekommt der Quarz noch pro Beinchen einen Kondensator (10pF bei dem verlinkten Typ) gegen Masse spendiert. Der Timer1 zählt nun mit einem 32.768 Hz Takt, was als Zahl genau 0x8000 entspricht. Also brauch der Timer1 für einen Überlauf (Intterrupt) von 0x8000 bis zum Überlauf (genau)eine Sekunde. Somit hat man zum Beispiel die Zeitbasis für eine Uhr geschaffen. Der Timer muss bei Überlauf immer mit dem Wert 0x8000 +/- vorgeladen werden. Dabei kann der Wert angepasst werden, falls die Zeit vor oder nachläuft.
Das Vorgehen nochmal zusammengefasst:
- Timer1 konfigurieren (externen Takt auswählen, Syncronisation aus) (T1CON)
- Den Interrupt des TMR1 konfigurieren (PIE1 und IPR1)
- Im Interrupt lediglich ein Flag setzten (+1 Sekunde-Merker)*
- Zählregister wieder auf 0x80 und 0x00 setzten (auch im Interrupt)
- Schritte 3 und 4 wiederholen sich automatisch durch den Interrupt
* Die Interrupt-Service-Routine (kurz ISR: So nennt man die Funktion, die aufgerufen wird, wenn ein Interrupt ausgelöst wurde) sollte immer so kurz wie möglich gestaltet werden. Keinesfalls werden Funktionsaufrufe ausgeführt! Wir setzten hier lediglich ein Flag, setzen die Zählregister wieder auf ihre Startwerte und löschen das Flag, das den Interrupt ausgelöst hat. Durch das Flag, welches wir gesetzt haben können wir im normalen Programm sehen, das eine Sekunde vergangen ist und entsprechend fortfahren.
Timer2/4/6
Die Timer2/4 und 6 sind drei identische 8 Bit Timer. Diese Timer sind wie der Timer0 wieder als 8 Bit Timer ausgeführt. Allerdings unterscheiden sie sich in einem entscheidenden Punkt. Die Timer 2,4 und 6 verfügen neben einem Vorteiler (Prescaler) zusätzlich über einen Nachteiler (Postscaler). Die folgende Grafik zeigt das entsprechende Blockdiagramm.
Quelle: Datenblatt des PIC18F45K22
Im Gegensatz zu den Timern 0 und 1/3 und 5, können die Timer2/4 und 6 nur mit den internen PIC Takt arbeiten. Genauer gesagt mit 1/4 der Frequenz des extern angeschlossenen Quarz ( siehe auch hier ). Der aktuelle Zählerstatus steht im TMRx Register. Genau wie bei den anderen Timern, kann der aktuelle Zählerstand sowohl ausgelesen als auch verändert werden.
Eine Besonderheit bei den Timern 2,4 und 6 ist, dass sich der Zählerwert dynamisch begrenzen lässt. Über das Register PRx kann ein Wert vorgegeben werden. Der aktuelle Zählerstand des TMRx Registers wird über einen Komparator mit dem Inhalt des PRx Registers verglichen. Wenn die Registerinhalte übereinstimmen startet der Timer von vorn.
Die Timer2/4/6 lassen sich unter anderem auch zum Erzeugen von PWM Signalen nutzen. Dabei arbeiten sie mit dem ECCP-Modul zusammen. Sobald der Timer überläuft, wird an das Modul ein Signal gesendet. Siehe hierzu auch diesen Abschnitt.
Die Timer werden mit folgenden Bits im Register TxCON eingestellt. Hierbei steht das “x” für den gewünschten Timer (2, 4 oder 6).
BIT 7 | BIT 0 | ||||||
---|---|---|---|---|---|---|---|
– | TxOUTPS<3:0> | TMRxON | TxCKPS<1:0> |
TxCKPS<1:0>
Hier kann der Vorteiler eingestellt werden. Ein Wert von ’00’ entspricht einem Vorteiler von und ’10’ einem Vorteiler von
.
TMRxON
Mit dem Setzen dieses Bits wird der Timer gestartet. Ein löschen (Bit zu 0 setzen) bewirkt, dass der Timer angehalten wird bzw. mit dem Zählen aufhört.
TxOUTPS<3:0>
Hier stellt Ihr den Nachteiler (Postscaler) ein, dieser reicht von mit einer Bitkombination von ‘0000’ bis hin zu
mit ‘1111’
Analog Digital Converter (ADC)
Digital ist ja schön und gut, doch manchmal brauchen wir doch das Zusammenspiel mit der Analogtechnik. Und genau hierfür hat ein PIC Mikrocontroller analoge Eingänge. Wie das funktioniert möchte ich euch im folgenden etwas näher erläutern. Die unten stehende Abbildung zeigt in grau dargestellt eine analoge Spannung, welche zu äquidistanten (gleichbleibender Abstand) Zeitpunkten abgetastet wird. Diese Abtastwerte werden mit einem ADC digitalisiert und stehen dann zur weiteren Verarbeitung bereit. Aufgrund der begrenzten Anzahl an Unterscheidungsmöglichkeiten im digitalen, gibt es nicht für jeden analogen Wert einen digitalen. Somit ergibt sich das dargestellte Raster in der Abbildung.
Stellt Euch einmal vor Ihr möchtet mit dem PIC eine Spannung messen um diese auf einem LC-Display anzuzeigen. Die zu messende Spannung kann zum Beispiel von einem analogen Sensor stammen und im Verhältnis zu einer physikalischen Größe stehen (z.B. zur Temperatur). Möglicherweise plant Ihr auch den Bau eines einfachen Voltmeters. Für solche Zwecke könnt Ihr die zu messende Spannung an einen anlogen Eingang des PIC anschließen. Diese haben die Bezeichnung ANx wobei das “x” durch eine Zahl ersetzt wird, die den Pin erkenntlich macht.
Nun kann es ja auch durchaus mal vorkommen, dass Ihr Spannungen messen möchtet, die über den üblichen Bereich der Betriebsspannung des Controllers hinaus reichen. In dem Fall dient im einfachsten Fall der gute alte Spannungsteiler. Dieser sollte so dimensioniert sein, dass die Spannung, die letztendlich am Pin anliegt, nicht größer werden kann als die Betriebsspannung des PIC selber.
Ein Beispiel seht Ihr im Bild links. Der Spannungsteiler teilt die Messspannung durch 2. Somit wäre bei einer Betriebsspannung von 5V eine maximale Messspannung von 10 Volt möglich. Die gemessene Spannung (digitaler Wert) kann im PIC wieder mit 2 multipliziert werden (entspricht einer Bitschiebe-Operation nach links um eine Stelle).
Grundlegendes
Der Analog-Digital-Konverter des PIC hat eine Auflösung von 10 Bit. Ein PIC hat nur einen ADC Modul. Er kann aber von verschiedenen Pins des µC angesprochen werden. Wenn ein Eingangspin Zugriff auf den ADC hat, so wird er auch als ANx bezeichnet. Somit kann der PIC die maximale Spannung in 1024 Werte (10 Bit) einteilen – er quantisiert. Bei einer maximal zulässigen Messspannung von 5V ergibt dies eine Auflösung von circa 5 mV pro Bit.
Nun kann es ja durchaus vorkommen, dass nur ein kleiner Spannungsbereich sehr genau gemessen werden soll. Ein Beispiel: Es werden 0…2 Volt als Messspannung benötigt. Man kann dem PIC mitteilen, dass die Referenzspannung für die AD-Umsetzung nicht mehr dem Standard von VDD (und Vss) entspricht, sondern die Referenzspannung an AN2 (VREF -) und AN3 (VREF +) des PIC entnehmen. So kann man die Auflösung (welche vorher auf den gesamten Bereich von 5V aufgespannt wurde) nun auf einen kleineren Bereich einstellen und somit die Voltzahl pro Bit verringern – die Auflösung erhöhen.
Dankeschön an Leser Stefan, für folgenden Beitrag:
Um die maximale Genauigkeit mit einem 5V-PIC zu erreichen, sind, je nach Typ, zwischen 2,5V und 3,0V Referenzspannung mindestens notwendig (sollte als Parameter AD06 und AD06A in den elektrischen Spezifikationen aufgeführt sein).
Im Folgenden wollen wir uns ansehen, wie der Analog-Digital-Umsetzer (ADU/ADC) eines PIC konfiguriert wird. Folgende Bits im den Registern ANSEL, ADCON0 und ADCON1 sind dafür nötig:
ANSEL (Analog Select Register)
Im ANSEL Register werden die gewünschten IOs ausgewählt, die als analoge Eingänge verwendet werden sollen. Wenn ein PIC mehrere Eingänge besitzt, die analog verwendet werden können, so hat er dementsprechend auch mehrere ANSEL-Register. Diese werden alphabetisch geführt (ANSELA, ANSELB usw.). Dabei sind die abschließenden Buchstaben korresponierend mit den Ports in denen die Eingänge liegen. Somit ist die folgende Konfiguration eher exemplarisch zu verstehen und hängt mehr vom verwendeten PIC ab.
BIT 7 | BIT 0 | ||||
---|---|---|---|---|---|
ANS7 | ANS0 |
Eine “1” im entsprechenden Bit setzt den IO Pins als analogen Eingang. Wenn ein Pin als analoger Eingang gewählt wird, dann muss das entsprechende TRIS Bit ebenfalls auf “1” gesetzt werden! Wird das Bit im ANSEL-Register hingegen gelöscht, so ist der Eingang auf digital geschaltet. Ein analoger Eingang kann nicht mehr auf logische Pegel abgefragt werden.
ADCON0 (A/D Control Register 0)
Im ADCON0-Register kann das ADC-Modul des PIC generell ein- oder ausgeschaltet werden. Außerdem beinhaltet das Register das Statusflag des ADC. Zusätzlich werden übrige Bits zum selektieren einzelner Kanäle (Auswahl eines ANx zum messen) verwendet.
BIT 7 | BIT 6…2 | BIT 1 | BIT 0 | ||||
---|---|---|---|---|---|---|---|
– | CHS<4:0> | ADON |
ADON (ADC Enable bit)
Dieses Bit aktiviert (1) oder deaktiviert (0) den Analog-Digital-Umsetzer
GO/DONE ( A/D Conversion Status bit)
Durch das setzen dieses Bits wird eine AD-Umsetzung gestartet. Das Bit bleibt dann solange High bis der PIC mit der Messung/Umsetzung fertig ist. Man muss dieses Bit also immer auf ‘0’ prüfen, wenn man eine neue Messung starten oder die aktuelle auswerten möchte. Der ADC kann auch einen Interrupt auslösen. Wenn der ADC entsprechend konfiguriert ist setzt er nach beendeter Umsetzung das ADIF Bit im PIR1 Register.
CHS<4:0> (Analog Channel Select bits)
Mit diesen Bits wird der ANx gewählt an dem die Analog-Ditial-Umsetzung stattfinden soll.
ADCON1 (A/D Control Register 1)
In diesem Register lassen sich weitere Einstellungen für den ADC vornehmen. So lässt sich zum Beispiel eine alternative Referenz (Spannung) auswählen. Standardmäßig sind und GND als Referenz voreingestellt.
BIT 7 | BIT 6 | BIT 7 | BIT 6 | BIT 3…2 | BIT 1…0 | ||
---|---|---|---|---|---|---|---|
TRIGSEL | – | – | – | PVCFG<1:0> | NVCFG<1:0> |
NVCFG<1:0> (Negative Voltage Reference Configuration bits)
Mit diesen beiden Bits wird die negative Referenzspannung eingestellt bzw. gewählt. Mit ’00’ wird die interne Spannung AVss gewählt. Mit ’01’ wird die Spannung vom externen Pin entnommen. Durch setzen auf ’10’ oder ’11’ wird beides mal AVss gewählt, da diese beiden Einstellungen nicht belegt bzw. reserviert sind.
PVCFG0/1 (Positive Voltage Reference Configuration bits)
Mit diesen beiden Bits wird die positive Referenzspannung eingestellt bzw. gewählt. Mit ’00’ wird die interne Spannung gewählt. Mit ’01’ wird die Spannung vom externen Pin
entnommen. Durch setzen auf ’10’ wird die positive Referenz mit dem internen Signal FVR BUF2 verbunden. Mit ’11’ wird
gewählt, da diese Einstellungen nicht belegt bzw. reserviert ist.
TRIGSEL (Special Trigger Select bit)
. . .
Acquisition time
Bei der Geschwindigkeit der Umsetzung sollte man beachten, dass der PIC genügend Zeit braucht um eine Umsetzung durchzuführen. Er muss hierzu während des Verfahrens einen im PIC befindlichen Kondensator, auf die am Eingang anliegende Spannung aufladen. So liegt es nahe, dass wenn man hier zu schnell zu Werke geht, eine fehlerhafte Messung durchgeführt wird. Im Datenblatt des PIC gibt es eine genaue Formel zur Berechnung dieser Zeit. Laut Sprut ist eine Zeit von ca. 40 µS ausreichend.
Das Ergebnis einer AD-Umsetzung
Das 10 Bit große Ergebnis einer Analog-Digital-Umsetzung steht in den beiden Registern ADRESL und ADRESH. Diese beiden Register wären theoretisch 16 Bit lang, da der ADC des PIC aber “nur” eine Auflösung von 10 Bit hat, steht das Ergebnis lediglich in 10 der 16 Bit und zwar entweder rechts- oder linksbündig. Das hängt ganz davon ab, wie wir das Bit ADFM im Register ADCON2 gesetzt haben.
ADCON2 (A/D Control Register 1)
BIT 7 | BIT 6 | BIT 5…3 | BIT 2…0 | ||||
---|---|---|---|---|---|---|---|
ADFM | – | ACQT<2:0> | ADCS<2:0> |
ADCS<2:0> (A/D Conversion Clock Select bits)
Es findet die Wahl des AD-Taktes statt:
- 000 Fosc/2
- 001 Fosc/8
- 010 Fosc/32
- 011 Frc
- 100 Fosc/4
- 101 Fosc/16
- 110 Fosc/64
- 111 Frc
ACQT<2:0> (A/D Acquisition time select bits)
Mit diesen drei Bit wird die Umsetzzeit eingestellt. Diese sollte gut bedacht gewählt werden. Eine zu kurze Zeit führt zu falschen Messwerten
- 000 0
- 001 2 TAD
- 010 4 TAD
- 011 6 TAD
- 100 8 TAD
- 101 12 TAD
- 110 16 TAD
- 111 20 TAD
ADFM (A/D Conversion Result Format Select bit)
Mit diesen Bit wird ausgewählt, ob das Ergebnis in ADRESL & ADRESH rechts- (1) oder linksbündig (0) ausgegeben wird.
ADC-Interrupt
Wenn Ihr mit dem Analog-Digital-Converter einen Interrupt auslösen mächtet, müsst Ihr das ADIE-Bit im PIE1 Register setzen. Die Priorität des Interrupt kann mit dem Bit ADIP im Register IPR1 gewählt werden. Das Bit ADIF ist das Interrupt-Flag und muss wie alle Interrupt-Flags, per Software zurück gesetzt werden. Das Bit wird vom PIC gesetzt, sobald eine Messung abgeschlossen wurde. Dieser Interrupt ist übrigens auch in der Lage den PIC aus dem Sleep Modus aufzuwecken.
Capture Compare Modul / PWM
Mit dem Capture/Compare Modul eines PIC lassen sich verschiedene Aufgaben bewältigen. Durch den Capture-Eingang lässt sich der genaue Zeitpunkt bestimmen, an dem ein Signal am Pin CCPx eintrifft. Und der Compare-Modus ist quasi das Pferd von hinten aufgezogen; Hier lässt sich am CCPx zu einem exakt bestimmten Zeitpunkt ein Signal (oder Flanke) erzeugen. Der PWM-Modus hingegen eignet sich zum Erstellen eines pulsweiten modulierten Signals (PWM). Während der Capture- und Compare-Modus den Timer 1, 3 oder 5 verwenden arbeitet der PWM-Modus mit dem Timer 2, 4 oder 6 zusammen. Der Unterschied zwischen CCP und ECCP besteht lediglich darin, dass der ECCP seine Funktion an mehreren IO-Pins bedienen kann.
Pulsweitenmodulation (PWM)
Jeder PIC18 und teilweise auch manche PIC16 besitzen das Capture, Compare, PWM (CCP) Modul mit dem man zusammen mit dem Timer2/4 oder 6 ein pulsweitenmoduliertes Signal (kurz PWM) erzeugen kann. Ich möchte Euch hier kurz erklären wie Ihr mit dem Modul umzugehen habt. Der Timer wird mit 1/4 des am PIC angeschlossenen Quarz-Taktes gespeist und kann zusätzlich noch über einen Vorteiler in drei Stufen geteilt werden (1, 4, 16). Für den PWM-Mode sind folgende Register von Bedeutung: Das Register CCPRxL, das TMRx und das PRx. Während der Timer immer bei 0 beginnt zu zählen wird der aktuelle Zählerstand (TMRx) immer mit dem Wert in PRx und CCPR1x verglichen. Wenn der Zählerstand des Timers dem Wert in CCPRxL entspricht, dann wird der CCPx Ausgang (Pin) gelöscht, also auf Low (0V) gesetzt. Wenn der Zählerwert (TMRx) dem Wert in PRx entspricht, dann wird der Ausgang auf high gesetzt und der Timer beginnt wieder von 0 an zu zählen.
Quelle: Datenblatt des PIC18F45K22
Es handelt sich hier um eine 10 Bit PWM. Der Timer2/4 und 6 und die PRx sowie CCPRxL Register sind aber nur 8 Bit groß. Daher bekommt das CCPRxL Register zwei zusätzliche Bits spendiert. Diese befinden sich im CCPxCON Register (Bit 4 und 5). Die Periode lässt sich hingegen nur mit 8 Bit einstellen, das Tastverhältnis mit 10 Bit. Der Pin an dem das PWM-Signal ausgegeben werden soll, muss von Euch als Ausgang konfiguriert werden. Hierfür ist das TRIS-Bit zu löschen.
Vorgehensweise:
- Timer einstellen
- Periode einstellen
- Tastverhältnis einstellen
- PWM aktivieren
Formel zum Errechnen der Periodendauer:
Formel zum Errechnen von PRx:
Formel zum Errechnen des Tastverhältnisses:
Durch variieren von CCPRxL + CCPxCON<4:5> könnt Ihr die PWM bzw. den Tastgrad des Signals verändern. So lässt sich zum Beispiel die Hintergrundbeleuchtung für ein LC-Display in Abhängigkeit der Umgebungshelligkeit regeln.
Hier ein Beispiel am PIC18F45K22. Das PWM Signal wird an RC2 ausgegeben. Die Bits 4 und 5 des CCP1CON Registers wurden in diesem Beispiel vernachlässigt Snippet
Capture Funktion
Mit der Capture-Funktion des CCP-Moduls eines PIC kann man die exakte Zeit messen, bis ein Pegelwechsel am CCPx Pin eintritt. Das nachfolgende Blockschaltbild verdeutlicht die Funktion.
Quelle: Datenblatt des PIC18F45K22
Für die Funktion wird der Timer 1/3 oder 5 benötigt. Er zählt die Zeit bis das Ereignis am Pin eintritt. Natürlich muss auch der Timer hierfür entsprechend konfiguriert werden. Wenn alles richtig eingestellt ist, kann man mit dem Timer messen, wann sich etwas am Pin CCPx tut. Wenn es zum Beispiel zu einer steigenden Flanke am Pin kommt, wird der Zählerwert des gewählten Timers in den Registern CCPRxH und CCPRxL gesichert. Welchen Timer man verwenden möchte kann man in den Registern CCPTMRS0 und CCPTMRS1 wählen. Wenn ein Capture, also ein Sichern des Zählerwertes des Timers stattgefunden hat, wird das Flag CCPxIF im Register PIR1/2 oder 4 gesetzt. Dies kann einen Interrupt auslösen.
Den CCPx Pin, den Ihr für diese Funktionalität verwenden möchtet, muss als Eingang (zugehöriges TRIS-Bit setzen) konfiguriert werden!
Für das Standard-CCP-Modul, also nicht ECCP, ist das folgende Register entsprechend zu setzen:
CCPxCON (Standard CCPx Control Register)
BIT 7 | BIT 6 | BIT 5…4 | BIT 3…0 | ||||
---|---|---|---|---|---|---|---|
– | – | DCxB<1:0> | CCPxM<3:0> |
CCPxM<3:0> (ECCPx Mode Select bits)
Mit diesen Bits wird eingestellt in welchem Modus sich das CCP Modul befinden soll und ihr könnt einstellen auf welche Ereignisse das Modul reagieren soll: [0100] Jede fallende Flanke [0101] steigende Flanke [0110] 4te steigende Flanke [0111] 16te steigende Flanke Alle anderen Einstellungen sind nicht für den Capture Modus bestimmt.
DCxB<1:0> (PWM Duty Cycle Least Significant bits)
Diese Bits werden im Capture Modus nicht benutzt…
Compare Funktion
Das Compare-Modul ermöglicht es einem ein Signal bzw. einen Flankenwechsel am Pin CCPx zu einem bestimmten Zeitpunkt zu erzeugen. Der Pin, der für diese Aufgabe verwendet werden soll, muss auf Ausgang (Trisbit gelöscht) konfiguriert werden!
Quelle: Datenblatt des PIC18F45K22
Das Modul arbeitet mit dem Timer 1/3 oder dem Timer 5. In den CCPRx-Registern wird ein Wert eingetragen. Wenn nun der Zählerwert des Timers diesen Wert erreicht hat, wird der Flankenwechsel am Pin CCPx ausgeführt. So sind die Einstellungen zum Compare Modus, am Beispiel des PIC18F45K22 für ein Stanard-CCP (nicht ECCP) Modul einzustellen:
CCPxCON (Standard CCPx Control Register)
BIT 7 | BIT 6 | BIT 5…4 | BIT 3…0 | ||||
---|---|---|---|---|---|---|---|
– | – | DCxB<1:0> | CCPxM<3:0> |
CCPxM<3:0> (ECCPx Mode Select bits)
Mit diesen Bits wird eingestellt in welchem Modus sich das CCP Modul befinden soll und ihr könnt einstellen auf welche Ereignisse das Modul reagieren soll: [1000] Pin geht nach eintreten von Low auf High (+CCP1IF) [1001] Pin geht nach eintreten von High auf Low (+CCP1IF) [1010] Ausgang wird nicht verändert (+CCP1IF) [1011] Ausgang wird nicht verändert (+CCP1IF + Timer1 auf 0)
DCxB<1:0> (PWM Duty Cycle Least Significant bits)
Diese Bits werden im Compare Modus nicht benutzt.
Der Captuer Modus kann natürlich auch einen Interrupt erzeugen. Hierbei wird das Flag CCPxIF im PIR1/2 oder 4 Register gesetzt. Sofern der Interrupt eingeschaltet ist, dient das Flag zur Identifikation der Interrupt-Quelle.
Auswahl des Timers
Wie Ihr sicherlich bereits gemerkt habt, könnt Ihr jeweils verschiedene Timer für die Module verwenden. Hier muss natürlich eine Entscheidung getroffen werden. Die Wahl über den zu verwendenden Timer, wird in den Registern CCPTMRS0 und CCPTMRS1 getroffen.
CCPTMRS0
Bit 7…6 | – | Bit 4…3 | – | Bit 1…0 | |||
---|---|---|---|---|---|---|---|
C3TSEL<1:0> | – | C2TSEL<1:0> | – | C1TSEL<1:0> |
Nun schauen wir uns die einzelnen Bits des Registers an.
CxTSEL<1:0> (CCPx Timer Selection bits)
Mit diesen Bits wird dem CCP-Modul ein Timer zugewiesen. Dabei reicht das x von 1-5. Hier einmal am Beispiel für das CCP1: 00: Capture/Compare: Timer1, PWM: Timer 2 01: Capture/Compare: Timer3, PWM: Timer 4 10: Capture/Compare: Timer5, PWM: Timer 6 11: –
CCPTMRS1 (PWM Timer Selection Control Register 1)
BIT 7…4 | BIT 3…2 | BIT 1…0 | |||||
---|---|---|---|---|---|---|---|
– | C5TSEL<1:0> | C4TSEL<1:0> |
Die Bits haben hier die selbe Bedeutung, wie auch schon im CCPTMRS0 Register (siehe oben). Nur, dass es hier um die Zuweisung für die CCP-Module 4 und 5 geht.
Stack
Die PIC18 Familie besitzt einen 32 Level großen Hardware Stack (vgl. PIC16 verfügen lediglich über einen 8 Level Stack). Der Stack ist ein sogenannter Stapelspeicher, der das “hopping” im Programm überhaupt erst ermöglicht. Im Stack wird bei einem Sprung zu einer Funktion/Unterprogramm die Adresse gesichert von der aus gesprungen wurde. Damit bei vollständiger Abarbeitung des Unterprogramms oder der Funktion wieder an diese Adresse zurück gesprungen werden kann. Dabei ist auch die Sichtbarkeit von Variablen zu beachten.
Angenommen Ihr habt eine globale Variable namens “x”. Nun springt ihr in eine Funktion und definiert hier eine neue Variable, die ebenfalls “x” heißt. Dann ist die globale Variable für die Zeit in der Funktion unsichtbar bleibt aber erhalten und ist bei Rückkehr in die obere Ebene des Stack wieder sichtbar.
Inter-Integrated Circuit (I2C)
Sobald euer PIC über ein Master-Synchronous-Serial-Port-Modul (kurz MSSP) verfügt, könnt Ihr damit einen I2C-Bus aufbauen. Somit kann dann ein gewünschtes Bauteil, das selbstverständlich ebenfalls den I2C-Bus verwenden kann, angesprochen werden.
Der I2C Bus besteht aus zwei Leitungen: Serial Clock (SCL) und Serial Data (SDA). Damit der Bus unabhängig von allen Teilnehmern benutzt werden kann, werden die beiden Busleitungen mit Pullup-Widerständen gegen +5V gezogen und die Teilnehmer sind mit Open-Collector-Ausgängen an den Bus angeschlossen. Somit werden Kurzschlüsse vermieden.
Quelle: http://www.nxp.com/documents/other/UM10204_v5.pdf
Die Namen der Leitungen sind Programm: Auf der SCL-Leitung wird der Takt des Bus übertragen, welcher ausschließlich vom Master erzeugt wird. Der Slave hat lediglich die Möglichkeit den Master-Clock gegen Masse zu ziehen, um zum Beispiel zu signalisieren, dass er mehr Zeit benötigt um seine Aufgaben zu erledigen. Auf der SDA-Leitung werden entsprechend die Datenpakete zum Slave (schreibend) oder vom Slave (lesend) übertragen.
Die einzelnen Bits eines Bytes die auf dem Bus egal ob lesend oder schreibend übertragen werden, fangen immer mit dem MSB (höchstwertigstes Bit) an. Während die SCL-Leitung im High-Zustand ist, darf auf der SDA-Leitung nichts mehr geändert werden (dies würde sonst als Befehl interpretiert). Ein Bit wird mit einem SCL-Impuls übertragen, dazu später mehr. Ihr müsst dem PIC mitteilen mit welcher Taktgeschwindigkeit ihr den IC2 Bus betreiben möchten. Dazu ist es notwendig das Register SSPADD mit einem passenden Teilerwert zu beschreiben. Dieser errechnet sich wie folgt:
Beispiel anhand eines SCL-Taktes von 50 kHz und einem 8 MHz-Quarz als Taktgeber für den PIC:
Die Pullup-Widerstände an SDA und SCL dürfen nicht vergessen werden. Andernfalls kann keine Kommunikation zustande kommen.
Start/Stop
Die nachfolgende Grafik zeigt eine Start- und Stop-Sequenze auf dem I2C-Bus. Schauen wir uns einmal an, was es damit auf sich hat.
Quelle: http://www.nxp.com/documents/other/UM10204_v5.pdf
Der I2C-Bus wird im wesentlichen in drei verschiedenen Geschwindigkeiten betrieben: 3,4 Mbit/s (Highspeed), 400 kbit/s (Fast) und mit 100 kbit/s (Standard). Dabei gilt es auch immer im Datenblatt der verwendeten Slaves zu beachten, welche Taktgeschwindigkeiten diese unterstützen. Zum Beispiel ist es bei einem DS1307 nicht empfehlenswert den Takt oberhalb von 100 kHz (Standard) zu betreiben, da dies die absolute Grenze bei diesem Baustein ist.
Jede Aktion auf dem Bus wird vom Master über die I2C-Start-Sequenz initiiert. Dazu muss sich der Master vergewissern, dass der Bus derzeit frei (SCL und SDA sind high) ist und beginnt dann mit seiner Arbeit. Streng genommen ist das eigentlich nur bei Multi-Master-Systemen notwendig. Für eine Start-Sequenz zieht der Master das Potential von SDA auf low und zwar während SCL auf high ist. In umgekehrter Reihenfolge entspricht das einer Stop-Sequenz.
Neben der Start- und Stop-Sequenz gibt es noch die Restart-Sequenz. Ein Restart kann immer dann ausgeführt werden, wenn man auch eine Stop-Sequenz ausführen dürfte. Verwendet wird der Restart um den Bus nach dem Beenden des aktuellen Transfers zu (be)halten. Vom Effekt her hat der Restart die selbe Auswirkung wie ein Start.
Adressierung
Hat ein Master erst einmal eine Start-Sequenz auf dem Bus eingeleitet, werden alle am Bus angeschlossenen Slaves hellhörig und wollen nun wissen an wen sich der Master richtet. Dafür überträgt der Master nun eine Adresse, die eindeutig zu einem der am Bus angeschlossenen Slaves passt. Alle anderen, deren Adresse nicht mit der ausgesandten übereinstimmt, interessieren sich nun nicht mehr für die folgenden Daten. Die Adresse der Slaves, also die, die vom Master gesendet wird ist anders als die Datenpakete lediglich 7 Bit lang! Das fehlende Bit des Adressbytes ist ein Richtungsbit. Dieses Bit sagt aus ob der Master Daten zum Slave schicken möchte [0] oder ob er Daten vom Slave haben möchte [1]. Da die Adresse auf 7 Bit begrenzt ist folgt, dass sich maximal 128 Teilnehmer (selten gibt es einen 10 Bit Modus) am Bus befinden können. Das Richtungsbit ist stets das niederwertigste Bit!
Acknowledge (ACK)
Immer nachdem 8 Bits übertragen wurden folgt ein ACK oder NACK (not Acknowledge). Dabei handelt es sich also um das 9. Bit einer Übertragung. Das ACK-Bit ist low aktiv. Die nachfolgende Grafik zeigt ein ACK auf dem I2C Bus, siehe 9. Bit.
Quelle: http://www.nxp.com/documents/other/UM10204_v5.pdf
Ein Beispiel: Wenn sich ein Slave durch Übereinstimmung der Adresse angesprochen fühlt quittiert er dieses mit einer ACK-Sequenz (Acknowledge). Die Datenpakete, die dem Adressierungsbyte folgen müssen ebenfalls mit einem ACK vom Slave bestätigt werden. Folgt auf ein gesendetes Byte ein NACK ist die Übertragung fehlgeschlagen und der Master muss die Übertragung dieses Bytes wiederholen. Ein ACK sieht auf dem Bus so aus: Der Master überträgt mit 8 Impulsen auf SCL die einzelnen Bits des Bytes auf SDA (angefangen mit MSB) und erzeugt im Anschluss einen 9. Impuls auf SCL. Wenn der Zustand beim 9. Takt einen Low Zustand auf SDA aufweist (vom Slave auf Low gezogen, nicht vom Master!), dann ist es ein ACK, der Slave ist einverstanden. Ist der Zustand hingegen High, so ist es ein NACK, der Slave ist nicht einverstanden.
Betrachten wir ein weiteres Beispiel: Wenn ein Master Daten von einem Slave erhalten möchte, prüft er zunächst ob der Bus frei ist. Wenn er frei ist, sendet er ein Start gefolgt von der 7 Bit langen Adresse des Slaves (schreibend, also ist Bit #0 = 0) den er ansprechen möchte. Der Slave antwortet mit ACK. Daraufhin sendet der Master i.d.R. eine Adresse eines Registers, das er beim Slave auslesen möchte (das hat nichts mit den I2C-Adressen zu tun). Der Slave quittiert wieder mit ACK. Der Master beendet die Kommunikation mit Stop oder führt ein Restart durch. Nun schickt er erneut die (I2C-)Adresse des Slaves. Aber nun mit der Angabe, dass er lesen möchte, also ist das Bit #0 diesmal eine ‘1’. Der Slave antwortet wieder mit ACK, woraufhin der Slave damit beginnt die Daten, die sich an der Adresse befinden, die ihm der Master zuvor mitgeteilt hat, über den Bus an den Master zu übermitteln (der Master gibt dabei immer den Takt vor). Je nachdem wie viele folgende Register der Master auslesen will quittiert er mit ACK (…noch ein Byte mehr lesen). Wenn der Master genug gelesen hat, beendet er mit einem NACK (das reicht, ich brauche kein weiteres Byte) und folgender Stop-Sequenz.
Hier mal eine Aufzeichnung einer I2C-Kommunikation:
Offensichtlich wird hier ein Teilnehmer mit der Adresse 0xA0 angesprochen, es sollen Daten von ihm gelesen werden (das 9. Bit ist eine ‘1’). Der angesprochene antwortet mit ACK. Danach sieht man, dass der angesprochene Teilnehmer damit beginnt Daten an den Anfragenden auszugeben.
C-Routinen
In der Codesammlung gibt es für den PIC18F45K22 ein Code-Beispiel zum I2C-Bus. Schaut euch auch mal folgendes PDF von Microchip an (englisch) I2C Master Mode .
Serial Peripheral Interface (SPI)
Schaut Euch ergänzend auch gerne das Einsteiger-PDF zum SPI Bus von Microchip an. Es ist ziemlich gut erklärt. Das Serial Peripheral Interface (kurz SPI) ist ein von Motorola entwickeltes Bus-System mit einem sehr lockeren Standard für einen synchronen seriellen Datenbus, mit dem digitale Schaltungen nach dem Master-Slave-Prinzip miteinander verbunden werden können. Ein ähnliches Bus-System existiert von National Semiconductor und nennt sich Microwire.
Für den Bus sind die nachfolgend aufgeführte Leitungen notwendig an denen alle Busteilnehmer angeschlossen sind:
-
- SDO (zu Englisch Serial Data Out) bzw. MISO oder SOMI (zu Englisch Master in, Slave out)
- SDI (zu Englisch Serial Data In) bzw. MOSI oder SIMO (zu Englisch Master out, Slave in)
- SCK (zu Englisch Serial Clock) bzw. SCLK, wird vom Master ausgegeben
Zusätzlich wird für jeden am Bus angeschlossenen Slave eine weitere Leitung benötigt. Diese Leitung wird ¬Slave select (kurz ¬SS) genannt und ist in den meisten Fällen low aktiv. Das bedeutet, dass wenn der Master eine ¬SS-Leitung auf low zieht, dann ist dieser Slave angesprochen und reagiert auf folgende Daten. Die SS Leitung kann durch jeden beliebigen I/O des PIC realisiert werden. Da der SPI Bus, wie zu Beginn dieses Abschnitts bereits erwähnt, sehr locker definiert ist, sind viele Parameter frei konfigurierbar. Das war auch einer der Gründe weshalb sich dieses Bussystem so weit verbreitet hat.
Der SPI Bus beim PIC
Viele PIC unterstützen die Verwendung des SPI Bus. Dafür werden entsprechende Module zur Verfügung gestellt. Es kann entweder das SSP oder das MSSP Modul verwendet werden. Eine Datenübertragung findet logischerweise nur statt, wenn der Clock aktiv ist. Wobei wir auch bei einem weiteren wichtigem Punkt sind: Der Takt auf der SCK Leitung wird ausschließlich vom Master generiert. Um das SPI bzw. das SSP/MSSP Modul nutzen zu können ist es vorweg nötig das Modul entsprechend zu konfigurieren. Das zuständige Register ist das SSPCON Register:
-
- SSPOV: Wird gesetzt wenn es einen Überlauf gab und muss vom Programmierer zurück gesetzt werden.
- SSPEN: Ein-/ Ausschalten (Strom sparen) des SSP-Moduls.
- CKP: Einstellen der Takt Polarität.
- SSPM3:SSPM0 (4 Bits):
SSPOV
Das SSPOV Bit ist der Indikator für ein eventuell aufgetretenes Überlaufen des Puffers. Nachdem ein Byte empfangen wurde muss dieses aus dem Puffer (Register SSPBUF) ausgelesen werden. Wenn das nicht erfolgt, wird SSPOV gesetzt. Außerdem wird der Inhalt des Puffers nicht mehr aktualisiert, solange das Bit gesetzt ist! Das Bit muss eigenhändig wieder gelöscht werden!
SSPEN
Wie es der Name des Bits schon vermuten lässt, wird durch das setzten dieses das SSP Modul aktiviert bzw. wird es deaktiviert wenn das Bit gelöscht ist. Ein löschen des Bits und somit das deaktivieren ist empfehlenswert bei low power Anwendungen um Stro zu sparen. Es versteht sich von selbst, dass das Bit nicht gelöscht werden darf, solange das SSP Modul in Benutzung ist.
CKP
Dieses Bit konfiguriert die Polarität des Taktes…
SSPM#
Die vier Bits von SSPM0 bis SSPM3 sind zuständig um den SPI Mode einzustellen. Wenn der Master Mode eingestellt ist, wird mit diesen Bits zusätzlich die Clock Frequenz geregelt. Näheres steht dann im Datenblatt eures PIC.
Ein weiteres Register, welches direkt mit dem SPI Bus bzw. mit dem SPI Bus in Bezug auf den PIC zu tun hat ist das SSPSTAT Register (Synchronous Serial Port STATus), welches den aktuellen Status des Moduls wieder spiegelt:
-
- SMP: Bitte Detailbeschreibung lesen.
- CKE: Bitte Detailbeschreibung lesen.
- BF: Buffer full sagt, wenn eine Übertragung abgeschlossen ist.
SMP
Quelle: http://ww1.microchip.com/downloads/en/DeviceDoc/41412F.pdf
Das Bit SaMPle timing (kurz SMP) kontrolliert die Daten Absatzrate. Wenn der PIC als Slave betrieben wird muss dieses Bit durch den Programmierer gelöscht werden. Wenn Ihr dieses Bit setzt, dann werden die Daten auf SDI am Ende der Ausgabe erfasst. Ist das Bit hingegen gelöscht, so werden die Daten in der Mitte erfasst. Seht euch einfach mal die Grafik dazu an.
CKE und CKP
Das CKE Bit muss in Zusammenhang mit dem CKP Bit gesehen werden. Wenn das CKE Bit gesetzt wird, dann werden die Daten beim Wechsel des Potentials auf der SCKx Leitung von Aktiv zu Leerlauf (idle) versendet. Ist das CKE Bit gelöscht, dann beim Wechsel von Leerlauf zu Aktiv. Dies muss dann wie gesagt immer im Zusammenhang mit dem CKP Bit betrachtet werden. Es ergeben sich somit vier verschiedene Clock Modes, welche sehr schön aus der Tabelle ersichtlich sind.
SPI MODE | CKP | CKE |
---|---|---|
0,0 | 0 | 1 |
0,1 | 0 | 0 |
1,0 | 1 | 1 |
1,1 | 1 | 0 |
Die grün geschriebenen Parameter bzw. der grün geschriebene SPI Mode ist der am häufigsten verwendete Mode.
BF
Dieses Bit sagt aus ob eine Konversation abgeschlossen ist oder eben noch läuft. Sobald dieses Bit logisch 1 ist, muss der Puffer SSPBUF ausgelesen werden. Das Bit wird automatisch gelöscht, sobald der Puffer gelesen wurde. Nochmal: Der Puffer muss nach empfangenen Daten gelesen werden! Ist das BF Bit 1 und das SSPBUF Register wird nicht ausgelesen, wird automatisch SSPOV gesetzt.
Q: Aber wie sagt man dem PIC denn nun, was gesendet werden soll? Oder wo kann ich die empfangenen Daten her holen?
A: Das zu übertragende Byte wird in das SSPBUF Register gelegt und automatisch versendet.
Beispiel: Schaut hier in der Codesammlung mal vorbei. Dort gibt es ein einfaches Beispiel zum Übertragen von Daten über den SPI Bus.
Die serielle Schnittstelle (EUSART/UART)
Das EUSART-Modul (Enhanced Universal Synchronous Asynchronous Reseiver Transmitter) bietet die Möglichkeit eine einfache serielle Verbindung aufzubauen. Das Modul kann entweder als synchrones Modul im Halb-Duplex-Verfahren oder aber als wesentlich interessanteres asynchrones Modul im Voll-Duplex-Verfahren eingesetzt werden. Der asynchrone Betrieb ist sehr beliebt um beispielsweise eine Verbindung zum COM-Port eines Computers herzustellen, besser bekannt unter dem Begriff “RS232”. Wer jetzt sagt: “Eine serielle Schnittstelle RS232-Schnittstelle an modernen Computern?” hat mit seiner Verwirrung vollkommen recht. Euch möchte ich folgenden Artikel ans Herz legen FTDI – FT232RL.
Zum Aufbau der seriellen Verbindung benötigt man lediglich zwei IOs des PIC-Controllers. Eine Leitung zum Senden TX und eine zum Empfangen im Vollduplex-Betrieb RX. In der Regel dienen hierzu die Pins RC6 und RC7 wobei neuere PIC-Typen über mehrere EUSART-Module verfügen. Die IO-Pins des Controllers werden als Open-Collector betrieben, damit es zu keinen Kurzschlüssen auf dem Bus kommen kann.
Protokoll
Das Protokoll der UART-Schnittstelle ist denkbar einfach. Übertragen werden Rohdaten mit einer Größe von acht Bit. Zusätzlich wird ein vorangehendes Startbit, ein oder wahlweise zwei nachfolgende(s) Stoppbit(s) sowie, wenn gewünscht ein Paritätsbit (gerade oder ungerade). Somit besteht ein vollständiges Datenpaket aus mindestens 10 bis maximal 12 Bits, siehe:
Die Spezifikation sieht vor, dass eine logische 1 (auch als Mark bezeichnet) mit einem Pegel von -12V und eine logische 0 (auch als Space bezeichnet) mit einem Pegel von +12V übertragen wird. Sprich, die Pegel auf dem Medium können als invertiert in Bezug zu den logischen Pegeln betrachtet werden. Natürlich gibt der Mikrocontroller keine Pegel von +/-12V an seinen Pins aus. Hierfür gibt es entsprechende Pegelwandler-ICs wie zum Beispiel den MAX232 . Wenn man aber zum Beispiel eine Verbindung über UART zu modernen PCs herstellen möchte, die in aller Regel keinen RS232-Anschluss mehr besitzen, so greift man auf so genannte USB/Seriell-Konverter zurück. Ein sehr prominenter Vertreter ist der FT232RL von FTDI. Dieser übernimmt alle Umwandlungen jeglicher Pegel und bietet die Möglichkeit den USB-Anschluss am Rechner zu nutzen um eine virtuelle serielle Verbindung mit einem Controller herzustellen. Siehe den verlinkten Artikel für mehr Details.
Initialisierung
Damit das EUSART-Modul (oder USART, UART) eines PIC-Controllers verwendet werden kann, muss dieses natürlich zunächst entsprechend den Anforderungen konfiguriert werden. Die Konfiguration gestaltet sich ausgesprochen einfach, wie wir jetzt sehen werden. Als erstes schauen wir uns das Register TXSTAX (Transmit Status And Control Register) an.
BIT 7 | BIT 0 | ||||||
---|---|---|---|---|---|---|---|
CSRC | TX9 | TXEN | SYNC | SENDB | BRGH | TMRT | TX9D |
TX9D (neuntes Datenbit)
Dieses Bit stellt den Inhalt im Falle einer 9-Bit-Datenübertragung und ist für den normalen RS232-Anwendungsfall uninteressant.
TMRT (Transmit Shift Register Status Bit)
Das Timer Shift Register zeigt an ob das Ausgangs-Schieberegister leer oder voll ist. Wir werden das Bit jedoch nicht gebrauchen. Eine abgeschlossene Übertragung ermitteln wir später durch das zum Modul zugehörige TX-Interrupt-Flag.
BRGH (High Baud Rate Select Bit)
Dieses Bit wird ausschließlich im asynchronen Modus verwendet um zwischen hoher (1) und niedriger (0) Baudrate zu unterscheiden. Je nach gewünschte Baudrate muss dieses Bit gesetzt oder gelöscht werden. Im Datenblatt des verwendeten PIC gibt es entsprechend Tabellen mit diversen Baudraten sowie der dazu passenden Einstellung für das BRGH-Bit. Zusätzlich besteht hier eine Abhängigkeit zur verwendeten Taktquelle des PIC.
SENDB (Send Brake Character Bit)
Dieses Bit wird ebenfalls ausschließlich im asynchronen Modus verwendet um zum Beispiel dem LIN-Bus-Spezifikationen eines bestimmten Break-Codes zu entsprechen. Im normalen RS232-Betrieb wird dieses Bit nicht verwendet.
SYNC (Mode Select Bit)
Mit diesem Bit wird zwischen dem üblicherweise verwendetem asynchronen Modus (0) oder dem synchronen Modus (1) gewählt.
TXEN (Transmit Enable Bit)
Dieses Bit schaltet das Modul ein (1) oder aus (0).
TX9 (9-Bit Transmit Enable Bit)
Wenn dieses Bit auf ‘1’ gesetzt wird, können neun statt der üblichen acht Bits pro Daten (netto) übertragen werden. In der Regel verwenden wir jedoch den normalen Modus mit 8 Datenbits und setzten das Bit folglich auf ‘0’.
CSRC (Clock Source Select Bit)
Im synchronen Modus wählt man mit diesem Bit aus, ob der PIC als Master (1) oder als Slave (0) fungieren soll. Im asynchronen Modus ist das Bit hingegen irrelevant.
Als nächstes betrachten wir das RCSTAX Register (Receive Status And Control Register).
BIT 7 | BIT 0 | ||||||
---|---|---|---|---|---|---|---|
SPEN | RX9 | SREN | CREN | ADDEN | FERR | OERR | RX9D |
RX9D (neuntes Datenbit)
Wie schon im entsprechenden TX-Register dient dieses Bit für die optionale 9-Bit-Daten-Kommunikation.
OERR (Overrun Error Bit)
Das Überlaufbit wird gesetzt, wenn der Empfangs-FIFO übergelaufen ist. Solange das Bit nicht gelöscht wird (durch Löschen des CREN Bits im RCSTAx-Register), können keine neuen Zeichen/Daten über den Bus empfangen werden.
FERR (Framing Error Bit)
Wenn in einem Datenpaket ein Stopp-Bit nicht erkannt wurde, wird das FERR-Bit gesetzt. Das Bit kann ausschließlich gelesen werden. Es ist nicht notwendig das Bit zu löschen. Sobald das nächste Zeichen eingelesen wird, wird das Bit wieder aktualisiert.
ADDEN (Address Detect Enable Bit)
Dieses Bit ist ausschließlich im 9-Bit-Modus relevant.
CREN (Continous Receive Enable Bit)
Im asynchronen-Modus wird mit einer ‘1’ das Empfangs-Modul aktiviert und mit einer ‘0’ deaktiviert. Im synchronen-Modus hingegen wird der dauerhafte Empfang aktiviert (1) oder deaktiviert (0).
SREN (Single Receive Enable Bit)
Im asynchronen-Modus ist dieses Bit nicht von Interesse. Ebenso, wenn der Controller im 9-Bit-Slave-Modus betrieben wird.
RX9 (9-th Receive Enable Bit)
Mit diesem Bit wird zwischen 9-Bit-Kommunikation (1) oder 8-Bit-Kommunikation (0) unterschieden. In der Regel verwenden wir den 8-Bit-Modus.
SPEN (Seriel Port Enable Bit)
Mit einer ‘1’ in diesem Bit wird das Empfangs-Modul aktiviert, mit einer ‘0’ deaktiviert.
Im BAUDCONx-Register werden Einstellungen zur Baudrate getätigt. Außerdem befinden sich ein paar Flags in diesem Register.
BIT 7 | BIT 0 | ||||||
---|---|---|---|---|---|---|---|
ABDOVF | RCIDL | DTRXP | CKTXP | BRG16 | – | WUE | ABDEN |
In diesem Register interessiert uns im Wesentlichen nur da Bit BRG16. Mit diesem Bit lässt sich zwischen 8 und 16-Bit-Baudgenerator unterschieden. Dies ist wichtig um später die richtige Baudrate auf Grundlage des PIC-Taktgebers zu generieren. Hierfür ist zusätzlich das Register SPBRGx wichtig. Der notwendige Wert für die gewünschte Baudrate kann wie folgt berechnet werden:
Das Ergebnis wird entsprechend Integer im Nachkomma-Bereich abgeschnitten und auf die beiden Register (SPBRGHx und SPBRGx) aufgeteilt.
Anwendung
An dieser Stelle möchte ich lediglich in aller Kürze Codeschnipesel zur Verfügung stellen. Als erstes den Code (am Beispiel eines PIC18F45K22) zur Initialisierung des EUSART-Moduls zum Verwenden der asynchronen UART im 8 Bit Modus. Die Baudrate ist dabei auf 9600 bit/s konfiguriert.
void initEUSART(void) { TXSTA = 0b00100000; RCSTA1 = 0b10010000; BAUDCON1bits.BRG16 = 0; SPBRG1 = 12; IPR1bits.RC1IP = 1; PIE1bits.RC1IE = 1; }
Der nächste Codeschnipsel zeigt eine Funktion die zum Aussenden eines Datenpaketes verwendet werden kann.
void transmitEUSART(char value) { /*are you ready to send out new data?*/ if(PIR1bits.TX1IF) { /*load the byte into the buffer*/ TXREG1 = value; } }
Zu guter letzt eine entsprechende Interrupt-Service-Routine, die beim Empfang eines neuen Datenpaketes (über die RX-Leitung) aufgerufen wird. Beachte, dass die Priorität auf hoch gesetzt wurde.
char eusartInput; // ... void interrupt highPrio(void) { /*is there an unreaded byte in the buffer?*/ if(PIR1bits.RC1IF == 1) { /*clear int-flag by readout the buffer*/ eusartInput = RCREG1; } }
Dabei ist die Initialisierung von oben bereits so geschrieben, dass der Interrupt für empfangene Pakete aktiviert ist (zusätzlich muss wie immer die globale Aktivierung für Interrupts erfolgt sein).
Interrupts
Oftmals kommt es vor, dass der PIC auf ein bestimmtes Ereignis sofort reagieren soll. Nun verwendet man hierfür als Anfänger gerne mal das so genannte “Polling”. Der Mikrocontroller soll, sobald am Eingang der Wahl eine Zustandsänderung eintrifft eine LED schalten. Hierfür zwei Lösungsmöglichkeiten.
Das Polling: Beim Polling würden wir nun in einer Schleife solange den Zustand von dem Pin abfragen, bis er den erwarteten Zustand erreicht hat und anschließend mit dem Schalten der LED fortfahren. Das ist sicherlich eine Möglichkeit, allerdings ist sie wenig Sinnvoll, da der Mikrocontroller sich ausschließlich damit beschäftigen kann den Zustand vom Port-Pin abzufragen.
Interrupts: Mit einem Interrupt wäre dieses Problem deutlich eleganter gelöst. Wir setzten gewisse Steuerbits, welche bewirken, dass sobald sich der Zustand am Eingang ändert, der PIC seinen aktuellen Befehl noch ausführt und im Anschluss sofort zu einer bestimmten Adresse springt und den Code abarbeitet den er dort findet. Es wird also im Prinzip ein Unterprogramm automatisch aufgerufen. Der große Vorteil daran ist, dass wir während wir auf die Zustandsänderung am Eingang warten trotzdem parallel noch weiter arbeiten können!
Interrupt-Quellen
Der PIC kann natürlich nicht nur beim Ändern des Zustandes an einem Eingang einen Interrupt auslösen. Es gibt diverse Möglichkeiten, die einen Interrupt auslösen können. Ihr könnt die Interrupt Quellen des PIC im Kapitel Device Overview oder im Kapitel Interrupts (siehe Interrupt Logic) im Datenblatt nachlesen. Nachfolgend ein paar Quellenbeispiele:
Interrupt on change
Dieser Interrupt wurde oben schon angesprochen. Er löst aus, sobald an einem Pin ein Zustandswechsel auftritt, dabei unterscheidet man zwischen fallender und steigender Flanke des Signales. Hierbei gilt es schon beim Schaltungsdesign darauf zu achten, dass nur einige wenige Pins für diesen Interrupt geeignet oder besser gesagt vorgesehen sind. Ihr erkennt diese an der Doppelbelegung mit ‘INTx’ – mit x = 0, 1, ….
Timer Interrupt
Dieser Interrupt wird ausgelöst, sobald ein Timer überläuft. Sprich, sobald der Zähler wieder bei 0 anfängt zu zählen, wird dieser Interrupt ausgelöst.
EUSART
Auch das serielle Interface kann einen Interrupt auslösen. Wenn das Modul ein Datenpaket empfängt und dieses in den Buffer lädt, kann ein Interrupt ausgelöst werden, so dass der Controller die empfangenen Daten sofort auslesen kann.
Konfiguration von Interrupts
Natürlich funktionieren die Interrupts nicht “einfach so” ohne jegliches Zutun. Interrupts sind im Normalfall deaktiviert bzw. verboten. Damit man einen Interrupt benutzen kann, muss man das entsprechende Enable-Bit setzten, welches den Interrupt zulässt. Außerdem muss maneine globale Freigabe für Interrupts freigeben, man muss das GIE Bit setzten. Dieses Bit ist das Global-Interrupt-Enable-Bit und verbietet beim Zustand ‘0’ alle Interrupts. Das bedeutet jedoch nicht, dass im Umkehrschluss, wenn dieses Bit gesetzt ist, dass alle Interrupts erlaubt sind. Jeder Interrupt hat ein weiteres Kontrollbit (Enable Bit).
Außerdem hat jeder Interrupt ein eigenes Flag, welches das Auftreten eines Interrupts signalisiert. Zum Beispiel wird bei einem Timer0 überlauf das Bit T0IF Bit gesetzt, somit weiß der PIC, dass der Timer0 einen Interrupt auslösen möchte, dieses wird aber nur passieren, wenn das zugehörige Enable Bit T0IE (Timer0 Interrupt Enable) Bit ebenfalls “1” ist und zusätzlich das GIE Bit die Interrupts überhaupt zulässt.
Bei den PIC18F-Typen werden verschiedene Interrupt Prioritäten unterschieden (Low & High). Diese haben auch zwei unterschiedliche Interrupt-Vektoren. Daher gibt es bei den PIC18F-Typen auch zwei globale Enable-Bits. Einmal das GIEL und das GIEH Bit. Ist das GIEL Bit auf disable, so können keine Interrupts, welche als “Low priority” deklariert sind ausgeführt werden – “high priority” Interrupts hingegen schon, sofern das GIEH Bit auf enable steht. Ist hingegen das GIEH Bit aus disable, können weder Low noch High- priorisierte Interrupts ausgeführt werden. Wir stellen also fest, dass das GIEH Bit übergreifend auch die niedrig priorisierten Interrupts sperren kann aber nicht umgekehrt! Für verschiedene Interrupt Prioritäten müsst Ihr das Bit IPEN im Register RCON setzten.
Die Priorität eines Interrupts wird mit dem zugehörigen Priority-Bit eingestellt. Diese sind auf verschiedene Register verteilt. Man findet jedoch mit Hilfe des Datenblatts sehr schnell heraus, wo das entsprechende Bit zu finden ist. Wird ein Priority-Bit gesetzt, so hat der zugehörige Interrupt eine hohe Priorität. Wird das Bit hingegen gelöscht, so ist die Priorität niedrig. Ein Interrupt mit einer niedrigen Priorität kann von einem Interrupt mit hoher Priorität unterbrochen werden! Umgekehrt st das logischerweise nicht möglich.
Programmieren eines Interrupts
Schaut Euch hierzu mal das folgende Beispiel an, das den Interrupt des Timer0 konfiguriert.
Das Konfigurationswort
Das Konfigurationswort eines PIC gibt spezielle Einstellungen an, welche für den PIC zum Arbeiten unabdingbar sind. Das entscheidende hierbei ist, dass der PIC dieses Wort (auch als Fuses bezeichnet) nicht selber verändern kann. Wenn die Fuses einmal beim Brennen gesetzt sind bleiben sie so. Man legt durch die Fuses grundlegende Hardware Einstellungen fest, welche angegeben werden müssen. Man kann das Konfigurationswort entweder manuell in den Programmcode eingeben, oder aber setzt die gewünschten Option in der IDE.
Erklärungen des Codes
Hier sind einmal die für den Einstieg in die PIC µC Welt wichtigsten Einstellungsmöglichkeiten in einer Tabelle aufgelistet:
FUNKTION | KURZBESCHREIBUNG |
---|---|
Taktgenerator | Gibt an mit welcher Frequenzkategorie der PIC arbeitet |
Power up Timer | Kann einen verzögerten Start des PIC hervorrufen (sinnvoll) |
Watchdog Timer | Kann einen Reset auslösen, wenn der PIC abstürzt |
Code protection | Wer seinen Code vor Spionage schützen möchte |
MCLR | Hier kann die Reset Funktion deaktiviert werden (bringt einen I (Input) Pin mehr |
LV Programming | Kann eine Programmierung mit 5V ermöglichen (kostet einen IO-Pin) |
Brown out Reset | Kann einen Reset auslösen, wenn die Betriebsspannung einbricht |
Taktgenerator
Bei dieser Option müssen Sie den richtigen Taktbereich auswählen, damit der PIC weiß, mit welcher Frequenz gearbeitet wird. Sie finden die Entsprechende Einstellung im Datenblatt. Hier ein Überblick:
LP | 32 kHz – 200 kHz | Quarz, Keramikresonator, Extern |
XT | 100 kHz – 4 MHz | Quarz, Keramikresonator, Extern |
HS | 4 MHz – 20 MHz | Quarz, Keramikresonator, Extern |
RC | 30 kHz – 4 MHz | Widerstand – Kondensator Kombi |
Power up Timer
Durch das aktivieren dieser Funktion startet der µC mit 72 ms Verspätung. Diese Option ist eigentlich immer Sinnvoll!
Watchdog Timer
Der Watchdog Timer ist ein weiterer Hardwaretimer, welcher den PIC resetet sobald der Timer überläuft. Ist diese Funktion aktiviert, muss der Timer in regelmäßigen Abständen gelöscht werden!
Code protection
Diese Funktion schützt Euren Programmcode vor Diebstahl. Wenn Ihr ein Programm geschrieben habt, welches Ihr nicht veröffentlichen möchtet, könnt Ihr mit dieser Funktion den Code schützen.
MCLR (Master clear reset)
Oftmals ist es ja überhaupt nicht notwendig, dass ein PIC per Tastendruck resetet werden kann. Daher kann der MCLR Pin (RA5) auch als Eingang (nur als Eingang) benutzt werden.
LV Programming
Diese Funktion ist für Einsteiger weniger Interessant. Sie ermöglicht das Brennen mit 5 anstatt 12V Programmierspannung. Geht aber auf Kosten von einem IO Pin!
Brown out Reset
Der Brown out Reset schützt den PIC davor fehlerhaft zu arbeiten, wenn ein Spannungseinbruch passiert ist. Der Brown out Reset überprüft ständig die Betriebsspannung des PIC. Sobald diese für mindestens 0,1 ms unter 4V fällt, wird ein Reset ausgelöst sobald die Spannung wieder im sicheren Bereich ist und 72 ms vergangen sind. Bei PIC18F ist die Schwelle einstellbar!
Gut zu wissen
Hier entsteht eine kleine Sammlung mit Dingen die immer wieder falsch gemacht werden bzw. zu Problemen führen. Für Hinweise per Mail oder als Kommentar unter diesem Tutorial bin ich immer dankbar.
Was ist Fosc, Tosc und Tcy
ist die Taktfrequenz der Signalquelle, die wir an unseren PIC anschließen (zum Beispiel ein Quarz).
ist dementsprechend die Periodendauer der Frequenz
. Man errechnet
mit
. Da ein PIC zum Bearbeiten eines Befehls 4 Taktzyklen (
) benötigt, errechnet sich
(also die Zeit zum Bearbeiten eines Befehls) durch
.
Beispiel: An einem PIC ist ein 4 MHz Quarz angeschlossen.
Durch die Tatsache, dass der PIC vier Taktzyklen zum Abarbeiten eines Befehls benötigt, ist der interne Befehlstakt . Also benötigt der PIC zum abarbeiten eines Befehls:
Offene Pins am Controller
Wenn es vorkommt, dass Ihr nicht alle Pins des Mikrocontrollers braucht, dann habt ihr zwei Möglichkeiten: Ihr schaltet die Pins in der Software auf Ausgang und weist Ihnen idealerweise den Wert ‘0’ zu (in diesem Fall keine externe Beschaltung vorsehen um die Gefahr eines Kurzschlusses zu vermeiden) oder Ihr legt die nicht verwendeten Pins (Eingänge) über entweder externe oder interne (falls vorhanden) Pull-up/down-Widerstände auf ein definiertes Potential. Nicht verwendete Eingänge sollten niemals offen gelassen werden. Sie können zum Schwingen führen und verursachen unter Umständen einen erhöhten Stromverbrauch. Siehe hierzu auch folgende Artikel [1], [2 siehe Unused Port Pins] und [3 siehe 2.3.2 Dynamische Verluste…]
Achtung bei RA4
Immer wenn Ihr den PIN RA4 eines PIC als Ausgang benutzen wollt müssen bei Euch die Alarmglocken angehen (dies bezieht sich lediglich auf PIC16F), denn dieser Pin ist bei vielen PIC16F Typen nur ein Open Drain Pin und ist somit nicht in der Lage, ohne einen extra Pull up Widerstand, sein Potential allein auf 5V zu ziehen!
In circuit serial programming
Wer kennt das nicht: Für die Entwicklung einer Software muss der PIC mehrmals geflasht und anschließend die Software in der Schaltung getestet werden. Es ist nervtötend andauernd den PIC immer wieder aus der Fassung der Schaltung zu entnehmen, dann in die Fassung des Brenners zu stecken und dann wieder anders herum. Es gibt hierfür eine Lösung und die nennt sich In Cuircuit Serial Programming oder kurz ICSP. Das bedeutet der PIC wird in seiner fertigen Schaltung gebrannt ohne ihn entnehmen zu müssen. Damit die ICSP Funktion benutzt werden kann müssen ein paar Vorkerungen getroffen werden:
Es werden folgende Leitungen benötigt:
, Leitung mit der Programmierspannung
, Leitung mit der Versorgungsspannung für PIC
, Leitung für Masse
, die Datenleitung zum Programmieren
, die Taktleitung zum Programmieren
Die Leitungen werden wie folgt angeschlossen:
ICSP LEITUNG | ANSCHLUSS AM PIC |
---|---|
Programmierspannung [ |
an den PIN MCLRE |
Versorgungsspannung [ |
an den/die Pin(s) |
Masseleitung [ |
an den/die Pin(s) |
Taktleitung [ |
an den Pin RB6 |
Datenleitung [ |
an den Pin RB7 |
Hier seht Ihr die ICSP-Beschaltung am Beispiel des PICKit3 von Microchip:
Schlusswort
Ich hoffe, dass ich Euch mit diesem kleinen Tutorial den Einstieg in die PIC-Mikrocontroller-Welt etwas versüßen konnte. Gerne könnt Ihr eure Meinung und Kritik als E-Mail oder als Kommentar im Forum abladen. Oder schreibt direkt einen Kommentar hier unter diesen Artikel. Ich freue mich über jede Rückmeldung.
Siehe auch
- Wozu dienen Kondensatoren ganz nah am IC?
- PIC Mikrocontroller Grundlagen
- deutsches PIC-Mikrocontroller-Forum
- PIC-C-Tutorial
Danke
Top Hilfe für alle PIC18 Einsteiger!
Hallo Nico
toll wie du hier so viele Informationen umfangreich und übersichtlich zusammengefasst hast!
Sehr praktisch für mich um den Einstieg in neue noch nicht verwendete Funktionen zu bekommen und um einfach mal wieder was nachzulesen.
Hab meinen PIC-Einstieg mit einem pic16f… vor längerem mit der Website von Sprut gehabt, verwende jetzt jedoch auch nur noch pic18f…
Ich will demnächst eine Funktstrecke aufbauen, werd mir deshalb jetzt mal deinen NRF24L01+ Beitrag zu Gemüte führen.
Viele Grüße und weiter so!
Vielen Dank! Es freut mich immer, wenn ich solche Rückmeldungen bekomme. Die Seiten von Sprut sind auch wirklich spitze. Bei ihm habe ich auch angefangen mich einzulesen. Die Funkmodule sind richtig gut. Viel Spaß weiterhin!