I2CPICMasterSlave - Homepage von Stefan Buchgeher

Transcription

I2CPICMasterSlave - Homepage von Stefan Buchgeher
Datenaustausch zwischen
zwei (oder mehreren)
PIC16Fxx-Mikrocontrollern
via I2CTMin C
(oder: Wie realisiere ich einen I2CTM-Slave
mit einem PIC16Fxx-Mikrocontroller)
Stefan Buchgeher
4. August 2014
www.stefan-buchgeher.info
B [email protected]
B Großambergstraße 106/3, A-4040 Linz (Österreich)
H ++43/699/11 29 63 38
1
INHALTSVERZEICHNIS
Inhaltsverzeichnis
1 Einleitung
2
2 I2 C-Protokoll
3
3 PIC16Fxx als I2 C-Slave
3.1 Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2 Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
4
6
4 PIC16Fxx als I2 C-Master
9
4.1 Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4.2 Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
5 Demonstrationsbeispiele
5.1 Schaltung (Hardware) . . . . . . . . . . . . . . .
5.2 Software für 1. Demo (Slave) . . . . . . . . . . . .
5.3 Anmerkungen zur Software für 1. Demo (Slave) .
5.4 Software für 1. Demo (Master) . . . . . . . . . . .
5.5 Anmerkungen zur Software für 1. Demo (Master)
5.6 Software für 2. Demo (Slave) . . . . . . . . . . . .
5.7 Anmerkungen zur Software für 2. Demo (Slave) .
5.8 Software für 2. Demo (Master) . . . . . . . . . . .
5.9 Anmerkungen zur Software für 2. Demo (Master)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
10
11
13
20
23
28
31
39
41
45
Literatur
[1] Microchip. Datenblatt des PIC16F887. http://ww1.microchip.com/downloads/en/
DeviceDoc/41291G.pdf, 2012.
[2] Microchip. Application Note: AN734 - Using the Mid-Range Enhanced Core PIC16
Devices’ MSSP Moduls for slave I2C Communication. http://ww1.microchip.com/
downloads/en/AppNotes/00000734C.pdf, 2013.
[3] mikroElekronika. mikroElektronika - Tools, Compilers, Books, Magazine. http://
www.mikroe.com/, 2009.
[4] mikroElekronika. mikroc user’s manual. http://www.mikroe.com/, 2009.
1 EINLEITUNG
1
2
Einleitung
Der I2 C-Bus1 wurde ursprünglich von der Firma Philips für die Kommunikation verschiedener Baugruppen in einem Gerät entwickelt.
Der I2 C-Bus ist eine so genannte synchrone serielle Zwei-Drahtverbindung zwischen einem
Master und einem oder mehreren Slaves. In den meisten Fällen ist der Master ein Mikrocontroller (z.B. ein PIC), während es sich beim Slave z.B. um einen Speicherbaustein
handelt, oder um Porterweiterungsbausteine, Temperatursensor, Uhrenbausteine, AnalogDigital-Wandler oder um Spezialbausteine aus dem Bereich der Audio- und Videotechnik.
Oder, und darum geht es hier, kann der Slave auch ein PIC-Mikrocontroller sein.
Der I2 C-Bus benötigt neben einer Masseleitung nur zwei Leitungen:
• Eine Taktleitung (diese wird meist mit SCL bezeichnet) und dient zur Erzeugung
des Taktes. Der Takt wird dabei immer vom Master erzeugt. Die Taktgeschwindigkeit ist von den verwendeten Slave-Bausteinen abhängig. Sie kann maximal 100
kHz, 400 kHz oder 1 MHz betragen.
• Eine Datenleitung (diese wird meist mit SDA bezeichnet) und dient zur Übertragung der Daten. Die Daten können sowohl vom Master zum Slave (hier spricht man
von Daten schreiben) als auch vom Slave zum Master (hier spricht man von Daten
lesen) übertragen werden.
In den meisten Fällen wird die Datenübertragung von einem Master ausgelöst. Es ist
aber auch möglich, dass zwei oder mehr Master in einen Bus vorkommen. In diesem Fall
spricht man vom Multi-Master-Mode. Hier ist durch ein bestimmtes Protokoll gesichert,
dass immer nur ein Master den Bus übernehmen kann, wenn der Bus frei ist. Der MultiMaster-Mode soll hier nicht näher betrachtet werden. Diese Dokumentation bezieht sich
ausschließlich auf die Konfiguration ein Master mit einem oder mehreren Slaves.
Einige Bausteine der PIC16-Familie beinhalten ein (oder zwei) Hardwaremodul(e) für die
Ansteuerung von I2 C-Slave-Bausteinen (z.B. PIC16F88x). Beinhaltet der für ein Projekt
ausgewählte PIC kein I2 C-Hardwaremodul, so ist man gezwungen diese per Software zu
realisieren, wenn man mit I2 C-Bausteinen kommunizieren muss. Diese Dokumentation
beschreibt die Software für die Implementierung des I2 C-Protokolls für einen Slave mit
einem PIC-Mikrocontroller mit I2 C-Hardwaremodul.
Wichtig:
Damit ein Mikrocontroller vom Typ PIC16Fxx als Slave für den I2 C-Bus verwendet werden kann muss dieser über das MSSP-Modul verfügen, und dieser muss
den Slave-Mode beinhalten. MSSP steht für Master Synchronous Serial Port.
Als Informationsquellen für diese Arbeit dienen das Datenblatt des verwendeten PICMikrocontroller (hier PIC16F887 [1])und die Application-Note AN734 mit dem Titel:
1
Das Kürzel I2 C bedeutet Inter-Integrated-Circuit und wird daher auch oft mit IIC abgekürzt
2 I2 C-PROTOKOLL
3
Using the Mid-Range Enhanced Core PIC16 Devices’ MSSP Modules for Slave I2 CTM
Communication [2].
Als Programmiersprache für die PIC-Mikrocontroller-Software wurde C mit dem mikroCCompiler2 verwendet. Für die Demonstrationsbeispiele (ab Seite 10) ist die kostenlose
Demoversion3 ausreichend.
I2C-Protokoll
2
Jede Aktion auf dem I2 C-Bus geht vom Master aus. Als Master dient hier ein PIC (z.B.
PIC16F887). Die erste Aufgabe des Masters einer jeden Datenübertragung ist das Erzeugen der Startbedingung. Die Startbedingung ist wie folgt definiert: Auf der Datenleitung (SDA) erfolgt eine High-Low-Flanke, während die Taktleitung (SCL)
High ist. Damit wird gekennzeichnet, dass auf dem I2 C-Bus ein Datenverkehr stattfindet.
Würden sich auf dem Bus weitere Master befinden (Multi-Master-Mode) so dürfen diese
jetzt keine Datenübertragung zu einem Slave beginnen, da der Bus jetzt belegt ist.
Nun muss der Master die Adresse des Slaves mit welchem er kommunizieren möchte bekannt geben. Zu diesem Zweck besitzt jeder Slave eine Adresse. Diese Adresse besteht in
den meisten Fällen aus einem vom Hersteller festgelegtem Bauteilkode und einer Bausteinadresse, welche durch Beschaltung dafür reservierter Anschlüsse wählbar ist. So ist
es möglich mehrere gleichartiger Bausteine an einem Bus anzuschließen. (Z.B. mehrere
Speicherbausteine oder mehrere Porterweiterungsbausteine.)
Nach der Bauteiladresse (diese besteht in den meisten Fällen aus 7 Bit oder aus 10 Bit)
erfolgt als nächstes die Bekanntgabe der Übertragungsrichtung. Möchte der Master (also
der PIC) von einem Slave Daten lesen, so erfolgt als Übertragungsrichtung ein Low (0).
Möchte der Master (PIC) zu einem Slave Daten (oder Befehle) übertragen, so erfolgt als
Übertragungsrichtung ein High (1).
Die Adresse und das Bit welches die Übertragungsrichtung festlegt werden auch als Kontrollbyte bezeichnet.
Nach dem Kontrollbyte muss der Master auf ein Bestätigungsbit vom adressierten Slave
warten.
Je nach Slave kann nun entweder ein Datenbyte oder mehrere Datenbytes vom Master zum Slave oder vom Slave zum Master übertragen werden.
Werden Daten vom Master zum Slave übertragen (Schreibvorgang), so muss der Master
nach jedem übertragenen Byte auf eine Bestätigung vom Slave warten.
Erfolgt der Datenverkehr in die andere Richtung (vom Slave zum Master, man spricht
hier auch von einem Lesevorgang) so muss der Master jedes empfange Byte bestätigen.
Sind alle Daten übertragen, muss der I2 C-Bus wieder freigegeben werden. Diese Freigabe
erfolgt mit einer Stoppbedingung. Die Stoppbedingung ist wie folgt definiert: Auf der
2
Der mikroC-Compiler wurde von der Firma mikroElektronika [3] entwickelt und dient zum Programmieren der PIC16Fxx-Familie in der Hochsprache C
3
Die freie Demoversion ist nur auf eine Programmspeichergröße von 2k begrenzt, ansonst voll kompatibel zur Vollversion. Die Demoversion ist auf der Firmen-Webseite [3] downloadbar
3 PIC16FXX ALS I2 C-SLAVE
4
Datenleitung (SDA) erfolgt eine Low-High-Flanke, während die Taktleitung
(SCL) High ist. Der I2 C-Bus ist nun frei und kann von einem anderen Master zur
Datenübertragung benutzt werden.
Das folgende Bild zeigt zur besseren Verdeutlichung nochmals den gesamten Vorgang.
Abbildung 1: I2 C-Protokoll
Achtung:
Das hier beschriebene Protokoll zum I2 C-Bus - also das Setzen und das Löschen
der Leitungen SDA und SCL muss in der Software nicht nachgebildet werden. Diese Aufgabe übernimmt das Hardwaremodul MSSP des PIC16Fxx-Mikrocontroller. In der Software müssen nur die Steuerbits gesetzt (oder gelöscht) werden und die zu übermittelten Daten bereitgestellt oder abgeholt werden. Mehr
dazu in den folgenden Abschnitten.
PIC16Fxx als I2C-Slave
3
Dieser Abschnitt beschreibt nun wie ein PIC16Fxx-Mikrocontroller als Slave für den I2 C
zu konfigurieren ist und welche Software-Routinen notwendig sind.
Wichtig:
Damit ein Mikrocontroller vom Typ PIC16Fxx als Slave für den I2 C-Bus verwendet werden kann muss dieser über das MSSP-Modul verfügen, und dieser muss
den Slave-Mode beinhalten. MSSP steht für Master Synchronous Serial Port.
3.1
Hardware
Zunächst die Hardwarebeschaltung. Abbildung 2 zeigt die Beschaltung des PIC16FxxMikrocontrollers, wobei auch die Beschaltung des Oszillators X1 entfallen kann, wenn der
verwendete PIC16Fxx-Mikrocontroller über einen internen Oszillator verfügt.
Der I2 C-Bus mit seinen Leitungen (SDA, SCL, Masse, Betriebsspannung und dem optionalen Interrupt) ist im Bild unten zu sehen. Wesentlich ist hier eigentlich nur, dass
3 PIC16FXX ALS I2 C-SLAVE
5
Abbildung 2: PIC16Fxx als I2 C-Slave, Schaltung
die beiden PIC-I/O-Pins SDA und SCL über Schutzwiderstände (R3 bis R5) mit dem
I2 C-Bus verbunden werden.
Die übrigen Schaltungsteile entsprechen den üblichen PIC16Fxx-Applikationen. Die Schaltung rund um den Quarz X1 erzeugt einen stabilen Systemtakt. Dieser Schaltungsteil kann
entweder komplett entfallen falls der verwendete PIC16F-Mikrocontroller einen internen
Oszillator besitzt und dieser verwendet wird, oder umschaltbar mit Steckbrücken.
Die PIC16Fxx-Familie lässt sich sehr gut in der Schaltung programmieren. Diese Methode
wird ICSP4 genannt. Der Reset wird hier mit einem RC-Glied bestehend aus R1 und C1
erzeugt. Zusätzlich kann ein Reset jederzeit mit dem Taster S1 ausgelöst werden. Da der
Reseteingang des Mikrocontrollers (MCLR, Pin 1) auch gleichzeitig die Programmierspannung (ca. 13V) bei der ICSP-Proghrammierung ist, darf während einer Programmierung
kein Reset ausgelöst werden. Durch die Diode D1 ist ein Reset durch das RC-Glied (R1
4
ICSP steht für In-Circuit-Serial-Programming
3 PIC16FXX ALS I2 C-SLAVE
6
und C1) während einer Programmierung via ICSP nicht möglich.
Die Spannungsversorgung für den Mikrocontroller erfolgt über den I2 C-Bus, so dass hier
kein extra Schaltungsteil notwendig ist. Ein Koppelkondensator (C4) ist aber empfehlenswert.
Die I2 C-Busadresse kann entweder in der Software fix vergeben werden oder über Steckbrücken (Jumper, JP1 bis JP6). Hier wird fast der gesamte Port B dafür verwendet.
Alle übrigen Portpins sind frei verfügbar.
3.2
Software
Damit ein PIC16Fxx-Mikrocontroller als Slave für den I2 C-Bus verwendet werden kann
muss dieser (wie in diesem Dokument schon öfter erwähnt) über ein so genanntes MSSPModul verfügen. Dieses Modul ist im Mikrocontroller als Hardware integriert und unterstützt neben dem I2 C-Bus einen weiteren seriellen Bus, der hier nicht weiter behandelt
wird. Dieses Hardware-Modul muss zunächst für den I2 C-Slave-Mode konfigueriert werden. Dazu dienen die folgenden Register:
• SSPCON
• SSPCON2
• SSPSTAT
• SSPADD
Wie diese konfiguriert werden müssen zeigen die beiden Demonstrationsbeispiel in Abschnitt 5 ab Seite 10.
Wichtig ist auch, dass die Portpins (SDA und SCL) als Eingang konfiguriert werden.
Da der Mikrocontroller über ein geeignetes Hardwaremodul verfügt erfolgt die Umsetzung
des I2 C-Protokolls automatisch, und der Anwender muss sich darum nicht kümmern. Er
hat nur“ die Aufgabe die empfangenen Daten rechtzeitig zu lesen und die zu sendenden
”
Daten rechtzeitig zur Verfügung zu stellen. Dieses rechtzeitig“ lässt sich sehr elegant
”
mit einem Interrupt erkennen, die der Mikrocontroller erzeugt. Wichtig ist, dass dieser
Interrupt (SSP-Interrupt) freigegeben werden muss! Die Abbildungen 3 und 4 zeigen die
Statusbits bei einem Lesebefehl bzw. bei einem Schreibbefehl.
3 PIC16FXX ALS I2 C-SLAVE
7
Abbildung 3: PIC16Fxx als I2 C-Slave, Statusbits bei einem Lesebefehl (Auszug aus dem
Datenblatt zum PIC16F887)
Abbildung 4: PIC16Fxx als I2 C-Slave, Statusbits bei einem Schreibebefehl (Auszug aus
dem Datenblatt zum PIC16F887)
Für den Anwender (Softwarenetwickler) besteht nur“ die Aufgabe zum richtigen Zeit”
punkt die zu lesenden Daten abzuholen bzw. die zu schreibenden Daten zur Verfügung zu
stellen. Dazu dienen die zwei Flags R W und D A im Register SSPSTAT. Diese beiden Flags
werden automatisch gesetzt oder gelöscht nachdem ein Datenbyte via I2 C-Bus empfangen oder gesendet wurde. Gleichzeitig wird auch das Interrupt-Flag für das SSP-Modul
(SSPIF) gesetzt und ein Interrupt ausgelöst, falls dieser Interrupt freigegeben wurde.
Mit anderen Worten ausgedrückt: Nach jedem empfangene oder gesendeten Byte via I2 CBus wird der SSP-Interrupt ausgelöst. Dabei gibt das Flag R W an, ob die Daten am Bus
vom Slave gelesen werden sollen R W = 0 oder ob der Slave Daten auf den Bus Schreiben
muss R W = 1. Das Flag D A gibt an, ob das zuletzt empfangene Byte das Adressbyte war
D A = 0 oder ob es sich um ein Datenbyte handelt D A = 1.
3 PIC16FXX ALS I2 C-SLAVE
8
Somit ergeben sich die vier Fälle:
RW
0
0
1
1
DA
0
1
0
1
Bedeutung
Daten vom Bus lesen, zuletzt empfangenes Byte war die Slaveadresse
Daten vom Bus lesen, zuletzt empfangenes Byte war ein Datenbyte
Daten auf den Bus schreiben, zuletzt empfangenes Byte war die Slaveadresse
Daten auf den Bus schreiben, zuletzt gesendetes Byte war ein Datenbyte
Das Flussdiagramm in Abbildung 5 zeigt was in diesen vier Fällen zu tun ist.
Abbildung 5: PIC16Fxx als I2 C-Slave, Flussdiagramm (Interrupt-Service-Routine)
Anmerkungen:
• Die beiden Demonstrationsbeispiel in Abschnitt 5 ab Seite 10 zeigen diese InterruptService-Routine an einem einfachen konkreten Beispiel
• Die Slave-Adresse wird in das Register SSPADD geschrieben und muss in der InterruptService-Routine (ISR) nicht beachtet werden
• Das Interrupt-Flag SSPIF wird nur dann gesetzt, wenn die empfange Adresse mit
dem Wert im Register SSPADD übereinstimmt
• Wichtig: Das Interrupt-Flag SSPIF muss in der ISR wieder gelöscht werden!
4 PIC16FXX ALS I2 C-MASTER
9
Noch ein Hinweise: Leider hat sich herausgestellt, dass meine Software nicht bei jedem
PIC16Fxx funktioniert obwohl dieser gemäß dem Datenblatt als I2 C-Slave geeignet ist.
Den Grund dafür habe ich leider nicht gefunden bzw. ich hatte noch nicht das Bedürfnis
diesen Fehler zu suchen. Die nachfolgende Tabelle zeigt mit welche PIC16Fxx-Typen
meine“ Software funktioniert und mit welchen nicht. Typen die in dieser Tabelle nicht
”
aufscheinen habe ich (noch) nicht als I2 C-Slave getestet.
Typ
PIC16F887
PIC16F877
Anz.Pins
40
40
funktioniert oder funktioniert nicht
funktioniert :-)
funktioniert (leider nicht) :-(
PIC16Fxx als I2C-Master
4
Dieser Abschnitt beschreibt nun wie ein PIC16Fxx-Mikrocontroller als Master für den
I2 C zu konfigurieren ist und welche Software-Routinen notwendig sind.
Wichtig:
Damit ein Mikrocontroller vom Typ PIC16Fxx als Master für den I2 C-Bus verwendet werden kann muss dieser über das MSSP-Modul verfügen. MSSP steht
für Master Synchronous Serial Port.
4.1
Hardware
Zunächst die Hardwarebeschaltung. Abbildung 6 zeigt die minimal notwendige Beschaltung des PIC16Fxx-Mikrocontrollers.
Auffällig ist, dass hier kein Oszillator vorhanden ist. Dies ist auch nicht notwendig, da
die Kommunikation via I2 C-Bus nicht zeitkritisch ist, und daher ein interner Oszillator
verwendet werden kann.
Wichtig sind hier nur die Pull-Up-Widerstände R2 bis R4 für die beiden I2 C-Leitungen
(SDA und SCL) sowie für die Interrupt-Leitung (INT)5 . An die Buchse K3 bzw. an den
Stecker K4 kann ein beliebiges (5-poliges) Kabel angeschlossen werden. Buchsentyp sowie
Steckertyp und Pinbelegung sind frei wählbar. Hier wird auch die Betriebsspannung sowie
die Masse über das Kabel übertragen, so dass die I2 C-Slaves mit dieser Betriebsspannung
versorgt werden können.
Wie schon bei der Beschaltung für den PIC16Fxx als Slave wird auch der Master mittels
ICSP6 programmiert. Schaltungsteil um Buchse K5.
5
Achtung: Dies ist kein Interrupt des Mikrocontroller PIC16Fxx. Es gibt I2 C-Bausteine (Slaves) die
neben den Leitungen SDA und SCL einen so genannten INT-Ausgang besitzen um den I2 C-Master
mitzuteilen, dass Daten zum Abholen bereit sind. z.B. siehe PCF8574.
6
ICSP steht für In-Circuit-Serial-Programming
5 DEMONSTRATIONSBEISPIELE
10
Abbildung 6: PIC16Fxx als I2 C-Master, Schaltung
4.2
Software
Der hier verwendete C-Compiler verfügt bereits über Unterprogramme zur Kommunikation via I2 C für den Master [4].
Wichtig ist dass zu Beginn die Taktfrequenz für den I2 C-Bus definiert werden muss. Diese Aufgabe übernimmt das Unterprogramm I2C Init(). Für die Erzeugung der Startund Stopp-Bedingung stehen die Unterprogramme I2C Start() und I2C Stop() zur
Verfügung. Das Schreiben von 8-Bit-Daten erfolgt mit dem Unterpogramm I2C Wr() und
das Lesen von 8-Bit-Daten erfolgt mit dem Unterprogramm I2C Rd().
Wichtig ist dass die Pins SDA und SCL (beim Master) als Ausgang definiert werden
müssen. (Vgl.: Bei der Verwendung eines PIC16Fxx als I2 C-Slave müssen die Pins SDA
und SCL als Eingang definiert werden).
5
Demonstrationsbeispiele
Das folgende Beispiel dient nur zur Demonstration. Es zeigt eine mögliche Einbindung
der zuvor beschriebenen ISR (Interrupt-Service-Routine) für den I2 C-Slave. Neben einem
PIC16Fxx als I2 C-Slave dient ein weiterer Mikrocontroller vom Typ PIC16Fxx als I2 C-
5 DEMONSTRATIONSBEISPIELE
11
Master. Weitere I2 C-Slaves sind ein I/O-Expander vom Typ PCF8574 zur 8-Bit-Eingabe
mittels Jumper und ein zweiter I/O-Expander vom gleichen Typ PCF8574 zur 8-BitAusgabe mittels Leuchtdioden (LEDs).
Die Aufgabe des I2 C-Masters ist es nun:
1. 8-Bit-Wert vom I2 C-Eingabemodul (mit PCF8574) lesen und am PIC-I2 C-Slave am
Port D mittels 8 Leuchtdioden (LEDs) ausgeben.
2. 8-Bit-Wert vom PIC-I2 C-Slave vom Port A einlesen und am I2 C-Ausgabemodul (mit
PCF8574) anzeigen (mittels 8 Leuchtdioden).
5.1
Schaltung (Hardware)
Die Abbildung 7 zeigt die gesamte Schaltung für dieses Demonstrationsbeispiel.
Der schwarz gezeichnete Schaltungsteil kennzeichnet den PIC-I2 C-Slave. Dieser Schaltungsteil entspricht der Schaltung aus Abbildung 2 (Seite 5). Zusätzlich sind hier die
Jumper und Pull-Up-Widerstände am Port A, sowie die Leuchtdioden und die dazugehörigen Vorwiderstände am Port D (grau dargestellt). Der externe Oszillator X1 mit
den Kondensatoren C2 und C3 sowie dem Widerstand R2 werden hier nicht benötigt,
da der interne Oszillator verwendet wird. Diese sind daher ebenfalls grau gekennzeichnet.
Weiters sind die Jumper JP1 bis JP10 so wie in Abbildung 7 zu setzen. JP1 bis JP6 definieren die I2 C-Slave-Adresse. Hier 0011000 R/W. Als Mikrocontroller für den I2 C-Slave
wurde hier der Typ PIC16F887 verwendet.
Der zweite Mikrocontroller (IC2) ist ebenfalls vom gleichen Typ (PIC16F887) und dient
hier als I2 C-Master. Dieser Schaltungsteil ist genau wie in Abschnitt 4.1 (Seite 9) beschrieben. (Wichtig sind hier die Pull-Up-Widerstände an den I/O-Pins SCL, SDA und
INT).
An den I2 C-Bus sind neben dem PIC-I2 C-Slave (rund um IC1) auch die beiden I/OExpander vom Typ PCF8574 angeschlossen (IC3 und IC4). Wichtig sind die I2 C-SlaveAdressen die hier ebenfalls mit Jumpern ausgewählt werden können. Bei IC3 sind die
Jumper für A1 und A2 gesteckt, während bei IC4 nur der Jumper für A2 gesteckt ist. Es
versteht sich von selbst, dass beide I/O-Expander unterschiedliche Slaveadressen besitzen
müssen, und dass die Slaveadresse des PIC-I2 C-Slave sich von denen der I/O-Expander
unterscheiden muss!
Die Spannungsversorgung besteht hier aus einem Labornetzgerät und beträgt 5V.
5 DEMONSTRATIONSBEISPIELE
Abbildung 7: Demonstrationsbeispiel (Schaltung)
12
5 DEMONSTRATIONSBEISPIELE
5.2
13
Software für 1. Demo (Slave)
Beim ersten Demonstrationsbeispiel sendet der I2 C-Master nur ein Datenbyte zum PICI2 C-Slave, bzw. liest anschließend auch nur ein Datenbyte vom PIC-I2 C-Slave.
Beachte:
Da bei diesem ersten Demonstrationsbeispiel nur ein Datenbyte gesendet bzw. nur
ein Datenbyte gelesen wird, vereinfacht sich das Flussdiagramm (aus Abbildung
5, Seite 8). Es sind nämlich kein Lesezeiger und kein Schreibzeiger notwendig.
Siehe auch Abschnitt 5.3, ab Seite 20.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Demo z u r Ansteuerung d e s PIC16Fxx a l s I2C−S l a v e gemaess A p p l i c a t i o n Note AN734
∗/
/∗
∗/
/∗ S l a v e
∗/
/∗
∗/
/∗ Demo 1 : j e w e i l s nur e i n Byte vom Port A l e s e n und an den Master s e n d e n bzw . e i n
∗/
/∗
Byte vom Master l e s e n und am Port D a u s g e b e n
∗/
/∗
∗/
/∗ M i k r o c o n t r o l l e r :
PIC16F887
∗/
/∗ Takt :
i n t e r n e r Takt ( 4 . 0 MHz)
∗/
/∗
∗/
/∗ Compiler :
mikroC V8 . 2
∗/
/∗
∗/
/∗ E n t w i c k l e r :
S t e f a n Buchgeher
∗/
/∗ E n t w i c k l u n g s b e g i n n d e r S o f t w a r e : 1 9 . Februar 2014
∗/
/∗ F u n k t i o n s f a e h i g s e i t :
2 . Maerz 2014
∗/
/∗ L e t z t e B e a r b e i t u n g :
4 . J u l i 2014
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ I n c l u d e −D a te i e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e I n c l u d e −D a te i e n ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ S t r u k t u r e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e S t r u k t u r e n v e r w e n d e t ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ E x te r n e R e g i s t e r ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e e x t e r n e n R e g i s t e r ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ B i t s i n den e x t e r n e n R e g i s t e r n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e e x t e r n e n R e g i s t e r ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ G l o b a l e R e g i s t e r ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
char
cDummy ;
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ B i t s i n den g l o b a l e n R e g i s t e r n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e g l o b a l e n R e g i s t e r ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ P o r t b e l e g u n g ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ \INT−Ausgang d e s PCF8574 ∗/
//#d e f i n e nINTPCF8574
PORTC. F5
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ Konstanten ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n Konstanten ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ T a b e l l e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
5 DEMONSTRATIONSBEISPIELE
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
14
/∗ k e i n e T a b e l l e n ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ F u n k t i o n s p r o t o t y p e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Unterprogramm z u r I n i t i a l i s i e r u n g d e s M i k r o c c n t r o l l e r s ∗/
void I n i t ( void ) ;
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ I n t e r r u p t −S e r v i c e −R o u ti n e ( ISR ) ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ I n t e r r u p t S e r v i c e R o u ti n e :
∗/
/∗
∗/
/∗ A u f r u f :
∗/
/∗
SSP I n t e r r u p t F l a g ( SSPIF ) , nach jedem I2C−Event ( wenn d e r Master e i n e A d r e s s e
∗/
/∗
a u f den I2C−Bus s c h r e i b t o d e r wenn s i c h Daten am I2C−Bus b e f i n d e n
∗/
/∗
∗/
/∗ Aufgaben :
∗/
/∗
+ Je nach S t a t u s s i n d u n t e r s c h i e d l i c h e Aktionen a u s z u f u e h r e n : s i e h e Kommentare im ∗/
/∗
Quellcode
∗/
/∗
+ Nach j e d e r Aktion muss das SSP−I n t e r r u p t −F l a g SSPIF w i e d e r g e l o e s c h e n werden
∗/
/∗
∗/
/∗ Achtung :
∗/
/∗
Der S t a t u s Lesen bzw . S c h r e i b e n e r f o l g t immer aus S i c h t d e s Master ! !
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
void i n t e r r u p t ( void )
// I n t e r r u p t r o u t i n e
{
i f (SSPSTAT .R W == 0 )
{
// S c h r e i b z u g r i f f e ( aus S i c h t d e s Masters , d . h . S l a v e muss Daten aus dem Sende−
// und E m p f a n g s b u f f e r (SSPBUF) l e s e n )
i f (SSPSTAT . D A == 0 )
{
// S t a t e 1 : I2C w r i t e o p e r a t i o n , l a s t b y te was an a d d r e s s b y te
// SSPSTAT b i t s : S=1 , D/A=0 , R/W=0 , BF=1
cDummy = SSPBUF ;
SSPSTAT . BF = 0 ;
// F l a g B u f f e r −F u l l l o e s c h e n
SSPCON.CKP = 1 ;
// C l o c k s t r e t c h i n g e r l a u b e n
PIR1 . SSPIF = 0 ;
// SSP−I n t e r r u p t −F l a g w i e d e r l o e s c h e n
return ;
}
else
{
// S t a t e 2 : I2C w r i t e o p e r a t i o n , l a s t b y te was a data b y te
// SSPSTAT b i t s : S=1 , D/A=1 , R/W=1 , BF=1
PORTD = SSPBUF ;
// Datenbyte von SSPBUF l e s e n und am
//
Port D a u s g e b e n
SSPCON.CKP = 1 ;
// C l o c k s t r e t c h i n g e r l a u b e n
PIR1 . SSPIF = 0 ;
// SSP−I n t e r r u p t −F l a g w i e d e r l o e s c h e n
return ;
}
}
else
{
// L e s e z u g r i f f ( aus S i c h t d e s Masters , d .H. S l a v e muss Daten i n Sende− und
// E m p f a n g s b u f f e r (SSPBUF) s c h r e i b e n )
i f (SSPSTAT . D A == 0 )
{
// S t a t e 3 : I2C r e a d o p e r a t i o n , l a s t b y te was an a d d r e s s b y te
// SSPSTAT b i t s : S=1 , D/A=0 , R/W=1 , BF=0
SSPBUF = PORTA;
// Datenbyte von PortA l e s e n und i n
//
SSPBUF s c h r e i b e n
SSPCON.CKP = 1 ;
// C l o c k s t r e t c h i n g e r l a u b e n
PIR1 . SSPIF = 0 ;
// SSP−I n t e r r u p t −F l a g w i e d e r l o e s c h e n
return ;
}
else
{
// S t a t e 4 : I2C r e a d o p e r a t i o n , l a s t b y te was a data b y te
// SSPSTAT b i t s : S=1 , D/A=1 , R/W=0 , BF=0
SSPBUF = cDummy ;
15
5 DEMONSTRATIONSBEISPIELE
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
SSPCON.CKP = 1 ;
PIR1 . SSPIF = 0 ;
return ;
// C l o c k s t r e t c h i n g e r l a u b e n
// SSP−I n t e r r u p t −F l a g w i e d e r l o e s c h e n
}
}
}
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ Unterprogramme und Funktionen ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ I n i t :
∗/
/∗
∗/
/∗ Aufgabe :
∗/
/∗
I n i t i a l i s i e r u n g des P r o z e s s o r :
∗/
/∗
+ internen Os z i l l a to r konfigurieren
∗/
/∗
+ P o r t s a u f D i g i t a l I /O u m s c h a l te n und a l s Ein− o d e r Ausgang k o n f i g u r i e r e n
∗/
/∗
+ I2C−Hardware−Modul a l s S l a v e k o n f i g u r i e r e n
∗/
/∗
+ I2C S l a v e A d r e s s e von Port B l e s e n und i n SSPADD s c h r e i b e n
∗/
/∗
+ Interrupt freigeben
∗/
/∗
∗/
/∗ U e b e r g a b e p a r a m e te r :
∗/
/∗
keiner
∗/
/∗
∗/
/∗ Rueckgabeparameter :
∗/
/∗
keiner
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
void I n i t ( void )
{
char c I2 C A d r e s s e ;
// I2C−S l a v e −A d r e s s e
/∗
// ( i n t e r n e n ) O s z i l l a t o r k o n f i g u r i e r e n
OSCCON = 0 b01100001 ;
// Sync O s c i l l a t o r C o n t r o l R e g i s t e r
+−−−−−−−−−−−−−−−−−−−− B i t 7 R e s e r v e
+++−−−−−−−−−−−−−−−−− B i t 6−4 ( IRCF2 : IRCF0 ) : I n t e r n a l O s c i l l a t o r Frequency
||||
Select bits
||||
000 : 31 kHz (LFINTOSC)
||||
001 : 125 kHz
||||
010 : 250 kHz
||||
011 : 500 kHz
||||
100 : 1 MHz
||||
101 : 2 MHz
||||
−> 110 : 4 MHz ( d e f a u l t )
||||
111 : 8 MHz
+−−−−−−−−−−−−−−−− B i t 3 (OSTS) : O s c i l l a t o r S t a r t −up Time−out S t a t u s
|||
( Read Only )
|||
0 : D e v i c e i s r u n n i n g from th e c l o c k d e f i n e d
|||
by FOSC2 : FOSC0 o f th e CONFIG1 r e g i s t e r
|||
1 : D e v i c e i s r u n n i n g from th e i n t e r n a l
|||
oscillator
(HFINTOSC o r LFINTOSC)
+−−−−−−−−−−−−−−− B i t 2 (HTS) : HFINTOSC S t a t u s b i r
||
( High Frequency − 125 kHz to 8MHz)
||
( Read Only )
||
0 : HFINTOSC i s not s t a b l e
||
1 : HFINTOSC i s s t a b l e
+−−−−−−−−−−−−−− B i t 1 (LTS) : LFINTOSC S t a t u s b i t
|
(Low Frequency − 31kHz )
|
( Read Only )
|
0 : LFINTOSC i s not s t a b l e
|
1 : LFINTOSC i s s t a b l e
+−−−−−−−−−−−−− B i t 0 (SCS ) : System Clock S e l e c t b i t
0 : Clock s o u r c e d e f i n e d by FOSC2 : FOSC0
o f th e CONFIG1 r e g i s t e r
−>
1 : I n t e r n a l o s c i l l a t o r i s used f o r system
clock
∗/
// A l l e P o r t s a u f d i g i t a l I /O k o n f i g u r i e r e n
ANSEL = 0 b00000000 ;
// Analog S e l e c t R e g i s t e r
||||||||
//
( 0 : D i g i t a l I /O, 1 : A n a l o g e i n g a n g )
16
5 DEMONSTRATIONSBEISPIELE
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
/∗
+−−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−
Bit
Bit
Bit
Bit
Bit
Bit
Bit
Bit
7:
6:
5:
4:
3:
2:
1:
0:
Port
Port
Port
Port
Port
Port
Port
Port
RE2/AN7
RE1/AN6
RE0/AN5
RA5/AN4
RA3/AN3
RA2/AN2
RA1/AN1
RA0/AN0
ist
ist
ist
ist
ist
ist
ist
ist
hier
hier
hier
hier
hier
hier
hier
hier
Digital
Digital
Digital
Digital
Digital
Digital
Digital
Digital
I /O
I /O
I /O
I /O
I /O
I /O
I /O
I /O
∗/
/∗
ANSELH = 0 b00000000 ;
||||||||
++−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−
+−−−−−−−−−−−−−
// Analog S e l e c t R e g i s t e r
//
( 0 : D i g i t a l I /O, 1 : A n a l o g e i n g a n g )
Bit 6 ,7 Reserve
B i t 5 : Port RB5/AN13 i s t h i e r D i g i t a l I /O
B i t 4 : Port RB0/AN12 i s t h i e r D i g i t a l I /O
B i t 3 : Port RB4/AN11 i s t h i e r D i g i t a l I /O
B i t 2 : Port RB1/AN10 i s t h i e r D i g i t a l I /O
B i t 1 : Port RB9/AN9 i s t h i e r D i g i t a l I /O
B i t 0 : Port RB2/AN8 i s t h i e r D i g i t a l I /O
// P o r t s k o n f i g u r i e r e n
TRISA = 0 b11111111 ;
+−−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−
// R i c h t u n g s r e g i s t e r
B i t 7 Port RA7 : h i e r
B i t 6 Port RA6 : h i e r
B i t 5 Port RA5 : h i e r
B i t 4 Port RA4 : h i e r
B i t 3 Port RA3 : h i e r
B i t 2 Port RA2 : h i e r
B i t 1 Port RA1 : h i e r
B i t 0 Port RA0 : h i e r
Port A ( 0 : Ausgang ,
Eingang ( Jumper Pin
Eingang ( Jumper Pin
Eingang ( Jumper Pin
Eingang ( Jumper Pin
Eingang ( Jumper Pin
Eingang ( Jumper Pin
Eingang ( Jumper Pin
Eingang ( Jumper Pin
TRISB = 0 b00111111 ;
+−−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−
// R i c h t u n g s r e g i s t e r
B i t 7 Port RB7 : h i e r
B i t 6 Port RB6 : h i e r
B i t 5 Port RB5 : h i e r
B i t 4 Port RB4 : h i e r
B i t 3 Port RB3 : h i e r
B i t 2 Port RB2 : h i e r
B i t 1 Port RB1 : h i e r
B i t 0 Port RB0 : h i e r
Port B ( 0 : Ausgang , 1 : Eingang )
u n b e n u tz t
u n b e n u tz t
Eingang ( I2C−S l a v e −A d r e s s e A5)
Eingang ( I2C−S l a v e −A d r e s s e A4)
Eingang ( I2C−S l a v e −A d r e s s e A3)
Eingang ( I2C−S l a v e −A d r e s s e A2)
Eingang ( I2C−S l a v e −A d r e s s e A1)
Eingang ( I2C−S l a v e −A d r e s s e A0)
TRISC = 0 b00011000 ;
+−−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−
// R i c h t u n g s r e g i s t e r
B i t 7 Port RC7 : h i e r
B i t 6 Port RC6 : h i e r
B i t 5 Port RC5 : h i e r
B i t 4 Port RC4 : h i e r
B i t 3 Port RC3 : h i e r
B i t 2 Port RC2 : h i e r
B i t 1 Port RC1 : h i e r
B i t 0 Port RC0 : h i e r
Port C ( 0 : Ausgang , 1 : Eingang )
u n b e n u tz t
u n b e n u tz t
u n b e n u tz t
Eingang (SDA)
Eingang (SCL)
u n b e n u tz t
u n b e n u tz t
u n b e n u tz t
TRISD = 0 b00000000 ;
+−−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−
// R i c h t u n g s r e g i s t e r
B i t 7 Port RD7 : h i e r
B i t 6 Port RD6 : h i e r
B i t 5 Port RD5 : h i e r
B i t 4 Port RD4 : h i e r
B i t 3 Port RD3 : h i e r
B i t 2 Port RD2 : h i e r
B i t 1 Port RD1 : h i e r
B i t 0 Port RD0 : h i e r
Port D ( 0 : Ausgang , 1 : Eingang )
Ausgang (LED D7)
Ausgang (LED D6)
Ausgang (LED D5)
Ausgang (LED D4)
Ausgang (LED D3)
Ausgang (LED D2)
Ausgang (LED D1)
Ausgang (LED D0)
∗/
/∗
1 : Eingang )
7)
6)
5)
4)
3)
2)
1)
0)
∗/
/∗
∗/
/∗
∗/
/∗
∗/
/∗
TRISE = 0 b00000000 ;
// R i c h t u n g s r e g i s t e r Port E ( 0 : Ausgang , 1 : Eingang )
||||||||
//
und P a r a l l e l S l a v e Port S t a t u s / C o n t r o l B i t s
+−−−−−−−−−−−−−−−−−−−−− B i t 7 ( IBF ) : In p u t B u f f e r F u l l S t a t u s b i t
|||||||
( Read o n l y )
|||||||
0 : No word has been r e c e i v e d
5 DEMONSTRATIONSBEISPIELE
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
|||||||
|||||||
+−−−−−−−−−−−−−−−−−−−−
||||||
||||||
||||||
||||||
+−−−−−−−−−−−−−−−−−−−
|||||
|||||
|||||
|||||
|||||
+−−−−−−−−−−−−−−−−−−
||||
||||
+−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−
17
1 : A word has been r e c e i v e d and i s w a i t i n g to
be r e a d by th e CPU
B i t 6 (OBF) : Output B u f f e r F u l l S t a t u s b i t
( Read o n l y )
0 : The o u tp u t b u f f e r has been r e a d
1 : The o u tp u t b u f f e r s t i l l h o l d s a p r e v i o u s l y
w r i t t e n word
B i t 5 (IBOV) : In p u t B u f f e r O v e r f l o w D e te c t b i t
( i n M i c r o p r o c e s s o r mode )
0 : No o v e r f l o w o c c u r r e d
1 : A w r i t e o c c u r r e d when a p r e v i o u s l y i n p u t
word has not been r e a d ( must be c l e a r e d
in Software )
B i t 4 (PSPMODE) : P a r a l l e l S l a v e Port Mode S e l e c t
−> 0 : PORTD f u n c t i o n s i n g e n e r a l Purpose I /O mode
1 : PORTD f u n c t i o n s i n P a r a l l e l S l a v e Port mode
Bit 3 Reserve
B i t 2 Port RE2 : h i e r u n b e n u tz t
B i t 1 Port RE1 : h i e r u n b e n u tz t
B i t 0 Port RE0 : h i e r u n b e n u tz t
∗/
PORTA
PORTB
PORTC
PORTD
PORTE
/∗
=
=
=
=
=
0;
0;
0;
0;
0;
// I2C−Hardware−Modul a l s S l a v e k o n f i g u r i e r e n
SSPCON = 0 b00100110 ;
// Sync S e r i a l Port C o n t r o l R e g i s t e r 1
+−−−−−−−−−−−−−−−−−−−− B i t 7 (WCOL) : Write C o l l i s i o n D e te c t b i t
|||||||
Master mode :
|||||||
0 : No c o l l i s i o n
|||||||
1 : A w r i t e to SSPBUF was attempt w h i l e th e I2C
|||||||
c o n d i t i o n s were not v a l i s
|||||||
S l a v e mode :
|||||||
0 : No c o l l i s i o n
|||||||
1 : SSPBUF r e g i s t e r i s w r i t t e n w h i l e s t i l l
|||||||
t r a n s m i t t i n g th e p r e v i o u s word ( must be
|||||||
cleared in software )
+−−−−−−−−−−−−−−−−−−− B i t 6 (SSPOV) : R e c e i v e O v e r f l o w I n d i c a t o r b i t
||||||
0 : No o v e r f l o w
||||||
1 : A new b y te i s r e c e i v e d w h i l e SSPBUF h o l d s
||||||
p r e v i o u s data ( w e i t e r s i e h e D a t e n b l a t t ! ! )
||||||
( must be c l e a r e d i n s o f t w a r e )
+−−−−−−−−−−−−−−−−−− B i t 5 (SSPEN ) : Synchronous S e r i a l Port Enable b i t
|||||
0 : D i s a b l e s s e r i a l p o r t and c o n f i g u r e s t h e s e
|||||
P i n s a s I /O p o r t p i n s
|||||
−>
1 : E n a b l e s th e s e r i a l p o r t an c o n f i g u r e s
|||||
SCK, SDO, SDI , SS / SDA, SCL p i n s a s th e
|||||
s o u r c e o f th e s e r i a l p o r t p i n s
+−−−−−−−−−−−−−−−−− B i t 4 (CKP) : Clock P o l a r i t y S e l e c t b i t
||||
In SPI mode :
||||
0 : I d l e s t a t e f o r c l o c k i s a low l e v e l
||||
1 : I d l e s t a t e f o r cl ock i s a high l e v e l
||||
In I2C S l a v e mode : SCK r e l e a s e c o n t r o l
||||
−>
0 : Holds c l o c k low ( c l o c k s t r e t c h ) . ( Used to
||||
e n s u r e data s e t u p time . )
||||
1 : Enable c l o c k
||||
In I2C Master mode : Unused i n t h i s mode
++++−−−−−−−−−−−−− B i t 3−0 (SSPM3 : SSPM0) : SSP Mode S e l e c t b i t s
0000 : SPI Master mode , c l o c k = Fosc /4
0001 : SPI Master mode , c l o c k = Fosc /16
0010 : SPI Master mode , c l o c k = Fosc /64
0011 : SPI Master mode , c l o c k = TMR2 o u tp u t /2
0100 : SPI S l a v e mode , c l o c k = SCK pin , nSS p i n
contr ol enabled
0101 : SPI S l a v e mode , c l o c k = SCK pin , nSS p i n
c o n t r o l d i s a b l e d . nSS can be used a s I /O
−> 0110 : I2C S l a v e mode , 7− b i t a d d r e s s
18
5 DEMONSTRATIONSBEISPIELE
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
0111 : I2C S l a v e mode , 10− b i t a d d r e s s
1000 : I2C Master mode ,
c l o c k = Fosc / ( 4 ∗ ( SSPADD+1) )
1001 : R e s e r v e d
1010 : R e s e r v e d
1011 : I2C Firmware C o n t r o l l e d Master mode
( slave idle )
1100 : R e s e r v e d
1101 : R e s e r v e d
1110 : I2C Firmware C o n t r o l l e d Master mode ,
7− b i t a d d r e s s with START and STOP b i t
i n t e r r u p t s enabled
1111 : I2C Firmware C o n t r o l l e d Master mode ,
10− b i t a d d r e s s with START and STOP b i t
i n t e r r u p t s enabled
∗/
/∗
SSPCON2 = 0 b00110110 ;
+−−−−−−−−−−−−−−−−−−−
|||||||
|||||||
|||||||
|||||||
+−−−−−−−−−−−−−−−−−−
||||||
||||||
||||||
+−−−−−−−−−−−−−−−−−
|||||
|||||
|||||
|||||
|||||
|||||
+−−−−−−−−−−−−−−−−
||||
||||
||||
||||
||||
+−−−−−−−−−−−−−−−
|||
|||
|||
+−−−−−−−−−−−−−−
||
||
||
||
+−−−−−−−−−−−−−
|
|
|
|
|
+−−−−−−−−−−−−
// Sync S e r i a l Port C o n t r o l R e g i s t e r 2
B i t 7 (GCEN) : G e n e r a l C a l l Enable b i t ( In I2C S l a v e
mode o n l y )
−>
0 : General C a l l a d d r e s s d i s a b l e d
1 : Enable i n t e r r u p t when a g e n e r a l c a l l
a d d r e s s (0 0 0 0 h ) i s t r e c e i v e d i n th e SSPSR
B i t 6 (ACKSTAT) : Acknowledge S t a t u s b i t ( In I2C
Master mode o n l y )
0 : Acknowledge was r e c e i v e d from s l a v e
1 : Acknowledge was not r e c e i v e d from s l a v e
B i t 5 (ACKDT) : Acknowledge Data b i t ( In I2C Master
mode o n l y ) :
Value t h a t w i l l be t r a n s m i t t e d when th e u s e r
i n i z i a t e s an Acknowledge s e q u e n c e a t th e end
of a r ecei ve
0 : Acknowledge
1 : Not Acknowledge
B i t 4 (ACKEN) : Acknowledge Sequence Enable b i t
( In I2C Master mode o n l y ) :
0 : Acknowledge s e q u e n c e i d l e
1 : I n i t i a t e Acknowledge s e q u e n c e on SDA and
SCL p i n s and t r a n s m i t ACKDT data b i t .
A u t o m a t i c a l l y c l e a r e d by hardware
B i t 3 (RCEN) : R e c e i v e Enable b i t ( In I2C Master
mode o n l y )
0 : Receive i d l e
1 : E n a b l e s R e c e i v e mode f o r I2C
B i t 2 (PEN) : STOP C o n d i t i o n Enable b i t ( In I2C
Master mode o n l y )
0 : STOP c o n d i t i o n i d l e
1 : I n i t i a t e STOP c o n d i t i o n on SDA and SCL p i n s
A u t o m a t i c a l l y c l e a r e d by hardware
B i t 1 (RSEN) : Repeated START C o n d i t i o n Enable b i t
( In I2C Master mode o n l y )
0 : Repeated START c o n d i t i o n i d l e
1 : I n i t i a t e Repeated START c o n d i t i o n on SDA
and SCL p i n s
A u t o m a t i c a l l y c l e a r e d by hardware
B i t 0 (SEN) : START C o n d i t i o n Enable b i t ( In I2C
Master mode o n l y )
0 : START c o n d i t i o n i d l e
1 : I n i t i a t e START cond . on SDA and SCL p i n s
A u t o m a t i c a l l y c l e a r e d by hardware
∗/
SSPSTAT = 0 b10000000 ;
// I2C S l a v e A d r e s s e von Port B l e s e n und i n SSPADD s c h r e i b e n
// H i e r 0 A5 A4 A3 A2 A1 A0 R/nW
c I2 C A d r e s s e = 0 b00111111 ;
// Maske
c I2 C A d r e s s e = c I2 C A d r e s s e & PORTB;
c I2 C A d r e s s e = c I2 C A d r e s s e << 1 ;
c I2 C A d r e s s e . F0 = 0 ;
// S c h r e i b z u g r i f f aus S i c h t d e s Master
SSPADD = c I2 C A d r e s s e ;
19
5 DEMONSTRATIONSBEISPIELE
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
/∗
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
// I n t e r r u p t f r e i g e b e n
PIE1 = 0 b00001000 ;
+−−−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−−−
||||||
||||||
+−−−−−−−−−−−−−−−−−−−−
|||||
|||||
+−−−−−−−−−−−−−−−−−−−
||||
||||
+−−−−−−−−−−−−−−−−−−
|||
|||
|||
+−−−−−−−−−−−−−−−−−
||
||
+−−−−−−−−−−−−−−−−
Enable b i t
|
|
+−−−−−−−−−−−−−−−
bit
// P e r i p h e r a l I n t e r r u p t Enable R e g i s t e r 1 ( Bank 1 )
Bit 7 Reserve
B i t 6 (ADIE) : A/D C o n v e r te r I n t e r r u p t Enable b i t
−>
0 : D i s a b l e s th e ADC i n t e r r u p t
1 : E n a b l e s th e ADC i n t e r r u p t
B i t 5 (RCIE) : EUSART R e c e i v e I n t e r r u p t Enable b i t
−>
0 : D i s a b l e s th e EUSART R e c e i v e I n t e r r u p t
1 : E n a b l e s th e EUSART R e c e i v e I n t e r r u p t
B i t 4 (TXIE ) : EUSART Transmit I n t e r r u p t Enable b i t
−>
0 : D i s a b l e s th e Transmit I n t e r r u p t Enable b i t
1 : E n a b l e s th e Transmit I n t e r r u p t Enable b i t
B i t 3 ( SSPIE ) : Master Synchronous S e r i a l Port (MSSP)
I n t e r r u p t Enable b i t
0 : D i s a b l e s th e MSSP i n t e r r u p t
−>
1 : E n a b l e s th e MSSP i n t e r r u p t
B i t 2 ( CCP1IF) : CCP1 I n t e r r u p t Enable b i t
−>
0 : D i s a b l e s th e CCP1 i n t e r r u p t
1 : E n a b l e s th e CCP1 i n t e r r u p t
B i t 1 (TMR2IE) : Timer 2 to PR2 Match I n t e r r u p t
−>
0 : D i s a b l e s th e Timer 2 to PR2 Match I n t e r r u p t
1 : E n a b l e s th e Timer 2 to PR2 Match I n t e r r u p t
B i t 0 (TMR1IE) : Timer 1 O v e r f l o w I n t e r r u p t Enable
−>
0 : D i s a b l e s Timer 1 O v e r f l o w I n t e r r u p t
1 : E n a b l e s Timer 1 O v e r f l o w I n t e r r u p t
∗/
/∗
INTCON = 0 b11000000 ;
// I n t e r r u p t −C o n tr o l −R e g i s t e r ( Bank 1 )
+−−−−−−−−−−−−−−−−−−−− B i t 7 ( GIE) : G l o b a l I n t e r r u p t Enable b i t
|||||||
0 : Disables a l l i nter r upts
|||||||
−>
1 : E n a b l e s a l l unmasked i n t e r r u p t s
+−−−−−−−−−−−−−−−−−−− B i t 6 ( PEIE ) : P e r i p h e r a l I n t e r r u p t Enable b i t
||||||
0 : Disables a l l peripheral i nter r upts
||||||
−>
1 : E n a b l e s a l l unmasked p e r i p h e r a l i n t e r r u p t s
+−−−−−−−−−−−−−−−−−− B i t 5 ( T0IE ) : Timer 0 O v e r f l o w I n t e r r u p t Enable B i t
|||||
−>
0 : Disabled
|||||
1 : Enabled
+−−−−−−−−−−−−−−−−− B i t 4 (INTE ) : RB0/INT E x t e r n a l I n t e r r u p t Enable B i t
||||
−>
0 : Disabled
||||
1 : Enabled
+−−−−−−−−−−−−−−−− B i t 3 (RPIE ) : RB Port Change I n t e r r u p t Enable B i t
|||
−>
0 : Disabled
|||
1 : Enabled
+−−−−−−−−−−−−−−− B i t 2 ( T0IF ) : Timer 0 O v e r f l o w I n t e r r u p t F l a g b i t
||
−>
0 : TMR0 r e g i s t e r d i d not o v e r f l o w
||
1 : TMR0 r e g i s t e r has o v e r f l o w e d
+−−−−−−−−−−−−−− B i t 1 (INTF) : RB0/INT E x t e r n a l I n t e r r u p t F l a g b i t
|
−>
0 : RB0/INT e x t e r n a l i n t e r r u p t d i d not o c c u r
|
1 : RB0/INT e x t e r n a l i n t e r r u p t o c c u r r e d
+−−−−−−−−−−−−− B i t 0 (RBIF ) : RB Port Change I n t e r r u p t F l a g b i t
−>
0 : None o f RB7 : RB4 p i n s have changed s t a t e
1 : One o f th e RB7 : RB4 p i n s changed s t a t e
∗/
}
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ Hauptprogramm ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Aufgaben d e s Hauptprogramms :
∗/
/∗
+ C o n t r o l l e r i n i t i a l i s i e r e n ( Unterprogramm I n i t )
∗/
/∗
+ A l l e s a n d e r e e r f o l g t i n d e r ISR ! !
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
void main ( void )
{
// C o n t r o l l e r i n i t i a l i s i e r e n
Init () ;
5 DEMONSTRATIONSBEISPIELE
477
478
479
480
481
20
// E n d l o s s c h l e i f e
while ( 1 ) ;
}
Listing 1: I2C Demo PIC Slave.c (Demo 1)
5.3
Anmerkungen zur Software für 1. Demo (Slave)
Der Quellcode für dieses Demonstrationsbeispiel wurde in C mit der freien Demoversion
des mikroC-Compilers erstellt7 .
Die Software (für den PIC-I2 C-Slave) besteht im Wesentlichen aus den folgenden Programmteilen:
• kurzes Hauptprogramm am Ende des Quellcodes, Zeilen 473 bis 481.
• 1 Unterprogramm zur Initialisierung des PIC16F887 (Unterprogramm Init, Zeilen
152 bis 463).
• kurze Interrupt-Service-Routine (kurz: ISR), Zeilen 79 bis 130.
Hauptprogramm:
Die Aufgabe des Hauptprogramms (Zeilen 473 bis 481) ist hier nur“ das Initialisieren
”
des Mikrocontrollers. Dies erfolgt mit dem Unterprogramm Init (Zeile 476). Alles andere
erfolgt in der Interrupt-Service-Routine (ISR).
Unterprogramm Init:
Das Unterprogramm Init (Zeilen 152 bis 463) dient zur Initialisierung des Mikrocontrollers. Hier werden die benötigten Hardwaremodule konfiguriert. Für den PIC-I2 C-Slave
sind das zunächst der interne Oszillator (Zeile 158), sämtliche Ports als Ein- oder Ausgang kunfigurieren und als digitale Ein-/Ausgabepins konfigurieren (Zeilen 193 bis 292).
Wichtig ist dass die Portpins (SDA und SCL) als Eingang konfiguriert werden.
Ganz wichtig ist hier natürlich das SSP-Modul, denn dieses ist für die Kommunikation
via I2 C zuständig. Im Register SSPCON wird u.a. ausgewählt dass der Mikrocontroller im
I2 C-Slave-Mode betrieben wird (Zeile 296). Wichtig ist auch dass der I2 C-Slave über eine
Slave-Adresse verfügt. Dafür ist das Register SSPADD zuständig. Da bei diesem Demonstrationsbeispiel die Slave-Adresse am Port B des Mikrocontrollers ausgewählt werden
kann muss diese vom Port B gelesen werden und die entsprechenden Bits müssen in das
Register SSPADD geschrieben werden. Beachte: Bit 0 gibt die Datenflussrichtung aus Sicht
des Masters an (also Master schreibt Daten oder liest Daten, Zeilen 403 bis 407). Als
letzter Schritt muss noch der SSP-Interrupt freigegeben werden. Bit SSPIE im Register
PIE1 (Zeile 411). Weiters die Globale Interruptfreigabe (Bit GIE im Register INTCON),
sowie das Bit PEIE ebenfalls im Register INTCON (Zeile 437).
7
Die freie Demoversion ist nur auf eine Programmspeichergröße von 2k begrenzt, ansonst voll kompatibel zur Vollversion. Die Demoversion ist auf der Firmen-Webseite [3] downloadbar
5 DEMONSTRATIONSBEISPIELE
21
Interrupt-Service-Routine (kurz: ISR):
Die SSP-ISR (Zeilen 79 bis 130) wird jedesmal aufgerufen wenn ein gesamtes Datenbyte
vom SSP-Hardware-Modul empfangen wurde und dieses für den PIC-Slave mit der Adresse
im Register SSPADD bestimmt ist. Jedesmal wenn diese SSP-ISR aufgerufen wird muss eine
der folgenden vier Fälle ausgeführt werden (vgl. Flussdiagramm in Abbildung 5, Seite 8
jedoch hier ohne Lese- und Schreibezeiger, da nur ein Datenbyte gelesen bzw. geschrieben
(gesendet) wird.).
Fall 1: Schreibzugriff aus Sicht des Masters, zuletzt wurde die Slave-Adresse empfangen
(Bits: SSPSTAT.R W = 0, SSPSTAT.D A = 0):
In diesem Fall muss der Mikrocontroller (Slave) die empfangenen Daten aus dem SSPBuffer (Register SSPBUF) lesen, kann den Inhalt von SSPBUF aber verwerfen, da es nur
die Adresse und keine Daten enthält (Zeile 89). Hier wird der Inhalt von SSPBUF in ein
Dummy-Register geschrieben. Wichtig ist das dass Register SSPBUF gelesen wird, weil
dadurch Steuerbits für das Hardwaremodul verändert werden. Wichtig sind auch die folgenden Codezeilen 90 bis 93. Das SSP-Interrupt-Flag (SSPIF) muss ebenfalls gelöscht
werden, da sonst dieser Interrupt sofort wieder ausgelöst wird!
Fall 2: Schreibzugriff aus Sicht des Masters, zuletzt wurde ein Datenbyte empfangen (Bits:
SSPSTAT.R W = 0, SSPSTAT.D A = 1):
Jetzt handelt es sich tatsächlich um die Nutzdaten. Bei diesem Demonstrationsbeispiel
wird nur ein 1 Datenbyte übertragen. Daher sind dies die einzigen Nutzdaten und können
vom Register SSPBUF gelesen und in ein eigenes Register gespeichert werden, oder so
wie hier direkt am Port D ausgegeben werden (Zeile 99). Auch hier sind die folgenden
Codezeilen 101 bis 103 wichtig und dürfen nicht weggelassen werden!
Fall 3: Lesezugriff aus Sicht des Masters, zuletzt wurde die Slave-Adresse empfangen (Bits:
SSPSTAT.R W = 1, SSPSTAT.D A = 0):
In diesem Fall müssen die zu sendenden Nutzdaten in das Register SSPBUF geschrieben
werden. Hier, bei diesem Demonstrationsbeispiel ist dies der Inhalt von Port A (Zeile 114).
Auch hier sind die folgenden Codezeilen 116 bis 118 wichtig und dürfen nicht weggelassen
werden!
Fall 4: Lesezugriff aus Sicht des Masters, zuletzt wurde ein Datenbyte gesendet (Bits:
SSPSTAT.R W = 1, SSPSTAT.D A = 1):
Meiner Ansicht nach dürfte bei diesem Demonstrationsbeispiel dieser Fall gar nicht auftreten, da vom Master nur ein Datenbyte gelesen werden darf. Daher wird in diesem Fall
nur der Inhalt einer Dummy-Variable (cDummy) in das Register SSPBUF geschrieben (Zeile 124). Auch hier sind die folgenden Codezeilen 125 bis 127 wichtig und dürfen nicht
weggelassen werden!
Mehr als das Lesen des SSPBUF-Registers oder das Schreiben in das SSPBUF-Register ist in
der Interrupt-Service-Routine (ISR) nicht zu tun. Alles andere übernimmt das HardwareModul SSP des Mikrocontrollers.
5 DEMONSTRATIONSBEISPIELE
22
Sonstiges:
Am Beginn des Quellcodes befinden sich die folgenden Definitionen und Einstellungen:
• Definition der globalen Register (hier nur cDummy, Zeile 37)
• Die Funktionsprototypen für die hier verwendeten Unterprogramme (hier nur für
das Unterprogramm Init, Zeile 59)
• Ab Zeile 62 beginnt der Quellcode der ausreichend mit Kommentaren versehen ist
Ein kleiner Nachteil beim mikroC-Compiler ist, dass die Konfigurationsbits für den PICMikrocontroller in der IDE gesetzt werden müssen. Ich persönlich würde diese lieber im
Quellcode mit einer geeigneten Anweisung setzen.
Hier sind die notwendigen Einstellungen für den PIC16F887 für dieses Demonstrationsbeispiel (für Slave und Master):
!
!
!
!
!
!
!
!
!
!
!
!
!
INTOSCIO
WDT OFF
PWRTE OFF
MCLRE ON
CP OFF
CPD OFF
BOR OFF
IESO OFF
FCMEN OFF
LVP OFF
DEBUG OFF
WRT OFF
WRT 1FOURTH
5 DEMONSTRATIONSBEISPIELE
5.4
23
Software für 1. Demo (Master)
Für den I2 C-Bus-Master wurde hier ebenfalls ein Mikrocontroller vom Typ PIC16F887
verwendet. Dieser hat hier folgende Aufgabe: Jedes mal wenn sich bei IC3 (PCF8574)
zumindest ein Port-Pin (P0 bis P7) ändert erzeugt dieser Chip einen Interrupt, indem
der Ausgang INT (Pin 13) den Pegel von High auf Low ändert. Daraufhin soll der Master
diesen (geänderten) Eingang lesen und am PIC-I2 C-Slave (am Port D) ausgeben. Danach
soll der Master die Daten vom PIC-I2 C-Slave (vom Port A) lesen und am IC4 (PCF8574)
ausgeben.
Der Quellcode für den I2 C-Bus-Master (mit dem PIC16F887, IC2) ist zur besseren Übersicht in mehrere Dateien aufgeteilt:
• I2C Demo PIC Master.c beinhaltet das Hauptprogramm und das Unterprogramm
zur Initialisierung des Mikrocontrollers (PIC16F887).
• PCF8574.C beinhaltet die Unterprogramme zur Datenübertragung mit dem PCF8574.
• PCF8574.H ist die Headerdatei zu PCF8574.C
Zuerst die Datei I2C Demo PIC Master.c:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Demo z u r Ansteuerung d e s PIC16Fxx a l s I2C−S l a v e gemaess A p p l i c a t i o n Note AN734
∗/
/∗
∗/
/∗ Master
∗/
/∗
∗/
/∗ Demo 1 : j e w e i l s nur e i n Byte vom Port B l e s e n und an den Master s e n d e n bzw . e i n
∗/
/∗
Byte vom Master l e s e n und am Port D a u s g e b e n
∗/
/∗
∗/
/∗ M i k r o c o n t r o l l e r :
PIC16F887
∗/
/∗ Takt :
i n t e r n e r Takt ( 4 , 0 MHz)
∗/
/∗
∗/
/∗ Compiler :
mikroC V8 . 2
∗/
/∗
∗/
/∗ E n t w i c k l e r :
S t e f a n Buchgeher
∗/
/∗ E n t w i c k l u n g s b e g i n n d e r S o f t w a r e : 1 9 . Februar 2014
∗/
/∗ F u n k t i o n s f a e h i g s e i t :
2 . Maerz 2014
∗/
/∗ L e t z t e B e a r b e i t u n g :
4 . J u l i 2014
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ I n c l u d e −D a te i e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
#include ”PCF8574.H”
#include ”PCF8574A.H”
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ S t r u k t u r e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e S t r u k t u r e n v e r w e n d e t ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ E x te r n e R e g i s t e r ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e e x t e r n e n R e g i s t e r ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ B i t s i n den e x t e r n e n R e g i s t e r n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e e x t e r n e n R e g i s t e r ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ G l o b a l e R e g i s t e r ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e g l o b a l e n R e g i s t e r ∗/
5 DEMONSTRATIONSBEISPIELE
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
24
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ B i t s i n den g l o b a l e n R e g i s t e r n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e g l o b a l e n R e g i s t e r ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ P o r t b e l e g u n g ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ \INT−Ausgang d e s PCF8574 ∗/
#define nINTPCF8574
PORTC. F5
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ Konstanten ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Konstanten f u e r I2C ∗/
#define noACK
0
#define ACK
1
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ T a b e l l e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e T a b e l l e n ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ F u n k t i o n s p r o t o t y p e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Unterprogramm z u r I n i t i a l i s i e r u n g d e s M i k r o c c n t r o l l e r s ∗/
void I n i t ( void ) ;
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ Unterprogramme und Funktionen ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ I n i t :
∗/
/∗
∗/
/∗ Aufgabe :
∗/
/∗
I n i t i a l i s i e r u n g des P r o z e s s o r :
∗/
/∗
+ internen Os z i l l a to r konfigurieren
∗/
/∗
+ Ports konf i gur i er en
∗/
/∗
∗/
/∗ U e b e r g a b e p a r a m e te r :
∗/
/∗
keiner
∗/
/∗
∗/
/∗ Rueckgabeparameter :
∗/
/∗
keiner
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
void I n i t ( void )
{
// ( i n t e r n e n ) O s z i l l a t o r k o n f i g u r i e r e n
OSCCON = 0 b01100001 ;
// Sync O s c i l l a t o r C o n t r o l R e g i s t e r
/∗
+−−−−−−−−−−−−−−−−−−−− B i t 7 R e s e r v e
+++−−−−−−−−−−−−−−−−− B i t 6−4 ( IRCF2 : IRCF0 ) : I n t e r n a l O s c i l l a t o r Frequency
||||
Select bits
||||
000 : 31 kHz (LFINTOSC)
||||
001 : 125 kHz
||||
010 : 250 kHz
||||
011 : 500 kHz
||||
100 : 1 MHz
||||
101 : 2 MHz
||||
−> 110 : 4 MHz ( d e f a u l t )
||||
111 : 8 MHz
+−−−−−−−−−−−−−−−− B i t 3 (OSTS) : O s c i l l a t o r S t a r t −up Time−out S t a t u s
|||
( Read Only )
|||
0 : D e v i c e i s r u n n i n g from th e c l o c k d e f i n e d
|||
by FOSC2 : FOSC0 o f th e CONFIG1 r e g i s t e r
|||
1 : D e v i c e i s r u n n i n g from th e i n t e r n a l
|||
oscillator
(HFINTOSC o r LFINTOSC)
+−−−−−−−−−−−−−−− B i t 2 (HTS) : HFINTOSC S t a t u s b i r
||
( High Frequency − 125 kHz to 8MHz)
||
( Read Only )
||
0 : HFINTOSC i s not s t a b l e
||
1 : HFINTOSC i s s t a b l e
+−−−−−−−−−−−−−− B i t 1 (LTS) : LFINTOSC S t a t u s b i t
|
(Low Frequency − 31kHz )
|
( Read Only )
25
5 DEMONSTRATIONSBEISPIELE
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
0 : LFINTOSC i s not s t a b l e
|
1 : LFINTOSC i s s t a b l e
+−−−−−−−−−−−−− B i t 0 (SCS ) : System Clock S e l e c t b i t
0 : Clock s o u r c e d e f i n e d by FOSC2 : FOSC0
o f th e CONFIG1 r e g i s t e r
−>
1 : I n t e r n a l o s c i l l a t o r i s used f o r system
clock
∗/
/∗
// P o r t s k o n f i g u r i e r e n
TRISC = 0 b00100000 ;
+−−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−
// R i c h t u n g s r e g i s t e r
B i t 7 Port RC7 : h i e r
B i t 6 Port RC6 : h i e r
B i t 5 Port RC5 : h i e r
B i t 4 Port RC4 : h i e r
B i t 3 Port RC3 : h i e r
B i t 2 Port RC2 : h i e r
B i t 1 Port RC1 : h i e r
B i t 0 Port RC0 : h i e r
Port C ( 0 : Ausgang , 1 : Eingang )
u n b e n u tz t
u n b e n u tz t
Eingang (/ INT )
Ausgang (SDA)
Ausgang (SCL)
u n b e n u tz t
u n b e n u tz t
u n b e n u tz t
∗/
}
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ Hauptprogramm ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Aufgaben d e s Hauptprogramms :
∗/
/∗
+ C o n t r o l l e r i n i t i a l i s i e r e n ( Unterprogramm I n i t )
∗/
/∗
+ Takt f u e r I2C−Bus f e s t l e g e n ( h i e r 100 kHz mit dem Unterprogramm I 2 C I n i t )
∗/
/∗
+ 8−Bit−Wert vom Eingabemodul ( mit dem PCF8574 ) l e s e n und am I2C−PIC−S l a v e
∗/
/∗
ausgeben
∗/
/∗
+ Daten vom I2C−PIC−S l a v e l e s e n und am I2C−LED−Modul ( mit einem w e i t e r e n PCF8574 ) ∗/
/∗
ausgeben
∗/
/∗
+ T a e t i g k e i t e n / Unterprogramme , d i e a l l e z y k l i s c h d u r c h g e f u e h r t werden muessen :
∗/
/∗
+ b e i jedem I n t e r r u p t d e s PCF8574 (A) d i e Daten vom Eingabemodul ( mit dem
∗/
/∗
PCF8574 ) l e s e n und am I2C−PIC−S l a v e a u s g e b e n . A n s c h l i e s s e n d Daten vom I2C−
∗/
/∗
PIC−S l a v e l e s e n und am LED−Ausgabemodul a u s g e b e n .
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
void main ( void )
{
char cTemp ;
// C o n t r o l l e r
Init () ;
initialisieren
// I2C i n i t i a l i s i e r e n
I2C Ini t (100000) ;
// I2C−T a k t f r e q u e n z : 100 kHz
// Demo 1 : 8−Bit−Wert vom I2C−Eingabemodul l e s e n . . .
cTemp = I2C PCF8574 ReadData ( 1 ) ;
// M o d u l a d r e s s e : h i e r 1
// . . . und am I2C−PIC−S l a v e a u s g e b e n
I2C Start () ;
// S t a r t b e d i n g u n g
I2C Wr (0 b00110000 ) ;
// B a u s t e i n a d r e s s e + S c h r e i b z u g r i f f
I2C Wr ( cTemp ) ;
// Daten an den PIC−S l a v e s c h r e i b e n
I2 C S to p ( ) ;
// S to p b e d i n g u n g
// Demo 2 : Daten vom I2C−PIC−S l a v e l e s e n
I2C Start () ;
I2C Wr (0 b00110001 ) ;
cTemp = I2C Rd (noACK) ;
I2 C S to p ( ) ;
// . . . und am I2C−LED−Modul a u s g e b e n
cTemp = ˜cTemp ;
I2C PCF8574 WriteData ( 3 , cTemp ) ;
// E n d l o s s c h l e i f e
while ( 1 )
{
...
//
//
//
//
Startbedingung
Bausteinadresse + L es e zu gr i f f
Daten vom PIC−S l a v e l e s e n
S to p b e d i n g u n g
// M o d u l a d r e s s e : h i e r 3
5 DEMONSTRATIONSBEISPIELE
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
26
// b e i jedem I n t e r r u p t d e s PCF8574 (A)
i f ( nINTPCF8574 == 0 )
{
// Demo 1 : 8−Bit−Wert vom I2C−Eingabemodul l e s e n . . .
cTemp = I2C PCF8574 ReadData ( 1 ) ;
// M o d u l a d r e s s e : h i e r 1
// . . . und am I2C−PIC−S l a v e a u s g e b e n
I2C Start () ;
// S t a r t b e d i n g u n g
I2C Wr (0 b00110000 ) ;
// B a u s t e i n a d r e s s e + S c h r e i b z u g r i f f
I2C Wr ( cTemp ) ;
// Daten an den PIC−S l a v e s c h r e i b e n
I2 C S to p ( ) ;
// S to p b e d i n g u n g
// Demo 2 : Daten vom I2C−PIC−S l a v e l e s e n . . .
I2C Start () ;
// S t a r t b e d i n g u n g
I2C Wr (0 b00110001 ) ;
// B a u s t e i n a d r e s s e + L e s e z u g r i f f
cTemp = I2C Rd (noACK) ;
// Daten vom PIC−S l a v e l e s e n
I2 C S to p ( ) ;
// S to p b e d i n g u n g
// . . . und am I2C−LED−Modul a u s g e b e n
cTemp = ˜cTemp ;
I2C PCF8574 WriteData ( 3 , cTemp ) ;
// M o d u l a d r e s s e : h i e r 3
}
}
}
Listing 2: I2C Demo PIC Master.c (Demo 1)
Datei PCF8574.H:
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Header f u e r d i e Unterprogramme z u r Ansteuerung d e s I /O−Port−Expander PCF8574
∗/
/∗
∗/
/∗ Compiler : mikroC V8 . 2
∗/
/∗
∗/
/∗ E n t w i c k l e r : S t e f a n Buchgeher
∗/
/∗ E n t w i c k l u n g s b e g i n n d e r S o f t w a r e : 1 7 . Februar 2013
∗/
/∗ F u n k t i o n s f a e h i g s e i t : 1 7 . Februar 2013
∗/
/∗ L e t z t e B e a r b e i t u n g : 1 7 . Februar 2013
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ G l o b a l e R e g i s t e r ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e g l o b a l e n R e g i s t e r ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ P o r t b e l e g u n g ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e P o r t d e f i n i t i o n e n ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ Konstanten ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e Konstanten ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ F u n k t i o n s p r o t o t y p e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Daten zum I /O−Port−Expander PCF8574 s c h r e i b e n ∗/
void I2C PCF8574 WriteData ( char c D e v i c e A d r e s s e , char cWriteData ) ;
/∗ Daten vom I /O−Port−Expander PCF8574 l e s e n ∗/
unsigned char I2C PCF8574 ReadData ( char c D e v i c e A d r e s s e ) ;
Listing 3: PCF8574.H
Datei PCF8574.C:
234
235
236
237
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Unterprogramme z u r Ansteuerung d e s I /O−Port−Expander PCF8574
∗/
/∗
∗/
/∗ Compiler : mikroC V8 . 2
∗/
27
5 DEMONSTRATIONSBEISPIELE
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
/∗
∗/
/∗ E n t w i c k l e r : S t e f a n Buchgeher
∗/
/∗ E n t w i c k l u n g s b e g i n n d e r S o f t w a r e : 1 7 . Februar 2013
∗/
/∗ F u n k t i o n s f a e h i g s e i t : 1 7 . Februar 2013
∗/
/∗ L e t z t e B e a r b e i t u n g : 1 7 . Februar 2013
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ I n c l u d e −D a te i e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
#include ”PCF8574.H”
#include ”PCF8574A.H”
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ S t r u k t u r e n
/∗ k e i n e S t r u k t u r e n ∗/
∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ G l o b a l e R e g i s t e r ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e g l o b a l e n R e g i s t e r ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ B i t s i n den g l o b a l e R e g i s t e r ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e g l o b a l e n R e g i s t e r ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ Konstanten ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
#define noACK
0
#define ACK
1
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ T a b e l l e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e T a b e l l e n ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ F u n k t i o n s p r o t o t y p e n ( f u e r i n t e r n e H i l f s u n te r p r o g r a m m e ) ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e i n t e r n e n H i l f s u n te r p r o g r a m m e ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ Unterprogramme ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ I2C PCF8574 WriteData :
∗/
/∗
∗/
/∗ Aufgabe :
∗/
/∗
Daten (8− Bit−Wert ) an den PCF8574 s c h r e i b e n
∗/
/∗
∗/
/∗ U e b e r g a b e p a r a m e te r :
∗/
/∗
cDeviceAdresse
B a u s t e i n a d r e s s e gemaess den g e s e t z t e n Jumper A0 b i s A2
∗/
/∗
cWriteData
Daten (8− Bit−Wert ) , w e l c h e an den PCF8574 g e s c h r i e b e n werden ∗/
/∗
∗/
/∗ Rueckgabeparameter :
∗/
/∗
keiner
∗/
/∗
∗/
/∗ V o r g e h e n s w e i s e :
∗/
/∗
S c h r i t t 1 : Die Device −A d r e s s s e e r m i t t e l n
∗/
/∗
S c h r i t t 2 : Daten (8− Bit−Wert ) an den PCF8574 s c h r e i b e n
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
void I2C PCF8574 WriteData ( char c D e v i c e A d r e s s e , char cWriteData )
{
char c H e l p A d r e s s e = c D e v i c e A d r e s s e ;
// S c h r i t t 1 : Device −A d r e s s e zusammensetzen
c H e l p A d r e s s e = 0 b00000111 & c H e l p A d r e s s e ;
c H e l p A d r e s s e = c H e l p A d r e s s e << 1 ;
c H e l p A d r e s s e = 0 b01000000 | c H e l p A d r e s s e ;
// B a u s t e i n a d r e s s e + S c h r e i b z u g r i f f
// S c h r i t t 2 : Daten (8− Bit−Wert ) an den PCF8574 s c h r e i b e n
I2C Start () ;
// S t a r t b e d i n g u n g
I2C Wr ( c H e l p A d r e s s e ) ;
// B a u s t e i n a d r e s s e + S c h r e i b z u g r i f f
I2C Wr ( cWriteData ) ;
// Daten an den PCF8574 s c h r e i b e n
I2 C S to p ( ) ;
// S to p b e d i n g u n g
}
28
5 DEMONSTRATIONSBEISPIELE
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ I2C PCF8574 ReadData :
∗/
/∗
∗/
/∗ Aufgabe :
∗/
/∗
Daten (8− Bit−Wert ) vom PCF8574 l e s e n
∗/
/∗
∗/
/∗ U e b e r g a b e p a r a m e te r :
∗/
/∗
cDeviceAdresse
B a u s t e i n a d r e s s e gemaess den g e s e t z t e n Jumper A0 b i s A2
∗/
/∗
∗/
/∗ Rueckgabeparameter :
∗/
/∗
cReadData
Daten (8− Bit−Wert ) , w e l c h e vom PCF8574 empfangen wurden
∗/
/∗
∗/
/∗ V o r g e h e n s w e i s e :
∗/
/∗
S c h r i t t 1 : Die Device −A d r e s s s e e r m i t t e l n
∗/
/∗
S c h r i t t 2 : Daten (8− Bit−Wert ) vom PCF8574 l e s e n
∗/
/∗
S c h r i t t 3 : Empfangenen Wert an das a u f r u f e n d e Programm u e b e r g e b e n
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
unsigned char I2C PCF8574 ReadData ( char c D e v i c e A d r e s s e )
{
char c H e l p A d r e s s e = c D e v i c e A d r e s s e ;
char cReadData ;
// S c h r i t t 1 : Device −A d r e s s e zusammensetzen
c H e l p A d r e s s e = 0 b00000111 & c H e l p A d r e s s e ;
c H e l p A d r e s s e = c H e l p A d r e s s e << 1 ;
c H e l p A d r e s s e = 0 b01000001 | c H e l p A d r e s s e ;
// B a u s t e i n a d r e s s e + L e s e z u g r i f f
// S c h r i t t 2 : Daten (8− Bit−Wert ) vom PCF8574 l e s e n
I2C Start () ;
// S t a r t b e d i n g u n g
I2C Wr ( c H e l p A d r e s s e ) ;
// B a u s t e i n a d r e s s e + L e s e z u g r i f f
cReadData = I2C Rd (noACK) ;
I2 C S to p ( ) ;
// S to p b e d i n g u n g
// S c h r i t t 3 : Empfangenen Wert an das a u f r u f e n d e Programm u e b e r g e b e n
return ( cReadData ) ;
}
Listing 4: PCF8574.C
5.5
Anmerkungen zur Software für 1. Demo (Master)
Auch dieser Quellcode wurde in C mit der freien Demoversion des mikroC-Compilers
erstellt.
Die Software (für den PIC-I2 C-Master) besteht im Wesentlichen aus den folgenden Programmteilen:
• Hauptprogramm am Ende des Quellcodes von I2C Demo PIC Master.c, Zeilen 148
bis 203.
• 1 Unterprogramm zur Initialisierung des PIC16F887 (Unterprogramm Init in der
Datei I2C Demo PIC Master.c, Zeilen 81 bis 130).
• 2 Unterprogramme zur Kommunikation mit dem PCF8574 (I2C PCF8574 WriteData,
Zeilen 293 bis 308 und I2C PCF8574 ReadData, Zeilen 330 bis 347 in der Datei
PCF8574.C.
5 DEMONSTRATIONSBEISPIELE
29
Hauptprogramm:
Zuerst muss der Mikrocontroller initialisiert werden. Diese Aufgabe übernehmen die Unterprogramme Init(), Zeile 153 und I2C Init(), Zeile 156.
Danach werden zum ersten Mal die Portpins vom I2 C-Eingabemodul mit dem PCF8574
(IC3) gelesen und am I2 C-PIC-Slave ausgegeben. Das Lesen vom I2 C-Eingabemodul geschieht mit dem Unterprogramm I2C PCF8574 ReadData (Zeile 159). Übergabeparameter
ist hier die Moduladresse (3-Bit entsprechend den Pins A2 bis A0). Hier der Wert 1, da
A0 offen ist - also den Pegel High besitzt, während A1 und A2 via Jumper auf low-Pegel
liegen (vgl. Schaltung in Abbildung 7, Seite 12).
Für das Ausgeben der Daten am I2 C-PIC-Slave muss zunächst die I2 C-Startbedingung
erzeugt werden (Zeile 161) anschließend die Adresse des I2 C-PIC-Slave inkl. Schreibzugriff
(Zeile 162, hier 0b00110000 da die Jumper JP1, JP2, JP3 und JP6 gesetzt sind, siehe
Abbildung 7 Seite 12. Das letzte niederwertigste Bit gibt die Zugriffsrichtung an. Hier 0 da
es sich um einen Schreibzugriff aus Sicht des Masters handelt.) Anschließend werden die
Daten an den I2 C-PIC-Slave geschrieben (Zeile 163) und zum Schluss die Stopbedingung
(Zeile 164).
Der umgekehrte Weg, also das Lesen von Daten vom I2 C-PIC-Slave und Ausgeben am
I2 C-Ausgabemodul mit dem PCF8574 (IC4) ist ähnlich: Für das Lesen vom I2 C-PIC-Slave
muss zunächst (wieder) die I2 C-Startbedingung erzeugt werden (Zeile 168) anschließend
die Adresse des I2 C-PIC-Slave hier inkl. Lesezugriff (Zeile 169). Das letzte niederwertigste Bit ist hier 1 da es sich um einen Lesezugriff aus Sicht des Masters handelt. Gefolgt
vom Lesen der Daten vom I2 C-PIC-Slave (Zeile 170) und zum Schluss wieder die Stopbedingung (Zeile 171). Der Übergabeparameter noACK bedeutet, dass keine weiteren Daten
gelesen werden.
Das Schreiben der gelesenen Daten (diese befinden sich im Register cTemp) am I2 CAusgabemodul erfolgt mit dem Unterprogramm I2C PCF8574 WriteData (Zeile 174).
Übergabeparameter sind hier die Moduladresse (auch hier 3-Bit, entsprechend den Pins
A2 bis A0. Hier der Wert 3, da A0 und A1 offen sind - also den Pegel High besitzen,
während A2 via Jumper auf low-Pegel liegen) und die zu schreibenden Daten. Beachte. Die Leuchtdioden beim Ausgabemodul sind gegen +5V geschaltet. D.h. damit eine
Leuchtdiode leuchtet muss am Portpin Px low anliegen. Daher muss das Register cTemp
invertiert werden bevor es am I2 C-Ausgabemodul ausgegeben werden kann (Zeile 199).
Nun befindet sich das Hauptprogramm in einer Endlosschleife. Jedesmal wenn am I2 CEingabemodul ein Portpin verändert wird erzeugt der PCF8574 einen so genannten Interrupt, indem der Pin 13 (INT) von High nach Low übergeht. Dieser Interrupt-Pin ist
sozusagen die fünfte Leitung des I2 C-Buses und kann mit einem beliebigen I/O-Pin des Mikrocontrollers verbunden werden. Hier ist es der Portpin RC5 (vgl. Schaltbild nach Abbildung 7, Seite 12). In meiner Software erhält dieser Portpin die Bezeichnung nINTPCF8574
(Zeile 47). Immer wenn dieser Portpin low ist, also wenn am I2 C-Eingabemodul zumindest
ein Portpin verändert wurde soll der geänderten Eingang gelesen und am PIC-I2 C-Slave
ausgeben werden (Zeilen 184 bis 189). Danach sollen die Daten vom PIC-I2 C-Slave gelesen
und am I2 C-Ausgabemodul ausgeben werden (Zeilen 193 bis 200).
5 DEMONSTRATIONSBEISPIELE
30
Hinweise:
• Der Interrupt-Pin (INT, Pin 13) des PCF8574 geht in seinen Ruhepegel (High) über,
nachdem sein Portzustand gelesen wurde.
• Die Zeilen 184 bis 189 sind die gleichen wie 161 bis 164, und die Zeilen 193 bis 200
sind gleich mit den Zeilen 168 bis 174.
Beachte:
Die Unterprogramme und Funktionen I2c Init(), I2c Start(), I2c Stop(),
I2c Wr() und I2c Rd() stellt der mikroC-Compiler zur Verfügung. Diese müssen
hier nicht mittels include-Anweisung eingebunden werden. Diese Unterprogramme und Funktionen steuern dass SSP-Hardware-Modul im I2 C-Master-Mode.
Unterprogramm Init:
Das Unterprogramm Init (Datei: I2C Demo PIC Master.c, Zeilen 81 bis 130) dient zur
Initialisierung des Mikrocontrollers. Hier wird der interne Oszillator konfiguriert (also auf
4MHz eingestellt, Zeile 84) und die Pins des Port C für den I2 C-Bus als Ein- oder Ausgang
definiert (Zeile 120). Die anderen Ports (A, B, D und E) werden hier nicht benötigt, und
müssen daher auch nicht konfiguriert werden.
Im Gegensatz zum Slave muss hier das SSP-Hardware-Module für den Mastermode nicht
initialisiert werden. Diese Aufgabe übernimmt das Unterprogramm I2c Init(), welches
vom microC-Compiler zur Verfügung gestellt wird.
Unterprogramme I2C PCF8574 WriteData und I2C PCF8574 ReadData:
Das Unterprogramm I2C PCF8574 WriteData (Datei: PCF8574.C, Zeilen 293 bis 308)
dient zum Schreiben eines 8-Bit-Wertes (Adresse oder Daten) zum PCF8574, während
das Unterprogramm I2C PCF8574 ReadData (Datei: PCF8574.C, Zeilen 228 bis 347) einen
8-Bit-Wert vom PCF8574 liest. Aufgrund der Einfachheit und der ausführlichen Kommentare ist hier eine weitere Erklärung glaube ich nicht notwendig.
Sonstiges:
Am Beginn des Quellcodes (in der Datei I2C Demo PIC Master.c) befinden sich die folgenden Definitionen und Einstellungen:
• Einbinden externer Codeteile (hier die Unterprogramme für den PCF8574, Zeile 21,
oder alternativ die Unterprogramme für den PCF8574A, Zeile 22)
• Portdefinition (hier für den INT-Ausgang des PCF8574, Zeilen 47)
• Konstanten für I2 C (Zeilen 52 und 53)
• Funktionsprototyp für das hier verwendete Unterprogramm (Zeile 62)
• Ab Zeile 81 beginnt der Quellcode der ausreichend mit Kommentaren versehen ist
5 DEMONSTRATIONSBEISPIELE
31
Ein kleiner Nachteil beim mikroC-Compiler ist, dass die Konfigurationsbits für den PICMikrocontroller in der IDE gesetzt werden müssen. Ich persönlich würde diese lieber im
Quellcode mit einer geeigneten Anweisung setzen.
Hier sind die notwendigen Einstellungen für den PIC16F887 für dieses Demonstrationsbeispiel (für Master und Slave):
!
!
!
!
!
!
!
!
!
!
!
!
!
5.6
INTOSCIO
WDT OFF
PWRTE OFF
MCLRE ON
CP OFF
CPD OFF
BOR OFF
IESO OFF
FCMEN OFF
LVP OFF
DEBUG OFF
WRT OFF
WRT 1FOURTH
Software für 2. Demo (Slave)
Beim zweiten Demonstrationsbeispiel sendet der I2 C-Master mehrere Datenbytes (hier
vier) zum PIC-I2 C-Slave, bzw. liest anschließend auch mehrere Datenbytes (auch vier)
vom PIC-I2 C-Slave.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Demo z u r Ansteuerung d e s PIC16Fxx a l s I2C−S l a v e gemaess A p p l i c a t i o n Note AN734
∗/
/∗
∗/
/∗ S l a v e
∗/
/∗
∗/
/∗ Demo 2 : e i n Byte vom Port A l e s e n und i n einem Array s p e i c h e r n . D i e s e s Array mit
∗/
/∗
w e i t e r e n b e l i e b i g e n Werten a u f f u e l l e n , und das gesamte Array v i a I2C an den ∗/
/∗
S l a v e s e n d e n . Ebenso e i n Array v i a I2C empfangen und das z u l e t z t empfangene ∗/
/∗
Byte am Port D a u s g e b e n .
∗/
/∗
∗/
/∗ M i k r o c o n t r o l l e r :
PIC16F887
∗/
/∗ Takt :
i n t e r n e r Takt ( 4 . 0 MHz)
∗/
/∗
∗/
/∗ Compiler :
mikroC V8 . 2
∗/
/∗
∗/
/∗ E n t w i c k l e r :
S t e f a n Buchgeher
∗/
/∗ E n t w i c k l u n g s b e g i n n d e r S o f t w a r e : 2 . Maerz 2014
∗/
/∗ F u n k t i o n s f a e h i g s e i t :
2 . Maerz 2014
∗/
5 DEMONSTRATIONSBEISPIELE
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
32
/∗ L e t z t e B e a r b e i t u n g :
4 . J u l i 2014
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ I n c l u d e −D a te i e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e I n c l u d e −D a te i e n ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ S t r u k t u r e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e S t r u k t u r e n v e r w e n d e t ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ E x te r n e R e g i s t e r ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e e x t e r n e n R e g i s t e r ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ B i t s i n den e x t e r n e n R e g i s t e r n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e e x t e r n e n R e g i s t e r ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ G l o b a l e R e g i s t e r ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
char
cDummy ;
char
char
char
char
c I2 C R e a d B u f f e r [ ] = { 0 , 0 , 0 , 0 } ;
cI2CWriteBuffer [ ] = {0 , 0 , 0 , 0};
c I2 C R e a d B u f f e r In d e x = 0 ;
cI2CWriteBufferIndex = 0;
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ B i t s i n den g l o b a l e n R e g i s t e r n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e g l o b a l e n R e g i s t e r ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ P o r t b e l e g u n g ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ \INT−Ausgang d e s PCF8574 ∗/
//#d e f i n e nINTPCF8574
PORTC. F5
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ Konstanten ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Konstanten I2C−S c h r e i b und L e s e b u f f e r ∗/
//#d e f i n e
READBUFFERMAX
4
//#d e f i n e
WRITEBUFFERMAX
4
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ T a b e l l e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e T a b e l l e n ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ F u n k t i o n s p r o t o t y p e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Unterprogramm z u r I n i t i a l i s i e r u n g d e s M i k r o c c n t r o l l e r s ∗/
void I n i t ( void ) ;
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ I n t e r r u p t −S e r v i c e −R o u ti n e ( ISR ) ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ I n t e r r u p t S e r v i c e R o u ti n e :
∗/
/∗
∗/
/∗ A u f r u f :
∗/
/∗
SSP I n t e r r u p t F l a g ( SSPIF ) , nach jedem I2C−Event ( wenn d e r Master e i n e A d r e s s e
∗/
/∗
a u f den I2C−Bus s c h r e i b t o d e r wenn s i c h Daten am I2C−Bus b e f i n d e n
∗/
/∗
∗/
/∗ Aufgaben :
∗/
/∗
+ Je nach S t a t u s s i n d u n t e r s c h i e d l i c h e Aktionen a u s z u f u e h r e n : s i e h e Kommentare im ∗/
/∗
Quellcode
∗/
/∗
+ Nach j e d e r Aktion muss das SSP−I n t e r r u p t −F l a g SSPIF w i e d e r g e l o e s c h e n werden
∗/
/∗
∗/
/∗ Achtung :
∗/
/∗
Der S t a t u s Lesen bzw . S c h r e i b e n e r f o l g t immer aus S i c h t d e s Master ! !
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
void i n t e r r u p t ( void )
// I n t e r r u p t r o u t i n e
{
5 DEMONSTRATIONSBEISPIELE
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
33
i f (SSPSTAT .R W == 0 )
{
// S c h r e i b z u g r i f f e ( aus S i c h t d e s Masters , d . h . S l a v e muss Daten aus dem Sende−
// und E m p f a n g s b u f f e r (SSPBUF) l e s e n )
i f (SSPSTAT . D A == 0 )
{
// S t a t e 1 : I2C w r i t e o p e r a t i o n , l a s t b y te was an a d d r e s s b y te
// SSPSTAT b i t s : S=1 , D/A=0 , R/W=0 , BF=1
cDummy = SSPBUF ;
SSPSTAT . BF = 0 ;
SSPCON.CKP = 1 ;
// C l o c k s t r e t c h i n g e r l a u b e n
cI2CWriteBufferIndex = 0;
PIR1 . SSPIF = 0 ;
// SSP−I n t e r r u p t −F l a g w i e d e r l o e s c h e n
return ;
}
else
{
// S t a t e 2 : I2C w r i t e o p e r a t i o n , l a s t b y te was a data b y te
// SSPSTAT b i t s : S=1 , D/A=1 , R/W=1 , BF=1
c I 2 C W r i t e B u f f e r [ c I 2 C W r i t e B u f f e r I n d e x ] = SSPBUF ; // Datenbyte von SSPBUF
// l e s e n und i n s Array s c h r e i b e n
cI2CWriteBufferIndex = cI2CWriteBufferIndex + 1;
SSPCON.CKP = 1 ;
// C l o c k s t r e t c h i n g e r l a u b e n
PIR1 . SSPIF = 0 ;
// SSP−I n t e r r u p t −F l a g w i e d e r l o e s c h e n
return ;
}
}
else
{
// L e s e z u g r i f f ( aus S i c h t d e s Masters , d . h . S l a v e muss Daten i n Sende− und
// E m p f a n g s b u f f e r (SSPBUF) s c h r e i b e n )
i f (SSPSTAT . D A == 0 )
{
// S t a t e 3 : I2C r e a d o p e r a t i o n , l a s t b y te was an a d d r e s s b y te
// SSPSTAT b i t s : S=1 , D/A=0 , R/W=1 , BF=0
SSPBUF = c I2 C R e a d B u f f e r [ 0 ] ;
// Datenbyte von Array l e s e n und i n SSPBUF
c I2 C R e a d B u f f e r In d e x = 0 ;
SSPCON.CKP = 1 ;
// C l o c k s t r e t c h i n g e r l a u b e n
PIR1 . SSPIF = 0 ;
// SSP−I n t e r r u p t −F l a g w i e d e r l o e s c h e n
return ;
}
else
{
// S t a t e 4 : I2C r e a d o p e r a t i o n , l a s t b y te was a data b y te
// SSPSTAT b i t s : S=1 , D/A=1 , R/W=0 , BF=0
c I2 C R e a d B u f f e r In d e x = c I2 C R e a d B u f f e r In d e x + 1 ;
SSPBUF = c I2 C R e a d B u f f e r [ c I2 C R e a d B u f f e r In d e x ] ;
// Datenbyte von Array
// l e s e n und i n SSPBUF
SSPCON.CKP = 1 ;
// C l o c k s t r e t c h i n g e r l a u b e n
PIR1 . SSPIF = 0 ;
// SSP−I n t e r r u p t −F l a g w i e d e r l o e s c h e n
return ;
}
}
}
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ Unterprogramme und Funktionen ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ I n i t :
∗/
/∗
∗/
/∗ Aufgabe :
∗/
/∗
I n i t i a l i s i e r u n g des P r o z e s s o r :
∗/
/∗
+ internen Os z i l l a to r konfigurieren
∗/
/∗
+ P o r t s a u f D i g i t a l I /O u m s c h a l te n und a l s Ein− o d e r Ausgang k o n f i g u r i e r e n
∗/
/∗
+ I2C−Hardware−Modul a l s S l a v e k o n f i g u r i e r e n
∗/
/∗
+ I2C S l a v e A d r e s s e von Port B l e s e n und i n SSPADD s c h r e i b e n
∗/
/∗
+ Interrupt freigeben
∗/
/∗
∗/
/∗ U e b e r g a b e p a r a m e te r :
∗/
/∗
keiner
∗/
5 DEMONSTRATIONSBEISPIELE
34
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/∗
∗/
/∗ Rueckgabeparameter :
∗/
/∗
keiner
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
void I n i t ( void )
{
char c I2 C A d r e s s e ;
// I2C−S l a v e −A d r e s s e
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
∗/
/∗
/∗
// ( i n t e r n e n ) O s z i l l a t o r k o n f i g u r i e r e n
OSCCON = 0 b01100001 ;
// Sync O s c i l l a t o r C o n t r o l R e g i s t e r
+−−−−−−−−−−−−−−−−−−−− B i t 7 R e s e r v e
+++−−−−−−−−−−−−−−−−− B i t 6−4 ( IRCF2 : IRCF0 ) : I n t e r n a l O s c i l l a t o r Frequency
||||
Select bits
||||
000 : 31 kHz (LFINTOSC)
||||
001 : 125 kHz
||||
010 : 250 kHz
||||
011 : 500 kHz
||||
100 : 1 MHz
||||
101 : 2 MHz
||||
−> 110 : 4 MHz ( d e f a u l t )
||||
111 : 8 MHz
+−−−−−−−−−−−−−−−− B i t 3 (OSTS) : O s c i l l a t o r S t a r t −up Time−out S t a t u s
|||
( Read Only )
|||
0 : D e v i c e i s r u n n i n g from th e c l o c k d e f i n e d
|||
by FOSC2 : FOSC0 o f th e CONFIG1 r e g i s t e r
|||
1 : D e v i c e i s r u n n i n g from th e i n t e r n a l
|||
oscillator
(HFINTOSC o r LFINTOSC)
+−−−−−−−−−−−−−−− B i t 2 (HTS) : HFINTOSC S t a t u s b i r
||
( High Frequency − 125 kHz to 8MHz)
||
( Read Only )
||
0 : HFINTOSC i s not s t a b l e
||
1 : HFINTOSC i s s t a b l e
+−−−−−−−−−−−−−− B i t 1 (LTS) : LFINTOSC S t a t u s b i t
|
(Low Frequency − 31kHz )
|
( Read Only )
|
0 : LFINTOSC i s not s t a b l e
|
1 : LFINTOSC i s s t a b l e
+−−−−−−−−−−−−− B i t 0 (SCS ) : System Clock S e l e c t b i t
0 : Clock s o u r c e d e f i n e d by FOSC2 : FOSC0
o f th e CONFIG1 r e g i s t e r
−>
1 : I n t e r n a l o s c i l l a t o r i s used f o r system
clock
// A l l e P o r t s a u f d i g i t a l I /O k o n f i g u r i e r e n
ANSEL = 0 b00000000 ;
// Analog S e l e c t R e g i s t e r
||||||||
//
( 0 : D i g i t a l I /O, 1 : A n a l o g e i n g a n g )
+−−−−−−−−−−−−−−−−−−−−− B i t 7 : Port RE2/AN7 i s t h i e r D i g i t a l I /O
+−−−−−−−−−−−−−−−−−−−− B i t 6 : Port RE1/AN6 i s t h i e r D i g i t a l I /O
+−−−−−−−−−−−−−−−−−−− B i t 5 : Port RE0/AN5 i s t h i e r D i g i t a l I /O
+−−−−−−−−−−−−−−−−−− B i t 4 : Port RA5/AN4 i s t h i e r D i g i t a l I /O
+−−−−−−−−−−−−−−−−− B i t 3 : Port RA3/AN3 i s t h i e r D i g i t a l I /O
+−−−−−−−−−−−−−−−− B i t 2 : Port RA2/AN2 i s t h i e r D i g i t a l I /O
+−−−−−−−−−−−−−−− B i t 1 : Port RA1/AN1 i s t h i e r D i g i t a l I /O
+−−−−−−−−−−−−−− B i t 0 : Port RA0/AN0 i s t h i e r D i g i t a l I /O
∗/
/∗
ANSELH = 0 b00000000 ;
||||||||
++−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−
+−−−−−−−−−−−−−
// Analog S e l e c t R e g i s t e r
//
( 0 : D i g i t a l I /O, 1 : A n a l o g e i n g a n g )
Bit 6 ,7 Reserve
B i t 5 : Port RB5/AN13 i s t h i e r D i g i t a l I /O
B i t 4 : Port RB0/AN12 i s t h i e r D i g i t a l I /O
B i t 3 : Port RB4/AN11 i s t h i e r D i g i t a l I /O
B i t 2 : Port RB1/AN10 i s t h i e r D i g i t a l I /O
B i t 1 : Port RB9/AN9 i s t h i e r D i g i t a l I /O
B i t 0 : Port RB2/AN8 i s t h i e r D i g i t a l I /O
// P o r t s k o n f i g u r i e r e n
TRISA = 0 b11111111 ;
// R i c h t u n g s r e g i s t e r Port A ( 0 : Ausgang , 1 : Eingang )
∗/
35
5 DEMONSTRATIONSBEISPIELE
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
/∗
+−−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−
Bit
Bit
Bit
Bit
Bit
Bit
Bit
Bit
7
6
5
4
3
2
1
0
Port
Port
Port
Port
Port
Port
Port
Port
RA7 :
RA6 :
RA5 :
RA4 :
RA3 :
RA2 :
RA1 :
RA0 :
hier
hier
hier
hier
hier
hier
hier
hier
Eingang
Eingang
Eingang
Eingang
Eingang
Eingang
Eingang
Eingang
( Jumper
( Jumper
( Jumper
( Jumper
( Jumper
( Jumper
( Jumper
( Jumper
Pin
Pin
Pin
Pin
Pin
Pin
Pin
Pin
7)
6)
5)
4)
3)
2)
1)
0)
∗/
/∗
TRISB = 0 b00111111 ;
+−−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−
// R i c h t u n g s r e g i s t e r
B i t 7 Port RB7 : h i e r
B i t 6 Port RB6 : h i e r
B i t 5 Port RB5 : h i e r
B i t 4 Port RB4 : h i e r
B i t 3 Port RB3 : h i e r
B i t 2 Port RB2 : h i e r
B i t 1 Port RB1 : h i e r
B i t 0 Port RB0 : h i e r
Port B ( 0 : Ausgang , 1 : Eingang )
u n b e n u tz t
u n b e n u tz t
Eingang ( I2C−S l a v e −A d r e s s e A5)
Eingang ( I2C−S l a v e −A d r e s s e A4)
Eingang ( I2C−S l a v e −A d r e s s e A3)
Eingang ( I2C−S l a v e −A d r e s s e A2)
Eingang ( I2C−S l a v e −A d r e s s e A1)
Eingang ( I2C−S l a v e −A d r e s s e A0)
TRISC = 0 b00011000 ;
+−−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−
// R i c h t u n g s r e g i s t e r
B i t 7 Port RC7 : h i e r
B i t 6 Port RC6 : h i e r
B i t 5 Port RC5 : h i e r
B i t 4 Port RC4 : h i e r
B i t 3 Port RC3 : h i e r
B i t 2 Port RC2 : h i e r
B i t 1 Port RC1 : h i e r
B i t 0 Port RC0 : h i e r
Port C ( 0 : Ausgang , 1 : Eingang )
u n b e n u tz t
u n b e n u tz t
u n b e n u tz t
Eingang (SDA)
Eingang (SCL)
u n b e n u tz t
u n b e n u tz t
u n b e n u tz t
TRISD = 0 b00000000 ;
+−−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−
// R i c h t u n g s r e g i s t e r
B i t 7 Port RD7 : h i e r
B i t 6 Port RD6 : h i e r
B i t 5 Port RD5 : h i e r
B i t 4 Port RD4 : h i e r
B i t 3 Port RD3 : h i e r
B i t 2 Port RD2 : h i e r
B i t 1 Port RD1 : h i e r
B i t 0 Port RD0 : h i e r
Port D ( 0 : Ausgang , 1 : Eingang )
Ausgang (LED D7)
Ausgang (LED D6)
Ausgang (LED D5)
Ausgang (LED D4)
Ausgang (LED D3)
Ausgang (LED D2)
Ausgang (LED D1)
Ausgang (LED D0)
TRISE = 0 b00000000 ;
||||||||
+−−−−−−−−−−−−−−−−−−−−−
|||||||
|||||||
|||||||
|||||||
+−−−−−−−−−−−−−−−−−−−−
||||||
||||||
||||||
||||||
+−−−−−−−−−−−−−−−−−−−
|||||
|||||
|||||
|||||
|||||
+−−−−−−−−−−−−−−−−−−
||||
||||
+−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−
// R i c h t u n g s r e g i s t e r Port E ( 0 : Ausgang , 1 : Eingang )
//
und P a r a l l e l S l a v e Port S t a t u s / C o n t r o l B i t s
B i t 7 ( IBF ) : In p u t B u f f e r F u l l S t a t u s b i t
( Read o n l y )
0 : No word has been r e c e i v e d
1 : A word has been r e c e i v e d and i s w a i t i n g to
be r e a d by th e CPU
B i t 6 (OBF) : Output B u f f e r F u l l S t a t u s b i t
( Read o n l y )
0 : The o u tp u t b u f f e r has been r e a d
1 : The o u tp u t b u f f e r s t i l l h o l d s a p r e v i o u s l y
w r i t t e n word
B i t 5 (IBOV) : In p u t B u f f e r O v e r f l o w D e te c t b i t
( i n M i c r o p r o c e s s o r mode )
0 : No o v e r f l o w o c c u r r e d
1 : A w r i t e o c c u r r e d when a p r e v i o u s l y i n p u t
word has not been r e a d ( must be c l e a r e d
in Software )
B i t 4 (PSPMODE) : P a r a l l e l S l a v e Port Mode S e l e c t
−> 0 : PORTD f u n c t i o n s i n g e n e r a l Purpose I /O mode
1 : PORTD f u n c t i o n s i n P a r a l l e l S l a v e Port mode
Bit 3 Reserve
B i t 2 Port RE2 : h i e r u n b e n u tz t
B i t 1 Port RE1 : h i e r u n b e n u tz t
B i t 0 Port RE0 : h i e r u n b e n u tz t
∗/
/∗
∗/
/∗
∗/
/∗
∗/
PORTA = 0 ;
5 DEMONSTRATIONSBEISPIELE
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
PORTB
PORTC
PORTD
PORTE
/∗
=
=
=
=
36
0;
0;
0;
0;
// I2C−Hardware−Modul a l s S l a v e k o n f i g u r i e r e n
SSPCON = 0 b00100110 ;
// Sync S e r i a l Port C o n t r o l R e g i s t e r 1
+−−−−−−−−−−−−−−−−−−−− B i t 7 (WCOL) : Write C o l l i s i o n D e te c t b i t
|||||||
Master mode :
|||||||
0 : No c o l l i s i o n
|||||||
1 : A w r i t e to SSPBUF was attempt w h i l e th e I2C
|||||||
c o n d i t i o n s were not v a l i s
|||||||
S l a v e mode :
|||||||
0 : No c o l l i s i o n
|||||||
1 : SSPBUF r e g i s t e r i s w r i t t e n w h i l e s t i l l
|||||||
t r a n s m i t t i n g th e p r e v i o u s word ( must be
|||||||
cleared in software )
+−−−−−−−−−−−−−−−−−−− B i t 6 (SSPOV) : R e c e i v e O v e r f l o w I n d i c a t o r b i t
||||||
0 : No o v e r f l o w
||||||
1 : A new b y te i s r e c e i v e d w h i l e SSPBUF h o l d s
||||||
p r e v i o u s data ( w e i t e r s i e h e D a t e n b l a t t ! ! )
||||||
( must be c l e a r e d i n s o f t w a r e )
+−−−−−−−−−−−−−−−−−− B i t 5 (SSPEN ) : Synchronous S e r i a l Port Enable b i t
|||||
0 : D i s a b l e s s e r i a l p o r t and c o n f i g u r e s t h e s e
|||||
P i n s a s I /O p o r t p i n s
|||||
−>
1 : E n a b l e s th e s e r i a l p o r t an c o n f i g u r e s
|||||
SCK, SDO, SDI , SS / SDA, SCL p i n s a s th e
|||||
s o u r c e o f th e s e r i a l p o r t p i n s
+−−−−−−−−−−−−−−−−− B i t 4 (CKP) : Clock P o l a r i t y S e l e c t b i t
||||
In SPI mode :
||||
0 : I d l e s t a t e f o r c l o c k i s a low l e v e l
||||
1 : I d l e s t a t e f o r cl ock i s a high l e v e l
||||
In I2C S l a v e mode : SCK r e l e a s e c o n t r o l
||||
−>
0 : Holds c l o c k low ( c l o c k s t r e t c h ) . ( Used to
||||
e n s u r e data s e t u p time . )
||||
1 : Enable c l o c k
||||
In I2C Master mode : Unused i n t h i s mode
++++−−−−−−−−−−−−− B i t 3−0 (SSPM3 : SSPM0) : SSP Mode S e l e c t b i t s
0000 : SPI Master mode , c l o c k = Fosc /4
0001 : SPI Master mode , c l o c k = Fosc /16
0010 : SPI Master mode , c l o c k = Fosc /64
0011 : SPI Master mode , c l o c k = TMR2 o u tp u t /2
0100 : SPI S l a v e mode , c l o c k = SCK pin , nSS p i n
contr ol enabled
0101 : SPI S l a v e mode , c l o c k = SCK pin , nSS p i n
c o n t r o l d i s a b l e d . nSS can be used a s I /O
−> 0110 : I2C S l a v e mode , 7− b i t a d d r e s s
0111 : I2C S l a v e mode , 10− b i t a d d r e s s
1000 : I2C Master mode ,
c l o c k = Fosc / ( 4 ∗ ( SSPADD+1) )
1001 : R e s e r v e d
1010 : R e s e r v e d
1011 : I2C Firmware C o n t r o l l e d Master mode
( slave idle )
1100 : R e s e r v e d
1101 : R e s e r v e d
1110 : I2C Firmware C o n t r o l l e d Master mode ,
7− b i t a d d r e s s with START and STOP b i t
i n t e r r u p t s enabled
1111 : I2C Firmware C o n t r o l l e d Master mode ,
10− b i t a d d r e s s with START and STOP b i t
i n t e r r u p t s enabled
∗/
/∗
SSPCON2 = 0 b00110110 ;
// Sync S e r i a l Port C o n t r o l R e g i s t e r 2
+−−−−−−−−−−−−−−−−−−− B i t 7 (GCEN) : G e n e r a l C a l l Enable b i t ( In I2C S l a v e
|||||||
mode o n l y )
|||||||
−>
0 : General C a l l a d d r e s s d i s a b l e d
|||||||
1 : Enable i n t e r r u p t when a g e n e r a l c a l l
|||||||
a d d r e s s (0 0 0 0 h ) i s t r e c e i v e d i n th e SSPSR
5 DEMONSTRATIONSBEISPIELE
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
+−−−−−−−−−−−−−−−−−−
||||||
||||||
||||||
+−−−−−−−−−−−−−−−−−
|||||
|||||
|||||
|||||
|||||
|||||
+−−−−−−−−−−−−−−−−
||||
||||
||||
||||
||||
+−−−−−−−−−−−−−−−
|||
|||
|||
+−−−−−−−−−−−−−−
||
||
||
||
+−−−−−−−−−−−−−
|
|
|
|
|
+−−−−−−−−−−−−
37
B i t 6 (ACKSTAT) : Acknowledge S t a t u s b i t ( In I2C
Master mode o n l y )
0 : Acknowledge was r e c e i v e d from s l a v e
1 : Acknowledge was not r e c e i v e d from s l a v e
B i t 5 (ACKDT) : Acknowledge Data b i t ( In I2C Master
mode o n l y ) :
Value t h a t w i l l be t r a n s m i t t e d when th e u s e r
i n i z i a t e s an Acknowledge s e q u e n c e a t th e end
of a r ecei ve
0 : Acknowledge
1 : Not Acknowledge
B i t 4 (ACKEN) : Acknowledge Sequence Enable b i t
( In I2C Master mode o n l y ) :
0 : Acknowledge s e q u e n c e i d l e
1 : I n i t i a t e Acknowledge s e q u e n c e on SDA and
SCL p i n s and t r a n s m i t ACKDT data b i t .
A u t o m a t i c a l l y c l e a r e d by hardware
B i t 3 (RCEN) : R e c e i v e Enable b i t ( In I2C Master
mode o n l y )
0 : Receive i d l e
1 : E n a b l e s R e c e i v e mode f o r I2C
B i t 2 (PEN) : STOP C o n d i t i o n Enable b i t ( In I2C
Master mode o n l y )
0 : STOP c o n d i t i o n i d l e
1 : I n i t i a t e STOP c o n d i t i o n on SDA and SCL p i n s
A u t o m a t i c a l l y c l e a r e d by hardware
B i t 1 (RSEN) : Repeated START C o n d i t i o n Enable b i t
( In I2C Master mode o n l y )
0 : Repeated START c o n d i t i o n i d l e
1 : I n i t i a t e Repeated START c o n d i t i o n on SDA
and SCL p i n s
A u t o m a t i c a l l y c l e a r e d by hardware
B i t 0 (SEN) : START C o n d i t i o n Enable b i t ( In I2C
Master mode o n l y )
0 : START c o n d i t i o n i d l e
1 : I n i t i a t e START cond . on SDA and SCL p i n s
A u t o m a t i c a l l y c l e a r e d by hardware
∗/
SSPSTAT = 0 b10000000 ;
// I2C S l a v e A d r e s s e von Port B l e s e n und i n SSPADD s c h r e i b e n
// H i e r 0 A5 A4 A3 A2 A1 A0 R/nW
c I2 C A d r e s s e = 0 b00111111 ;
// Maske
c I2 C A d r e s s e = c I2 C A d r e s s e & PORTB;
c I2 C A d r e s s e = c I2 C A d r e s s e << 1 ;
c I2 C A d r e s s e . F0 = 0 ;
// S c h r e i b z u g r i f f aus S i c h t d e s Master
SSPADD = c I2 C A d r e s s e ;
// D i v e r s e R e g i s t e r i n i t i a l i s i e r e n
/∗
// I n t e r r u p t f r e i g e b e n
PIE1 = 0 b00001000 ;
+−−−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−−−
||||||
||||||
+−−−−−−−−−−−−−−−−−−−−
|||||
|||||
+−−−−−−−−−−−−−−−−−−−
||||
||||
+−−−−−−−−−−−−−−−−−−
|||
|||
|||
+−−−−−−−−−−−−−−−−−
||
// P e r i p h e r a l I n t e r r u p t Enable R e g i s t e r 1 ( Bank 1 )
Bit 7 Reserve
B i t 6 (ADIE) : A/D C o n v e r te r I n t e r r u p t Enable b i t
−>
0 : D i s a b l e s th e ADC i n t e r r u p t
1 : E n a b l e s th e ADC i n t e r r u p t
B i t 5 (RCIE) : EUSART R e c e i v e I n t e r r u p t Enable b i t
−>
0 : D i s a b l e s th e EUSART R e c e i v e I n t e r r u p t
1 : E n a b l e s th e EUSART R e c e i v e I n t e r r u p t
B i t 4 (TXIE ) : EUSART Transmit I n t e r r u p t Enable b i t
−>
0 : D i s a b l e s th e Transmit I n t e r r u p t Enable b i t
1 : E n a b l e s th e Transmit I n t e r r u p t Enable b i t
B i t 3 ( SSPIE ) : Master Synchronous S e r i a l Port (MSSP)
I n t e r r u p t Enable b i t
0 : D i s a b l e s th e MSSP i n t e r r u p t
−>
1 : E n a b l e s th e MSSP i n t e r r u p t
B i t 2 ( CCP1IF) : CCP1 I n t e r r u p t Enable b i t
−>
0 : D i s a b l e s th e CCP1 i n t e r r u p t
5 DEMONSTRATIONSBEISPIELE
444
445
||
1 : E n a b l e s th e CCP1 i n t e r r u p t
+−−−−−−−−−−−−−−−− B i t 1 (TMR2IE) : Timer 2 to PR2 Match I n t e r r u p t
Enable b i t
|
−>
0 : D i s a b l e s th e Timer 2 to PR2 Match I n t e r r u p t
|
1 : E n a b l e s th e Timer 2 to PR2 Match I n t e r r u p t
+−−−−−−−−−−−−−−− B i t 0 (TMR1IE) : Timer 1 O v e r f l o w I n t e r r u p t Enable
bit
−>
0 : D i s a b l e s Timer 1 O v e r f l o w I n t e r r u p t
1 : E n a b l e s Timer 1 O v e r f l o w I n t e r r u p t
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
38
∗/
/∗
INTCON = 0 b11000000 ;
// I n t e r r u p t −C o n tr o l −R e g i s t e r ( Bank 1 )
+−−−−−−−−−−−−−−−−−−−− B i t 7 ( GIE) : G l o b a l I n t e r r u p t Enable b i t
|||||||
0 : Disables a l l i nter r upts
|||||||
−>
1 : E n a b l e s a l l unmasked i n t e r r u p t s
+−−−−−−−−−−−−−−−−−−− B i t 6 ( PEIE ) : P e r i p h e r a l I n t e r r u p t Enable b i t
||||||
0 : Disables a l l peripheral i nter r upts
||||||
−>
1 : E n a b l e s a l l unmasked p e r i p h e r a l i n t e r r u p t s
+−−−−−−−−−−−−−−−−−− B i t 5 ( T0IE ) : Timer 0 O v e r f l o w I n t e r r u p t Enable B i t
|||||
−>
0 : Disabled
|||||
1 : Enabled
+−−−−−−−−−−−−−−−−− B i t 4 (INTE ) : RB0/INT E x t e r n a l I n t e r r u p t Enable B i t
||||
−>
0 : Disabled
||||
1 : Enabled
+−−−−−−−−−−−−−−−− B i t 3 (RPIE ) : RB Port Change I n t e r r u p t Enable B i t
|||
−>
0 : Disabled
|||
1 : Enabled
+−−−−−−−−−−−−−−− B i t 2 ( T0IF ) : Timer 0 O v e r f l o w I n t e r r u p t F l a g b i t
||
−>
0 : TMR0 r e g i s t e r d i d not o v e r f l o w
||
1 : TMR0 r e g i s t e r has o v e r f l o w e d
+−−−−−−−−−−−−−− B i t 1 (INTF) : RB0/INT E x t e r n a l I n t e r r u p t F l a g b i t
|
−>
0 : RB0/INT e x t e r n a l i n t e r r u p t d i d not o c c u r
|
1 : RB0/INT e x t e r n a l i n t e r r u p t o c c u r r e d
+−−−−−−−−−−−−− B i t 0 (RBIF ) : RB Port Change I n t e r r u p t F l a g b i t
−>
0 : None o f RB7 : RB4 p i n s have changed s t a t e
1 : One o f th e RB7 : RB4 p i n s changed s t a t e
∗/
}
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ Hauptprogramm ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Aufgaben d e s Hauptprogramms :
∗/
/∗
+ C o n t r o l l e r i n i t i a l i s i e r e n ( Unterprogramm I n i t )
∗/
/∗
+ Aufgaben i n d e r E n d l o s s c h l e i f e :
∗/
/∗
+ Daten vom emfangenen Array am Port D a u s g g e b e n ( h i e r nur das l e t z t e Daten− ∗/
/∗
b y te
∗/
/∗
+ Daten vom Port A e i n l e s e n und i n einem Demo−Array s p e i c h e r n ( d i e n t h i e r
∗/
/∗
nur z u r D e m o n s tr a ti o n ! )
∗/
/∗
+ A l l e s a n d e r e e r f o l g t i n d e r ISR ! !
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
void main ( void )
{
// C o n t r o l l e r i n i t i a l i s i e r e n
Init () ;
// E n d l o s s c h l e i f e
while ( 1 )
{
PORTD = c I 2 C W r i t e B u f f e r [ 3 ] ;
c I2 C R e a d B u f f e r [ 0 ]
c I2 C R e a d B u f f e r [ 1 ]
c I2 C R e a d B u f f e r [ 2 ]
c I2 C R e a d B u f f e r [ 3 ]
=
=
=
=
PORTA;
0 b00111100 ;
0 b01010011 ;
PORTA;
}
}
Listing 5: I2C Demo PIC Slave.c (Demo 2)
5 DEMONSTRATIONSBEISPIELE
5.7
39
Anmerkungen zur Software für 2. Demo (Slave)
Auch bei diesem zweiten Demonstrationsbeispiel wurde der Quellcode in C mit der freien Demoversion des mikroC-Compilers erstellt, und die Software für den PIC-I2 C-Slave
besteht aus den gleichen, aber angepassten, Programmteilen wie beim ersten Demonstrationsbeispiel. Nämlich aus:
• kurzes Hauptprogramm am Ende des Quellcodes, Zeilen 494 bis 510.
• 1 Unterprogramm zur Initialisierung des PIC16F887 (Unterprogramm Init, Zeilen
165 bis 479).
• kurze Interrupt-Service-Routine (kurz: ISR), Zeilen 88 bis 143.
Wichtig zu erwähnen ist, dass es bei diesem zweiten Demonstrationsbeispiel zweckmäßig
ist die empfangenen Daten und die zu sendenden Daten in je einem Array zu speichern
(hier: cI2CReadBuffer[] und cI2CWriteBuffer[]).
Hauptprogramm:
Die Aufgabe des Hauptprogramms (Zeilen 494 bis 510) ist hier zunächst das Initialisieren
des Mikrocontrollers. Dies erfolgt mit dem Unterprogramm Init (Zeile 497). Das Bereitstellen der zu übertragenden Daten und die Weiterverarbeitung der empfangenen Daten
erfolgt in der Endlosschleife. Bei diesem Demonstrationsbeispiel soll nur das vierte empfange Byte am Port D ausgegeben werden (Zeile 503), während der Zustand von Port A
zweimal zum I2 C-Master übertragen werden soll. Das zweite und dritte Datenbyte sind
hier beliebige konstante Werte (Zeilen 505 bis 508).
Alles andere erfolgt in der Interrupt-Service-Routine (ISR).
Beachte:
Die Bezeichnungen der Variablen cI2CReadBuffer[] und cI2CWriteBuffer[]) erfolgen
aus Sicht des Masters!
Unterprogramm Init:
Das Unterprogramm Init (Zeilen 165 bis 479) dient auch hier zur Initialisierung des
Mikrocontrollers. Es ist gleich wie beim ersten Demonstrationsbeispiel (siehe Abschnitt
5.3 ab Seite 20).
Interrupt-Service-Routine (kurz: ISR):
Die SSP-ISR (Zeilen 88 bis 143) wird auch hier jedesmal aufgerufen wenn ein gesamtes
Datenbyte vom SSP-Hardware-Modul empfangen wurde und dieses für den PIC-Slave mit
der Adresse im Register SSPADD bestimmt ist. Jedes mal wenn diese SSP-ISR aufgerufen
wird muss eine der folgenden vier Fälle ausgeführt werden (vgl. Flussdiagramm in Abbildung 5, Seite 8). Im Gegensatz zum ersten Demonstrationsbeispiel müssen hier auch die
Lese- und Schreibezeiger richtig behandelt werden, da hier mehr als ein Datenbyte gelesen
bzw. geschrieben (gesendet) werden).
5 DEMONSTRATIONSBEISPIELE
40
Fall 1: Schreibzugriff aus Sicht des Masters, zuletzt wurde die Slave-Adresse empfangen
(Bits: SSPSTAT.R W = 0, SSPSTAT.D A = 0):
In diesem Fall muss der Mikrocontroller (Slave) die empfangenen Daten aus dem SSPBuffer (Register SSPBUF) lesen kann den Inhalt von SSPBUF aber verwerfen, da es nur
die Adresse und keine Daten enthält (Zeile 98). Hier wird der Inhalt von SSPBUF in ein
Dummy-Register geschrieben. Wichtig ist das dass Register SSPBUF gelesen wird, weil dadurch Steuerbits für das Hardwaremodul verändert werden. Neu ist bei diesem Demonstrationsbeispiel das Initialisieren des Schreib-Zeiger cI2CWriteBufferIndex (aus Sicht
des Masters, Zeile 101). Wichtig sind auch hier die folgenden Codezeilen 99 und 100. Das
SSP-Interrupt-Flag SSPIF muss ebenfalls gelöscht werden, da sonst dieser Interrupt sofort
wieder ausgelöst wird (Zeile 102)!
Fall 2: Schreibzugriff aus Sicht des Masters, zuletzt wurde ein Datenbyte empfangen (Bits:
SSPSTAT.R W = 0, SSPSTAT.D A = 1):
Jetzt handelt es sich tatsächlich um Nutzdaten. Diese befinden sich im SSP-BufferRegister SSPBUF. Daher den Inhalt dieses Registers in das eigene Array cI2CWriteBuffer[]
an der Stelle auf den der Index-Zeiger cI2CWriteBufferIndex zeigt schreiben (Zeile
109). Diesen Index-Zeiger anschließend um eins erhöhen (Zeile 111), damit beim nächsten Aufruf dieser ISR der nächste empfangene Wert an die nächste Stelle im Array
cI2CWriteBuffer[] geschrieben wird.
Auch hier sind die folgenden Codezeilen 112 bis 114 wichtig und dürfen nicht weggelassen
werden!
Fall 3: Lesezugriff aus Sicht des Masters, zuletzt wurde die Slave-Adresse empfangen (Bits:
SSPSTAT.R W = 1, SSPSTAT.D A = 0):
In diesem Fall muss das erste zu sendende Datenbyte in das Register SSPBUF geschrieben
werden. Daher das erste Datenbyte (mit dem Index 0) vom eigene Array cI2CReadBuffer[]
lesen und in das Register SSPBUF schreiben (Zeile 125). Als nächstes den Lese-Zeiger (aus
Sicht des Masters) cI2CReadBufferIndex initialisieren (Zeile 126).
Auch hier sind die folgenden Codezeilen 127 bis 129 wichtig und dürfen nicht weggelassen
werden!
Fall 4: Lesezugriff aus Sicht des Masters, zuletzt wurde ein Datenbyte gesendet (Bits:
SSPSTAT.R W = 1, SSPSTAT.D A = 1):
Im Gegensatz zum ersten Demonstrationsbeispiel tritt hier auch dieser Fall auf. Hier muss
zunächst der Lese-Index-Zeiger cI2CReadBufferIndex um eins erhöht werden (Zeile 135).
Anschließend den Inhalt des Lesearray, auf den der Lesezeiger zeigt lesen und in das
Register SSPBUF schreiben (Zeile 136).
Auch hier sind die folgenden Codezeilen 138 bis 140 wichtig und dürfen nicht weggelassen
werden!
Mehr als das Lesen des SSPBUF-Registers oder das Schreiben in das SSPBUF-Register ist
auch bei diesem zweiten Demonstrationsbeispiel in der Interrupt-Service-Routine (ISR)
nicht zu tun. Alles andere übernimmt auch hier das Hardware-Modul SSP des Mikrocontrollers.
5 DEMONSTRATIONSBEISPIELE
41
Sonstiges:
Am Beginn des Quellcodes befinden sich die folgenden Definitionen und Einstellungen:
• Definition der globalen Register (hier cDummy, Zeile 37, sowie die Arrays zum speichern der gesendeten und empfangenen Daten (Zeilen 41 und 42) und die IndexZeiger (Zeilen 43 und 44)
• Funktionsprototyp für das hier verwendete Unterprogramm (Init, Zeile 68)
• Ab Zeile 88 beginnt der Quellcode der ausreichend mit Kommentaren versehen ist
Die Konfigurationsbits für den PIC16F887-Mikrocontroller sind hier gleich wie beim ersten
Demonstrationsbeispiel.
5.8
Software für 2. Demo (Master)
Natürlich müssen auch beim Master Änderungen vorgenommen werden.
Auch bei diesem zweiten Demonstrationsbeispiel ist der Quellcode für den I2 C-Bus-Master
(mit dem PIC16F887, IC2) zur besseren Übersicht in mehrere Dateien aufgeteilt:
• I2C Demo PIC Master.c beinhaltet das Hauptprogramm und das Unterprogramm
zur Initialisierung des Mikrocontrollers (PIC16F887).
• PCF8574.C beinhaltet die Unterprogramme zur Datenübertragung mit dem PCF8574.
• PCF8574.H ist die Headerdatei zu PCF8574.C
Die Dateien PCF8574.C und PCF8574.H unterscheiden sich nicht zum ersten Demonstrationsbeispiel und werden hier daher auch nicht mehr behandelt.
Hier die Datei I2C Demo PIC Master.c (für das zweite Demonstrationsbeispiel):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Demo z u r Ansteuerung d e s PIC16Fxx a l s I2C−S l a v e gemaess A p p l i c a t i o n Note AN734
∗/
/∗
∗/
/∗ Master
∗/
/∗
∗/
/∗ Demo 2 : e i n Byte vom Port B l e s e n und i n einem Array s p e i c h e r n . D i e s e Array mit
∗/
/∗
w e i t e r e n b e l i e b i g e n Werten a u f f u e l l e n , und da gesamte Array v i a I2C an den ∗/
/∗
S l a v e s e n d e n . Ebenso e i n Array v i a I2C empfangen und das z u l e t z t empfangene ∗/
/∗
Byte am Port D a u s g e b e n .
∗/
/∗
∗/
/∗ M i k r o c o n t r o l l e r :
PIC16F887
∗/
/∗ Takt :
i n t e r n e r Takt ( 4 . 0 MHz)
∗/
/∗
∗/
/∗ Compiler :
mikroC V8 . 2
∗/
/∗
∗/
/∗ E n t w i c k l e r :
S t e f a n Buchgeher
∗/
/∗ E n t w i c k l u n g s b e g i n n d e r S o f t w a r e : 2 . Maerz 2014
∗/
/∗ F u n k t i o n s f a e h i g s e i t :
2 . Maerz 2014
∗/
/∗ L e t z t e B e a r b e i t u n g :
4 . J u l i 2014
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ I n c l u d e −D a te i e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
5 DEMONSTRATIONSBEISPIELE
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
42
#include ”PCF8574.H”
#include ”PCF8574A.H”
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ S t r u k t u r e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e S t r u k t u r e n v e r w e n d e t ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ E x te r n e R e g i s t e r ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e e x t e r n e n R e g i s t e r ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ B i t s i n den e x t e r n e n R e g i s t e r n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e e x t e r n e n R e g i s t e r ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ G l o b a l e R e g i s t e r ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e g l o b a l e n R e g i s t e r ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ B i t s i n den g l o b a l e n R e g i s t e r n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e g l o b a l e n R e g i s t e r ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ P o r t b e l e g u n g ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ \INT−Ausgang d e s PCF8574 ∗/
#define nINTPCF8574
PORTC. F5
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ Konstanten ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Konstanten f u e r I2C ∗/
#define noACK
0
#define ACK
1
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ T a b e l l e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ k e i n e T a b e l l e n ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ F u n k t i o n s p r o t o t y p e n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Unterprogramm z u r I n i t i a l i s i e r u n g d e s M i k r o c c n t r o l l e r s ∗/
void I n i t ( void ) ;
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ Unterprogramme und Funktionen ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ I n i t :
∗/
/∗
∗/
/∗ Aufgabe :
∗/
/∗
I n i t i a l i s i e r u n g des P r o z e s s o r :
∗/
/∗
+ internen Os z i l l a to r konfigurieren
∗/
/∗
+ Ports konf i gur i er en
∗/
/∗
∗/
/∗ U e b e r g a b e p a r a m e te r :
∗/
/∗
keiner
∗/
/∗
∗/
/∗ Rueckgabeparameter :
∗/
/∗
keiner
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
void I n i t ( void )
{
// ( i n t e r n e n ) O s z i l l a t o r k o n f i g u r i e r e n
OSCCON = 0 b01100001 ;
// Sync O s c i l l a t o r C o n t r o l R e g i s t e r
/∗
+−−−−−−−−−−−−−−−−−−−− B i t 7 R e s e r v e
+++−−−−−−−−−−−−−−−−− B i t 6−4 ( IRCF2 : IRCF0 ) : I n t e r n a l O s c i l l a t o r Frequency
||||
Select bits
||||
000 : 31 kHz (LFINTOSC)
||||
001 : 125 kHz
||||
010 : 250 kHz
||||
011 : 500 kHz
43
5 DEMONSTRATIONSBEISPIELE
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
||||
||||
||||
||||
+−−−−−−−−−−−−−−−−
|||
|||
|||
|||
|||
+−−−−−−−−−−−−−−−
||
||
||
||
+−−−−−−−−−−−−−−
|
|
|
|
+−−−−−−−−−−−−−
100 : 1 MHz
101 : 2 MHz
−> 110 : 4 MHz ( d e f a u l t )
111 : 8 MHz
B i t 3 (OSTS) : O s c i l l a t o r S t a r t −up Time−out S t a t u s
( Read Only )
0 : D e v i c e i s r u n n i n g from th e c l o c k d e f i n e d
by FOSC2 : FOSC0 o f th e CONFIG1 r e g i s t e r
1 : D e v i c e i s r u n n i n g from th e i n t e r n a l
oscillator
(HFINTOSC o r LFINTOSC)
B i t 2 (HTS) : HFINTOSC S t a t u s b i r
( High Frequency − 125 kHz to 8MHz)
( Read Only )
0 : HFINTOSC i s not s t a b l e
1 : HFINTOSC i s s t a b l e
B i t 1 (LTS) : LFINTOSC S t a t u s b i t
(Low Frequency − 31kHz )
( Read Only )
0 : LFINTOSC i s not s t a b l e
1 : LFINTOSC i s s t a b l e
B i t 0 (SCS ) : System Clock S e l e c t b i t
0 : Clock s o u r c e d e f i n e d by FOSC2 : FOSC0
o f th e CONFIG1 r e g i s t e r
−>
1 : I n t e r n a l o s c i l l a t o r i s used f o r system
clock
∗/
/∗
// P o r t s k o n f i g u r i e r e n
TRISC = 0 b00100000 ;
+−−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−−
+−−−−−−−−−−−−−−
// R i c h t u n g s r e g i s t e r
B i t 7 Port RC7 : h i e r
B i t 6 Port RC6 : h i e r
B i t 5 Port RC5 : h i e r
B i t 4 Port RC4 : h i e r
B i t 3 Port RC3 : h i e r
B i t 2 Port RC2 : h i e r
B i t 1 Port RC1 : h i e r
B i t 0 Port RC0 : h i e r
Port C ( 0 : Ausgang , 1 : Eingang )
u n b e n u tz t
u n b e n u tz t
Eingang (/ INT )
Ausgang (SDA)
Ausgang (SCL)
u n b e n u tz t
u n b e n u tz t
u n b e n u tz t
∗/
}
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ Hauptprogramm ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
/∗ Aufgaben d e s Hauptprogramms :
∗/
/∗
+ C o n t r o l l e r i n i t i a l i s i e r e n ( Unterprogramm I n i t )
∗/
/∗
+ Takt f u e r I2C−Bus f e s t l e g e n ( h i e r 100 kHz mit dem Unterprogramm I 2 C I n i t )
∗/
/∗
+ 8−Bit−Wert vom Eingabemodul ( mit dem PCF8574 ) l e s e n und insgesammt v i e r Byte an ∗/
/∗
den I2C−PIC−S l a v e s e n d e n
∗/
/∗
+ Daten (4 Byte ) vom I2C−PIC−S l a v e l e s e n und das v i e r t e Byte am I2C−LED−Modul
∗/
/∗
( mit einem w e i t e r e n PCF8574 ) a u s g e b e n
∗/
/∗
+ T a e t i g k e i t e n / Unterprogramme , d i e a l l e z y k l i s c h d u r c h g e f u e h r t werden muessen :
∗/
/∗
+ b e i jedem I n t e r r u p t d e s PCF8574 (A) d i e Daten vom Eingabemodul ( mit dem
∗/
/∗
PCF8574 ) l e s e n und ( w i e d e r ) v i e r Byte am I2C−PIC−S l a v e a u s g e b e n . A n s c h l i e s − ∗/
/∗
send Daten (4 Byte ) vom I2C−PIC−S l a v e l e s e n und das v i e r t e Byte am I2C−LED− ∗/
/∗
Modul a u s g e b e n .
∗/
/∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/
void main ( void )
{
char cTemp ;
char cTemp1 ;
char cTemp2 ;
char cTemp3 ;
char cTemp4 ;
// C o n t r o l l e r
Init () ;
initialisieren
// I2C i n i t i a l i s i e r e n
I2C Ini t (100000) ;
// I2C−T a k t f r e q u e n z : 100 kHz
44
5 DEMONSTRATIONSBEISPIELE
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
// Demo 1 : 8−Bit−Wert vom I2C−Eingabemodul l e s e n . . .
cTemp = I2C PCF8574 ReadData ( 1 ) ;
// M o d u l a d r e s s e : h i e r 1
// . . . und am I2C−PIC−S l a v e a u s g e b e n
I2C Start () ;
// S t a r t b e d i n g u n g
I2C Wr (0 b00110000 ) ;
// B a u s t e i n a d r e s s e + S c h r e i b z u g r i f f
I2C Wr ( cTemp ) ;
// 4 Datenbyte
I2C Wr (0 b00001111 ) ;
//
an den
I2C Wr (0 b11001100 ) ;
//
PIC−S l a v e
I2C Wr ( cTemp ) ;
//
schreiben
I2 C S to p ( ) ;
// S to p b e d i n g u n g
// Demo 2 : Daten vom I2C−PIC−S l a v e l e s e n
I2C Start () ;
I2C Wr (0 b00110001 ) ;
cTemp1 = I2C Rd (ACK) ;
cTemp2 = I2C Rd (ACK) ;
cTemp3 = I2C Rd (ACK) ;
cTemp4 = I2C Rd (noACK) ;
I2 C S to p ( ) ;
// . . . und am I2C−LED−Modul a u s g e b e n
cTemp4 = ˜cTemp4 ;
I2C PCF8574 WriteData ( 3 , cTemp4 ) ;
...
//
//
//
//
//
//
//
Startbedingung
Bausteinadresse + L es e zu gr i f f
Daten
vom
PIC−S l a v e
lesen
S to p b e d i n g u n g
// M o d u l a d r e s s e : h i e r 3
// E n d l o s s c h l e i f e
while ( 1 )
{
// b e i jedem I n t e r r u p t d e s PCF8574 (A)
i f ( nINTPCF8574 == 0 )
{
// Demo 1 : 8−Bit−Wert vom I2C−Eingabemodul l e s e n . . .
cTemp = I2C PCF8574 ReadData ( 1 ) ;
// M o d u l a d r e s s e : h i e r 1
// . . . und am I2C−PIC−S l a v e a u s g e b e n
I2C Start () ;
// S t a r t b e d i n g u n g
I2C Wr (0 b00110000 ) ;
// B a u s t e i n a d r e s s e + S c h r e i b z u g r i f f
I2C Wr ( cTemp ) ;
// 4 Datenbyte
I2C Wr (0 b00001111 ) ;
//
an den
I2C Wr (0 b11001100 ) ;
//
PIC−S l a v e
I2C Wr ( cTemp ) ;
//
schreiben
I2 C S to p ( ) ;
// S to p b e d i n g u n g
// Demo 2 : Daten vom I2C−PIC−S l a v e l e s e n . . .
I2C Start () ;
// S t a r t b e d i n g u n g
I2C Wr (0 b00110001 ) ;
// B a u s t e i n a d r e s s e + L e s e z u g r i f f
cTemp1 = I2C Rd (ACK) ;
// Daten
cTemp2 = I2C Rd (ACK) ;
//
vom
cTemp3 = I2C Rd (ACK) ;
//
PIC−S l a v e
cTemp4 = I2C Rd (noACK) ;
//
lesen
I2 C S to p ( ) ;
// S to p b e d i n g u n g
// . . . und am I2C−LED−Modul a u s g e b e n
cTemp4 = ˜cTemp4 ;
I2C PCF8574 WriteData ( 3 , cTemp4 ) ;
// M o d u l a d r e s s e : h i e r 3
}
}
}
Listing 6: I2C Demo PIC Master.c (Demo 2)
5 DEMONSTRATIONSBEISPIELE
5.9
45
Anmerkungen zur Software für 2. Demo (Master)
Auch dieser Quellcode wurde in C mit der freien Demoversion des mikroC-Compilers
erstellt.
Die Software (für den PIC-I2 C-Master) besteht auch hier im Wesentlichen aus den folgenden Programmteilen:
• Hauptprogramm am Ende des Quellcodes von I2C Demo PIC Master.c, Zeilen 150
bis 222.
• 1 Unterprogramm zur Initialisierung des PIC16F887 (Unterprogramm Init in der
Datei I2C Demo PIC Master.c, Zeilen 83 bis 131).
• 2 Unterprogramme zur Kommunikation mit dem PCF8574 (I2C PCF8574 WriteData
und I2C PCF8574 ReadData in der Datei PCF8574.C, siehe erstes Demonstrationsbeispiel.
Hier nur kurz die Änderungen im Hauptprogramm. Das Unterprogramm Init bleibt hier
unverändert:
Das Hauptprogramm ist - verglichen mit dem ersten Demonstrationsbeispiel, Master etwas länger. Grund dafür ist nur dass jetzt jeweils vier Datenbytes (anstelle von einer,
beim ersten Demonstrationsbeispiel) gesendet bzw. gelesen werden müssen. Dies ist, glaube ich, im Quellcode sehr gut erkennbar. Dies ist auch der einzige Unterschied. Anstelle
der temporären Register cTemp1 bis cTemp4 könnte auch ein Array verwendet werden,
doch dies ist hier nicht unbedingt notwendig.
Zum Abschluss noch ein Wort zu den Konfigurationsbits. Auch diese sind hier gleich wie
beim ersten Demonstrationsbeispiel.