Alle DIL-Bausteine sollten sie auf Sockel stecken. Dies erleichtert den Austausch, falls einmal ein Baustein defekt sein sollte. Verwenden sie zum Löten handelsübliches Lötzinn und eine Lötkolbentemperatur von 390° C.
Löten sie zuerst den Spannungsversorgungsteil auf das LPC-Experimentierboard. Beginnen sie dabei mit den liegenden Bauteilen (Diode, Widerstände). Danach löten sie die nächst größeren Bauteile (Kondensatoren, LED, Buchsen) ein. Zum Schluss wird der Spannungsregler eingelötet.
F !! Achten sie beim Bestücken auf die Polarität des C2 und auf die Richtung der Dioden und des Spannungsreglers. Die Metallseite des 7805 muss zum Leiterplattenrand zeigen. !!
|
|
Abbildung 2 Spannungsversorgung LPC-Experimentierboard (Stromlaufplan)
|
|
Abbildung 3 Spannungsversorgung LPC-Experimentierboard (Bestückung)
Tabelle 2 enthält die Bestückungsliste für die Stromversorgung. Nachdem sie die Bauteile eingelötet haben, stecken sie ein 9 V-Steckernetzteil ein. Die Leuchtdiode sollte nun leuchten. Zwischen den Pins XVCC1 und GND sollte eine Spannung von 5 V liegen. Über der Diode sollte ein Spannungsabfall von circa 0,7 V zu messen sein.
|
Position |
Wert |
Anzahl |
Hinweise |
|
R1 |
270 Ohm |
1 |
liegend einbauen |
|
V1 |
1N5401 |
1 |
liegend einbauen !! Polarität beachten !! |
|
V2 |
TLLR 4400 |
1 |
Leuchtdiode !! Polarität beachten !! |
|
C1 |
100n |
1 |
|
|
C2 |
100µF/16V |
1 |
!! Polarität beachten !! |
|
N1 |
7805 |
1 |
Spannungsregler !! Polarität beachten !! |
|
GND |
2mm Buchse |
1 |
Optional kann eine Pfostenbuchse eingelötet werden. |
|
XVCC1 |
2mm Buchse |
1 |
Tabelle 2 Bestückungsliste für die Stromversorgung des LPC-Experimentierboard
Bestücken sie zudem die Anschlussseite für das MCB900 bzw. EPM900. Der Sockel X1 ist für die EPM900-, der Sockel X9 für die MCB900-Verbindung. Mit Hilfe des Jumpers J28 (siehe Abbildung 4) wird die 3.3 V-Spannungsversorgung eingestellt.
|
|
Abbildung 4 Bestückungsplan für das EPM900-/MCB900-Board
|
|
Abbildung 5 Stromlaufplan für das EPM900-/MCB900-Board
|
Position |
Wert |
Anzahl |
Hinweise |
|
X1, X9 |
28 poliger Sockel |
2 |
|
|
J28 |
Stiftleiste |
1 |
|
|
XP0.x, XP3.x X-VDD, X-GND |
2mm Buchsen |
28 |
Es kann optional eine Pfostenbuchse eingelötet werden. |
Tabelle 3 Bestückungsliste für den Anschluss an das EPM900-/MCB900-Board
M !! Überprüfen sie immer zuerst den korrekten Anschluss zwischen dem LPC-Experimentierboard und dem verwendeten Board (EPM900 bzw. MCB900), bevor sie die Spannung an die Boards anlegen. Ansonsten können beide Boards beschädigt werden. !!
F !! Wird das MCB900-Board verwendet, werden zwei 9 V-Steckernetzteile benötigt. Die 3.3 V werden vom EPM900-/MCB900-Board geliefert. !!
Löten sie nun zuerst alle Widerstände, dann die Schalter und Buchsen und zum Schluss die Taster ein. Die Bestückung können sie Abbildung 6 entnehmen. Mit den Widerständen wird sichergestellt, dass nur ein Strom von 0,5 mA in den LPC900 bei „High“ hineinfließt bzw. nur ein Strom von 11 mA aus dem LPC900 herausfließt.
|
|
|
Abbildung 6 Schalt-/Bestückungsplan für Schalter und Taster
|
Position |
Wert |
Anzahl |
Hinweise |
|
S1-S8 |
Schalter |
8 |
|
|
S9-S16 |
Taster |
8 |
|
|
R2, R4, R6, R8, R10, R12, R14, R16, R36-R43 |
430 Ohm |
16 |
liegend einbauen |
|
R3, R5, R7, R9, R11, R13, R15, R17-R25 |
10k Ohm |
16 |
liegend einbauen |
|
XTa0- XTa7 XS0-XS7 |
2mm Buchsen |
16 |
Es kann optional eine Pfostenbuchse eingelötet werden. |
Tabelle 4 Bestückungsliste für Taster und Schalter
Erstellen sie für den Funktionstest der Taster und Schalter ein Projekt, das die Zustände der Schalter/Taster an Port 0 einliest und an Port 2 ausgibt. Wird der Schalter gedrückt, sollte die passende LED auf dem EPM900-/MCB900-Board aufleuchten.
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
TestExp_Taster |
Test_Taster |
TestExpTasterSchalter.c |
Tabelle 5 Projekt TestExp_Taster
|
|
#include <REG932.H>
void main(void) { P2M1= 0; // Port 2 auf Quasi-Bidirektional setzen P2M2= 0; while (1) // Stetiges Auslesen von Port 0. Der Inhalt P2 = ~P0; // wird invertiert auf P2 ausgegeben } |
Listing 1 Inhalt von TestExpTasterSchalter.c
F !! Wenn sie ein EPM900 verwenden, dann müssen sie den Port 2 über die Checkbox „Enable P2 LED driver“ im Dialog „Configure EPM900 Emulator“ aktivieren, ansonsten werden die LED nicht aktiv. Wenn sie den Debugmode gestartet haben, können sie den entsprechenden Dialog unter dem Menüpunkt Peripherals/Monitor Settings öffnen. !!
|
|
Abbildung 7 Dialog Configure EPM900 Emulator
Verbinden sie die Tasten-Anschlüsse XTa0 – XTa7 mit dem Port-Anschlüssen (XP00-XP07) mit Hilfe der 2 mm-Kabel bzw. mit den flexiblen Steckbrücken. Die flexiblen Steckbrücken sollten 200 mm lang sein. Sie können diese z. B. bei Conrad beziehen (siehe Tabelle 80, Seite 130).
Arbeitsweise MCB900:
Übersetzen sie das Projekt und laden sie es mit dem Button „Load“ auf das LPC900-Board. Falls sie noch nie eine Datei auf das MCB900 kopiert haben, sollten sie zuvor die Beschreibung des MCB900 durcharbeiten. Nachdem der Jumper auf die Position „Run“ gesteckt ist, können sie die einzelnen Taster betätigen. Es sollte die jeweilige LED dazu aufleuchten.
|
Fehlermöglichkeiten: |
Abhilfe: |
|
Das Programm lässt sich nicht auf das MCB900 übertragen. |
Der Jumper steckt nicht auf der Position „Reset“. Die serielle Schnittstelle ist falsch ausgewählt. |
Arbeitsweise EPM900:
Übersetzen sie das Projekt und betätigen sie den Debug-Button. Das Programm wird jetzt automatisch in das Board übertragen. Starten sie das Programm mit dem Button „Run“. Wenn jetzt die Taste gedrückt wird, sollte die entsprechende LED leuchten.
|
Fehlermöglichkeiten: |
Abhilfe: |
|
Es wird die Fehlermeldung „Connection to target system lost” im Dialog ausgegeben. |
Im Dialog „Options for Target“, Reiter „Debug“ ist der Eintrag „EPM900 LPC Emulator“ auszuwählen. |
Wiederholen sie den Test mit den Schaltern. Ist der Test erfolgreich durchlaufen, können sie zum nächsten Abschnitt gehen.
Um frei konfigurierbare LEDs auf dem LPC-Experimentierboard ansteuern zu können, ist eine Balken-LED mit aufgenommen worden. Als Treiber dient der 8-Bit Inverter 74HC540 (siehe Abbildung 8). Die Balken-LED wird über ein Widerstands-Netzwerk (8x330 Ohm) auf VCC gelegt. Damit der 74HC540 bei einem Defekt einfach ausgetauscht werden kann, wird dieser auf einen 20-poligen DIP-Sockel gesteckt.
Löten sie zuerst den Block-Kondensator (C14), dann die Sockel und das Widerstands-Netzwerk und zum Schluss die Buchsen ein.
|
|
Abbildung 8 Schalt-/Bestückungsplan für Balken-LED
F !! Die Widerstandsnetzwerke werden ohne Sockel bestückt. !!
|
|
|
Abbildung 9 Schalt-/Bestückungsplan für Balken-LED
|
Position |
Wert/Bez. |
Anzahl |
Beschreibung |
|
D4 |
20pol. Sockel |
1 |
!! Einbaurichtung beachten. !! |
|
D4 |
74HC540 |
1 |
!! Einbaurichtung beachten. !! |
|
C14 |
100n |
1 |
|
|
R46 |
8x330 Ohm |
1 |
!! Einbaurichtung
(Punkt) beachten. !! |
|
RW5 |
8x10 kOhm |
1 |
!! Einbaurichtung
(Punkt) beachten. !! |
|
V5 |
Balken-LED |
1 |
!! Einbaurichtung beachten. !! |
|
XLEDB0- XLEDB7 |
2mm Buchsen |
8 |
Es kann zudem eine Pfostenbuchse eingelötet werden. |
Tabelle 6 Bestückungsliste für Balken-LED
Um die Funktionsweise der Balken-LED zu testen, verbinden sie mit Hilfe einer flexiblen Steckbrücke die Buchse XLEDB0 mit dem Anschluss der XTa7 (Taste S16). Wird die Taste gedrückt, muss die erste LED leuchten. Wiederholen sie diesen Test mit den anderen LEDs.
Erstellen sie nun ein Programm, dass den Wert der Variablen „ucValue“ in binärer Darstellung an Port 2 ausgibt. Mit Hilfe der Taste „XTa0“ soll die Variable inkrementiert, mit „XTa1“ dekrementiert werden. Das Projekt soll anhand der Tabelle 7 aufgebaut sein. Um die Ausgabe von Port 2 auf die Balken-LED zu bekommen, müssen noch Verbindungen zwischen XP2.0 – 7 und XLEDB0 – 7, XTa0 mit XP0.0 und XTa1 mit XP0.1 gesteckt werden.
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
TestBalkenLED |
Test_BalkenLED |
TestBalkenLED.c |
Tabelle 7 Projekt TestBalkenLED
|
|
#include <REG932.H>
sbit TasteInc = P0^0; sbit TasteDec = P0^1; void main(void) { unsigned char ucValue = 0;
P2M1 = 0x00; // Port 2 als quasi-bidirektional P2M2 = 0x00; P2 = ucValue;
do { // Abfrage, ob eine Taste gedrueckt wurde while ((TasteInc == 1) & (TasteDec == 1)); if (TasteInc == 0) { ucValue++; while (TasteInc == 0); // Warten bis Taste losgelassen } if (TasteDec == 0) { ucValue--; while (TasteDec == 0); // Warten bis Taste losgelassen } P2 = ucValue; } while(1); } |
Listing 2 Inhalt von TestBalkenLED.c
Wenn sie nun die Tasten betätigen fällt ihnen sicherlich auf, dass es ab und zu vorkommt, dass die LED um zwei anstatt um eins weitergezählt wird. Dieses Verhalten wird durch den Prellvorgang der Tasten erzeugt.
Auf dem Experimentierboard ist ein RS232-Pegelwandler mit einer 9-poligen DSUB Buchse vorhanden. Mit Hilfe der Jumper J3 und J4 kann der Pegelwandler an die serielle Schnittstelle des LPC932/935 angebunden werden (siehe Abbildung 10). Sie benötigen ihn z. B. zum Testen mit dem EPM900-Board. Folgende Signalleitungen sind miteinander an der 9-pol. Buchse verbunden:
RTS (X8.7) <-> CTS (X8.8)
DCD (X8.1) <-> DTR (X8.4) <-> DSR (X4.6)
Falls sie die Flusssteuerung mit Software realisieren wollen, können die Verbindungen auf der Lötseite z. B. mit einem scharfen Messer aufgetrennt werden.
|
|
Abbildung 10 Schaltplan für die RS232-Schnittstelle
Löten sie zuerst den Sockel und danach die Kondensatoren ein. Alle Kondensatoren zeigen mit der Polarität in die gleiche Richtung.
Stecken sie auf J3 und J4 einen Jumper.
|
|
|
Abbildung 11 Bestückungsplan für die RS232-Schnittstelle
|
Position |
Wert/Bez. |
Anzahl |
Beschreibung |
|
D1 |
16-pol. Sockel |
1 |
!! Einbaurichtung beachten. !! |
|
D1 |
MAX232 |
|
!! Einbaurichtung beachten. !! |
|
C3-C7 |
1 µF/35 V |
5 |
!! Polarität beachten !! |
|
X8 |
9pol. DSUB |
|
|
Tabelle 8 Bestückungsliste für die RS232-Schnittstelle
Legen sie die Versorgungsspannung an das Board und messen sie die Spannung an den einzelnen Pins des MAX232. Folgende Werte sollten an ihrem Baustein anliegen:
|
Pin |
Beschreibung: | |
|
1 (C1+) |
+10 V ~174 kHz |
|
|
2 (V+) |
+9 V |
|
|
3 (C1-) |
+5 V ~174 kHz |
|
|
4 (C2+) |
+10,5 V ~174 kHz |
|
|
5 (C2-) |
-10 V ~174 kHz |
|
|
6 (V-) |
-10 V |
|
|
7 (T2Out) |
-10 V |
|
|
8 (R2in) |
0 V |
|
|
9 (R2out) |
+5 V |
|
|
10 (T2in) |
+5 V |
|
|
11 (T1in) |
+5 V |
|
|
12 (R1Out) |
+5 V |
|
|
13 (R1in) |
0 V |
|
|
14 (T1out) |
-10 V |
|
|
15 (GND) |
0 V |
Spannungsversorgung |
|
16 (VCC) |
+5 V |
Spannungsversorgung |
Tabelle 9 Signalbelegung am MAX232
Entsprechen die Messungen den in Tabelle 9 aufgeführten Werten, können sie die Pegelumsetzung testen. Verbinden sie XS0 (Schalter 1) mit XP1.0. Liegt an P1.0 ein „Lowpegel“ (Schalterstellung rechts) an, liegt an Pin 3 (X8) ein Signal von +9 V an (siehe Abbildung 12).
|
|
Abbildung 12 Test des RS232-Pegelwandlers (P1.0 = 0)
Liegt an P1.0 ein „Highpegel“ (Schalterstellung links) an, liegt an Pin 3 (X8) ein Signal von –9 V an (siehe Abbildung 13).
|
|
Abbildung 13 Test des RS232-Pegelwandlers (P1.0 = 1)
Ist dieser Test erfolgreich verlaufen, können sie einen Kommunikationstest mit dem EPM900/ MCB900 durchführen. Das Programm sendet den Text „Hello World“ mit 9600 Baud, 8 Bit aus. Erstellen sie dafür folgendes Projekt und geben sie das Programm aus.
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
TestRS232 |
Test_RS232 |
TestRS232.c |
Tabelle 10 Projekt TestRS232
|
|
#include <REG932.H>
// Testausgabe ueber die ser. Schnittstelle char code acArray[] = {"Hello World "}; unsigned char ucOffset; sbit sbTaste = P2^0;
bit btRS232Finished; void main(void) { P1M1 = 0x00; // Config Port 1 als Quasi-bidirectional P1M2 = 0x00; P1 = 0xFF; // alle Portpins auf 1 setzen
SCON = 0x40; // 8-bit UART (var. baudrate)
// Baudrate fuer Baudratengenerator setzen BRGR0 = 0xF0; // 9600 Baud BRGR1 = 0x02;
// Baudratengenerator freigeben und starten BRGCON = 0x03;
// Interrupt Konfiguration ES = 1; // Freigabe der ser. Schnittstelle EA = 1; // allg. Interruptfreigabe
// Erstes Byte aus dem Array auslesen und senden // alle weiteren Bytes werden aus der ISR gesendet while(1) { // Auf Tastendruck von P2.0 warten while (sbTaste == 1); btRS232Finished =0; ucOffset = 0; // Offset auf erstes Zeichen im Array setzen // Sendevorgang starten SBUF = acArray[ucOffset++]; // Auf Beendigung des Sendevorgangs warten while (btRS232Finished == 0); } }
// ISR der seriellen Schnittstelle void v_IntSer(void) interrupt 4 using 1 { TI = 0; // TI-Flag loeschen if (acArray[ucOffset] != 0) // Ueberpruefung, ob das letzte { // Byte erreicht ist SBUF = acArray[ucOffset]; // naechstes Byte senden ucOffset++; // Offset im Array erhoehen } else { while (sbTaste == 0); // Warten bis Taste losgelassen wurde btRS232Finished = 1; } } |
Listing 3 Inhalt von TestRS232.c
F !! Eine ausführliche Beschreibung zum UART der LPC900-Familie finden sie in Kapitel 10.11 UART [3]. !!
Um den Empfang am PC prüfen zu können, können sie z. B. das COM Terminal von http://home.wtal.de/Mischka/VB/COM/ verwenden. Dieses Programm zeichnet sich z. B. dadurch aus, dass es den aktuellen Status der Steuersignale anzeigt und die empfangenen Bytes in mehreren Arten dargestellt werden.
Starten sie zuerst das COM Terminal, wählen die COM-Schnittstelle und stellen die Parameter auf 9600,N,8,1 ein. Wechseln sie beim EPM900 in den Emulator-Mode bzw. laden sie das Programm mit Hilfe des Download-Buttons in den Baustein.
F !! Bei Verwendung des MCB900 muss bei der Compilierung die Checkbox Create HEX File im Menüpunkt „Project\Options for Target\Reiter Output“ aktiviert werden. !!
|
|
Nach dem Start des Programms sollte das COM Terminal den Text „Hello World“ empfangen (siehe Abbildung 14). Zur Messung der Zeiten zwischen den gesendeten Bytes können sie das Programm Portmon verwenden. (www.Sysinternals.com) |
Abbildung 14 COM Terminal (Empfang von „Hello World“)
Um den Reset-Eingang zu aktivieren, muss das Bit RPE im UCFG1 auf „1“ gesetzt werden. Dies wird am einfachsten dadurch erreicht, indem die START900.a51 zum Projekt hinzugefügt wird. In µVision3 können die Einstellungen der START900.a51 mit Hilfe eines Configuration-Wizards vorgenommen werden (siehe Abbildung 15). Wählen sie das RPE aus und setzen sie es auf „Enable (P1.5 used as reset pin)“.
|
|
|
Abbildung 15 Configuration Wizard von START00.a51
F !! Eine ausführliche Beschreibung zu Aufbau und Funktionsweise des „Configuration Wizard“ finden sie im Buch Teil 2 [2]. !!
Wird der EPM900-Emulator für den Test verwendet, muss die Option “Use UCG1 from START900.a51” aktiviert werden (siehe Abbildung 16).
|
|
Abbildung 16 Window Configure EPM900 Emulator
Das Programm soll nun in Abhängigkeit von der Betätigung des Tasters bzw. durch Aktivieren des Resets unterschiedliche Texte über die serielle Schnittstelle ausgeben. Die Auswertung, ob ein externer Reset erfolgt ist, wird über das SFR RSTSRC, Bit 0 festgestellt (siehe Listing 4, ). Ist das Bit 0 nicht gesetzt, wartet das Programm so lange, bis die Taste den Portpin P2.0 auf „0“ zieht (siehe ‚).
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
TestReset |
Test_Reset |
TestReset.c, START900.a51 |
Tabelle 11 Projekt TestReset
|
‚ |
#include <REG932.H>
// Ausgabetexte definieren char code acResetInf[] = {"Reset Detect "}; char code acNormalInf[] = {"Normal Start "}; unsigned char ucOffset; sbit sbTaste = P2^0; // Abfragetaste
v_InitRS232(void) { P1M1 = P1M1 & 0xFC; P1M2 = P1M2 & 0xFC;
SCON = 0x40; // 8-bit UART (var. Baudrate) // Baudrate fuer Baudratengenerator setzen BRGR0 = 0xF0; // 9600 Baud BRGR1 = 0x02;
// Baudratengenerator freigeben und starten BRGCON = 0x03;
// Interrupt Konfiguration ES = 1; // Freigabe der ser. Schnittstelle }
bit btResetDetect, btRS232Finished; void main(void) { v_InitRS232(); EA = 1; // allg. Interruptfreigabe
while(1) { btRS232Finished =0; // Variablen zuruecksetzen ucOffset = 0; if (RSTSRC & 0x01) // externer Reset wurde ausgeloest { btResetDetect = 1; SBUF = acResetInf[ucOffset++]; } else { btResetDetect = 0; while (sbTaste == 1); // Warten bis Taste gedrueckt SBUF = acNormalInf[ucOffset++]; } while (btRS232Finished == 0); // Warten bis alle Zeichen } // ausgesendet wurden }
// Seriell ISR is called after a complete send from the UART void v_IntSer(void) interrupt 4 using 1 { unsigned char ucSendVal; TI = 0; // TI-Flag loeschen
// naechstes Byte zum Senden bereitstellen if (btResetDetect == 0) ucSendVal = acNormalInf[ucOffset]; else ucSendVal = acResetInf[ucOffset]; if (ucSendVal != 0) // Ueberpruefung ob Ende der Zeile erreicht { SBUF = ucSendVal; // Wert aussenden ucOffset++; // Offset im Array erhoehen } else { while (sbTaste == 0); // Warten bis Taste losgelassen wurde RSTSRC = 0x00; // Reset-Flag zuruecksetzen ucOffset =0; // Offset im Array auf 0 setzen btRS232Finished = 1; // Bit fuer Endekennung des } // Sendevorgangs setzen } |
Listing 4 Inhalt von TestReset.c
Sie haben mit den Aufbau des Experimentierboards alle Möglichkeiten, die beiden Analog-Komperatoren bzw. die A/D-Wandler (P89LPC935) zu testen. Die Konfiguration erfolgt mit Hilfe von Jumpern (siehe Abbildung 17). Das RC-Glied, bestehend aus R56 und C22, ist für die Appnote AN1087 „Low-Cost A/D-Converter with LPC-Devices“ von Philips vorgesehen. Die Appnote finden sie unter www.c51.de/LPC900 Abschnitt „Appnotes (Philips)“.
Wenn sie die Analog-Komperatoren bzw. den A/D-Wandler verwenden wollen, müssen die jeweiligen Widerstände bei RW1 entfernt sein. Sie können dazu entweder RW1 aus dem Sockel ziehen oder die jeweiligen Füße beiseite biegen.
Um die einzelnen Tests mit den Analog-Komperatoren nachvollziehen zu können, sollten sie sich zuerst das Kapitel 10.17 „Analog-Komperatoren“ und das Ergänzungskapitel 10.20 „A/D-Wandler“ durchgelesen haben. Das Ergänzungskapitel finden sie in der Rubrik „Auszüge zum Buch Keil C51 / Philips LPC900“.
|
|
Abbildung 17 Schaltplan für die Analog-Komperatoren
|
|
Bestücken sie zuerst den Widerstand und den Kondensator, dann die Stiftleisten und zum Schluss die Potis. Um die Spannungsversorgung von 3.3 V an den Potis (siehe Abbildung 18) zu prüfen, stecken sie das MCB900- bzw. EPM900-Board an das Experimentierboard an. Falls keine Spannung anliegt, überprüfen sie die Jumperstellung von J28. Je nach Board muss der Jumper umgesteckt werden. |
Abbildung 18 Bestückungsplan für die Ansteuerung der Analog-Komperatoren
|
Position |
Wert/Bez. |
Anzahl |
Beschreibung |
|
C22 |
33 nF |
1 |
|
|
R56 |
100 k |
1 |
|
|
PT2, PT3 |
25 k |
2 |
|
|
Stiftleiste |
2-reihig |
11 |
|
Tabelle 12 Bestückungsliste für die Ansteuerung der Analog-Komperatoren
Für den ersten Test soll der Komperator 1 ein Signal ausgeben, wenn der Eingang von CIN1A (P0.4) unter die interne VREF abfällt. Für diesen Versuchsaufbau muss J2 in der oberen Position waagerecht mit einem Jumper versehen werden. Die VREF wird im Datenblatt mit einem Wert von 1.11 – 1.34 V angegeben. Fällt die Spannung unter die VREF ab, soll die LED P2.0 eingeschaltet werden. In Abhängigkeit der Einstellung von PT2 sollte sich jetzt der Zustand an der LED ändern.
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
TestComp1_Vref |
Test_Comp1Vref |
TestComp1_Vref.c |
Tabelle 13 Projekt TestComp1_Vref
|
|
#include <REG932.H>
sbit sbComp1LED = P2^0; sbit sbComp1Out = P0^6; void main(void) { P2M1 = 0x00; // Port 2 auf quasi-bidir. P0M1 = 0xBF; // Port 0, Pin 6 auf quasi-bidir.
CMP1 = 0x2C; // CE1 =1 (En.Comp), CN1 =1 (Vref) // OE1 =1 (Output auf P0.6)
while(1) { sbComp1LED = sbComp1Out; } } |
Listing 5 Inhalt von TestComp1_Vref.c
Um die Ausgabe von CMP1 (P0.6) abfragen zu können, muss dieser Portpin in den Modus „Quasi-bidir.“ gesetzt werden. Die Abfrage des Komperators kann auch mit Hilfe der ISR durchgeführt werden (siehe dazu Beispiel AnalogComp.uv2 aus Kapitel 10.17 [3]).
Erstellen sie nun ein Programm, das den Wert von PT2 mit dem AD12 wandelt. Stecken sie dazu einen weiteren Jumper in J2.
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
TestAD_PT2 |
Test_AD_PT2 |
TestAD_PT2.c |
Tabelle 14 Projekt TestAD_PT2
|
|
#include <REG935.H>
void main(void) { P2M1 = 0x00; // Port 2 auf quasi-bidir.
ADINS = 0x40; // Auswahl des A/D-Eingangs (AD12) ADCON1 = 0x04; // ENADC1 =1 (Freigabe des A/D-Wandlers) ADMODB = 0x40; // Wandlerfrequenz (CPU-Takt /3)
while(1) { ADCON1 = ADCON1 | 0x01; // Start einer A/D-Wandlung while ((ADCON1 & 0x08) == 0); ADCON1 = ADCON1 & 0xF7; // A/D-Flag zuruecksetzen P2 = AD1DAT2; // Inhalt in P2 ausgeben } } |
Listing 6 Inhalt von TestAD_PT2.c
Der hier verwendete Inkrementalgeber enthält einen 2-bit Graycode und einen Taster. Der Encoder kann über die Jumper J7 bis J9 an den Port 0 angeschlossen werden (siehe Abbildung 19). Mit Hilfe der Widerstände R44, R45 und R55 werden die Eingänge auf 5 V gelegt. In Abhängigkeit der Encoderstellung wird der jeweilige Eingang (CHA, CHB) auf 0 V gezogen.
|
|
Abbildung 19 Schaltplan für den Inkrementalgeber Bourns
Bestücken sie zuerst die Widerstände und die Stiftleisten für die Jumper J7 bis J9. Danach den Inkrementalgeber.
|
|
|
Abbildung 20 Bestückungsplan für den Inkrementalgeber Bourns
|
Position |
Wert/Bez. |
Anzahl |
Beschreibung |
|
R44, R45, R55 |
10 k |
1 |
|
|
S17 |
Bourns |
1 |
Inkrementalgeber mit Taster |
|
J7, J8, J9 |
Stiftleiste |
3 |
|
Tabelle 15 Bestückungsliste für den Inkrementalgeber Bourns
Um die Funktionalität des Inkrementalgebers zu testen, verbinden sie die Buchsen XP0.5 mit XLED1, XP0.7 mit XLED2 und XP0.6 mit XLED1. Wenn sie die Taste des Inkrementalgebers betätigen, leuchtet die erste LED auf. Wird nun der Inkrementalgeber gedreht, ändern sich die Zustände der zweiten und dritten LED.
Um den Inkrementalgeber mit dem µController auszuwerten, erstellen sie das Projekt aus Tabelle 16. Um die Auswertung zu vereinfachen, wird die Keyboard-Funktionalität und die ISR des Keyboards verwendet. Eine ausführliche Beschreibung zum Aufbau des Keyboard Interrupts finden sie in Kapitel 10.9 [3].
Die Variable „ucActEncVal” speichert beim Start den aktuellen Zustand des Inkrementalgebers (siehe Listing 7, ). Danach wird der aktuelle Zustand von CHA und CHB im Patternregister KBCON abgespeichert. Nach der Freigabe der ISR für das Keyboard läuft das Programm in der while(1) Schleife (siehe ‚). Erfolgt nun eine Änderung der Zustände von Portpin P0.5 bis P0.7 wird die Keyboard-ISR aufgerufen (siehe ƒ). In der ISR wird zuerst überprüft, ob die Taste betätigt wurde. Ist dies der Fall, wird die LED an Port 2.0 gelöscht (siehe „), ansonsten gesetzt (siehe …). Es folgt nun die Überprüfung, ob der Inkrementalgeber gedreht wurde (siehe †). Ist dies der Fall, wird die Drehrichtung ausgewertet (siehe ‡). Je nach Drehrichtung des Inkrementalgebers wird die Variable „ucValue“ um eins erhöht bzw. erniedrigt. Danach wird die aktuelle Position in „ucActEncVal“ gespeichert (siehe ˆ). Der Wert von ucValue wird in den oberen sieben Bits von P2 ausgegeben (siehe ‰). Am Schluss der ISR wird das Keyboard-Interrupt-Flag zurückgesetzt (siehe Š).
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
Test_Encoder |
Test_Encoder |
TestEncoder.c |
Tabelle 16 Projekt Test_Encoder
|
‚
ƒ
„
…
†
‡
ˆ
‰ Š
|
#include <REG932.H> // Bourns EPS1D-F19-AE0036 (2-bit gray code) sbit EncSwitch = P0^6; // Taster sbit EncChA = P0^5; // Kanal A sbit EncChB = P0^7; // Kanal B
sbit LED0 = P2^0; // LED definition unsigned char ucActEncVal; // akt. Position des Inkrementalgebers unsigned char ucValue = 0;
void main(void) { P2M1 = 0x00; P2M2 = 0x00; P2 = 0x01; // Taste beim Inkrementalgeber “offen” KBMASK = 0xE0; // Maske fuer Portpin 5, 6 und 7
ucActEncVal = P0 & 0xA0; // Abspeichern der akt. Position KBPATN = P0 & 0xE0; // Setzen des Keyboard-Patterns KBCON = 0x00; EKBI = 1; // ISR fuer Keyboard-Int. freigeben EA = 1; // Allg. Interruptsperre aufheben
while(1); // Endlosschleife }
// ISR des Keyboard void v_KeyboardInt(void) interrupt 7 { if (EncSwitch == 0) // Abfrage des Tasters LED0 = 0; else LED0 = 1; KBPATN = P0 & 0xE0; // Neues Keyboard-Pattern setzen
if (ucActEncVal != (P0 & 0xA0))// Abfrage, ob Aenderung beim { // Inkrementalgebers erfolgt ist switch(P0&0xA0) { case 0x00: if (ucActEncVal == 0x20) ucValue++; else ucValue--; break; case 0x20: if (ucActEncVal == 0xA0) ucValue++; else ucValue--; break; case 0x80: if (ucActEncVal == 0x00) ucValue++; else ucValue--; break; case 0xA0: if (ucActEncVal == 0x80) ucValue++; else ucValue--; break; } ucActEncVal = P0 & 0xA0; // Abspeichern der neuen Position } // des Inkrementalgebers P2 = (ucValue *2) | (P2 & 0x01); // Ausgabe auf P2 KBCON = 0x00; // loeschen des Keyboard Flags } |
Listing 7 Inhalt von TestEncoder.c
Auf dem Experimentierboard können sie eine Alphanumerische LCD-Anzeige, die mit einem HD44780 kompatiblen Controller ausgerüstet ist, anschließen. Die Ansteuerung erfolgt über den Port 2 im 4-bit Modus (siehe Abbildung 21). Der Kontrast der LCD kann über P1 eingestellt werden. Da die LCD-Hersteller ihre LCDs teilweise mit einer einreihigen bzw. 2-reihigen Anschlussbelegung anbieten, sind für beide Varianten Anschlüsse vorgesehen. Mit Hilfe der Jumper J14-J20 wird die Verbindung zur LCD realisiert. Die Lage der Jumper können sie Abbildung 22 entnehmen.
Löten sie zuerst die 2x2-reihigen Stiftleisten für die Jumper und in Abhängigkeit der LCD nur die einreihige Buchsenleiste bzw. die zweireihige Stiftleiste ein. Löten sie nun noch das Poti (PT1) ein und messen sie die Spannung nach. An Pin 2 müssen 5 V anliegen. An Pin 3 kann eine Spannung zwischen 0–5 V in Abhängigkeit der Stellung des PT1 anliegen. Entfernen sie die Spannungsversorgung des Experimentierboards und stecken sie die LCD-Anzeige ein. Stecken sie nun die Spannungsversorgung wieder ein und stellen den Kontrast auf dem LCD mit PT1 so ein, dass nur die erste Zeile dunkel hinterlegt ist.
|
|
Abbildung 21 Schaltplan für die LCD
|
|
|
Abbildung 22 Bestückungsplan der LCD
|
Position |
Wert/Bez. |
Anzahl |
Beschreibung |
|
X6 |
16 pol. Stiftleiste |
1 |
(alternative Bestückung) |
|
X7 |
14 pol. Buchsenleiste |
1 |
einreihig |
|
|
2x2 Stiftleiste |
7 |
|
|
PT1 |
Poti 25k |
1 |
|
|
J14-J20 |
Stiftleiste |
7 |
|
Tabelle 17 Bestückungsliste der LCD
Erstellen sie nun ein Programm, das eine Ausgabe auf dem LCD realisiert. Eine ausführliche Beschreibung, wie der HD44780 programmiert wird und die hier verwendeten Funktionen finden sie in Buch Teil 2, Kapitel 5. Dieses Beispiel verwendet anstatt dem printf() die Funktion v_SM_Printf(). Diese Funktion ist wesentlich kleiner, da sie die Option „%f“ nicht unterstützt.
F !! Eine ausführliche Beschreibung zu v_SM_Printf() und den anderen Funktionen finden sie in der PDF-Datei „Auszug aus Buch Teil 1 (2. Auflage) Kapitel 20“. Die Datei finden sie auf www.c51.de in der Rubrik „C51-Bücher“ im Abschnitt „Auszüge zum Buch Teil 1 (2.Auflage)“ !!
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
LCD_Port |
LCD_P2Test |
LCD_Test.c, CGRAM_V7.c sm_printf.c, LCDLib_4bitPort.c Itoa.a51, Bcd2Hex.a51 |
Tabelle 18 Projekt LCD_Port
|
|
#include <REG932.H> #include <lcd_def.h> #include <sm_printf.h>
void main(void){ uchar ucResult; // 0.1 Initialisierung des Port 0 auf Bidirektional P2M1 = 0; P2M2 = 0; // 1. Initialisierung des HD44780 Controller ucResult = uc_LCDIni(_2LINE | _7DOTS); // 2. Loeschen des HD44780 Speichers. uc_Clrscr(); // 3. Ausgabe auf dem Display v_SM_Printf( "LPC 900"); v_SM_Printf( "\n%cExp.Board V1.4 ",_2_LINE);
while(1); } |
Listing 8 Inhalt von LCD_Test.c
Das Experimentierboard enthält einen Integrierer (siehe Abbildung 23) sowie einen Impedanzwandler (siehe Abbildung 24). Der Integrierer ist so dimensioniert worden, dass er aus PWM-Signalen (Puls Weiten Modulation) eine Gleichspannung erzeugt. Die obere Grenzfrequenz für den Integrierer errechnet sich wie folgt:
FGRENZ = 1 = 1 = 72.34 Hz
2*PI*R*C 6.283*2200*1 µF
Der Impedanzwandler ist für den D/A-Ausgang des P89LPC935 vorgesehen, da dieser sehr hochohmig ist.
|
|
Abbildung 23 Schaltplan für den LM258 (Integrierer)
|
|
Abbildung 24 Schaltplan für den LM258 (Impedanzwandler)
|
|
Löten sie zuerst die Widerstände, den Sockel für den OP und den Kondensator ein. Danach erst die Buchsen. |
Abbildung 25 Bestückungsplan für den LM258
|
Position |
Wert/Bez. |
Anzahl |
Beschreibung |
|
R33, R34 |
2k2 |
2 |
|
|
C10 |
1 µF |
1 |
!! Polarität beachten !! |
|
C11 |
22 pF |
1 |
|
|
N2 |
8-pol. Sockel |
1 |
!! Einbaurichtung beachten !! |
|
N2 |
LM258D |
1 |
!! Einbaurichtung beachten !! |
|
XIN2, XOUT2, XDA |
2mm Buchsen |
3 |
|
Tabelle 19 Bestückungsliste für den LM258
Erstellen sie nun ein Projekt, das ein Rechtecksignal auf Port P1.0 mit einem ti/T = 0.5 ausgibt. Das Rechtecksignal soll mit Hilfe des Timers 0 in Betriebsart 2 erzeugt werden. Funktionsweise und Programmierung des Timers 0 können sie in Kapitel 10.10, Abschnitt „Programmierung der Timer 0,1 (Betriebsart 2)“ entnehmen. Da T = R*C = 2.2 ms entspricht, sollte die Frequenz um Faktor 10 bis 20 größer sein, damit das Ausgangssignal nur leicht gewellt ist.
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
Test_OPImp |
Test_OPImp |
TestOpImp.c |
Tabelle 20 Projekt Test_OPImp
|
|
#include <REG932.H> sbit btToggle = P1^0;
void main(void) { P1M1 = P1M1 & 0xFE; // Betriebsart Push/Pull P1M2 = P1M2 | 0x01; // fuer Portpin P1.0
TMOD = 0x02; // Timer 0, Betriebsart 2 TH0 = 0x80; // Timer 0 mit Wert vorladen TL0 = TH0; TF0 = 0; // Ueberlaufflag zuruecksetzen TR0 = 1; // Timer 0 starten ET0 = 1; // Interrupt fuer Timer 0 freigeben EA = 1; // allg. Interruptsperre aufheben
while(1); // Endlosschleife }
void v_Timer0Int(void) interrupt 1 using 1 { btToggle = !btToggle; } |
Listing 9 Inhalt von TestOpImp.c
|
|
Abbildung 26 ti/T = 0.5 (Timer 0, Betriebsart 2, TH0 = 0x80) (Rot = Ausgang OP)
Soll das ti/T-Verhältnis zwischen 0–1 einstellbar sein, muss der Timer in Betriebsart 6 betrieben werden. Da der Ausgang von Timer 0 bei der Betriebsart 6 keinen Push-Pull zulässt, muss der Timer 1 verwendet werden.
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
Test_OP_tiT |
Test_OP_tiT |
TestOp_tiT.c |
Tabelle 21 Projekt Test_OP_tiT
|
|
#include <REG932.H>
void main(void) { P0M1 = P1M1 & 0x7F; // Betriebsart Push/Pull P0M2 = P1M2 | 0x80; // fuer Portpin P0.7
TMOD = 0x20; // Timer 1, Betriebsart 6 TAMOD= 0x10; TH1 = 0xF0; // Timer 1 mit Wert vorladen TL1 = TH1; AUXR1 = 0x20; // P0.7 freigeben TR1 = 1; // Timer 0 starten while(1); // Endlosschleife } |
Listing 10 Inhalt von TestOp_tiT.c
|
|
Abbildung 27 ti/T = 0.1 (Timer 1, Betriebsart 6, TH1 = 0xF0) (Rot = Ausgang OP)
|
|
Abbildung 28 ti/T = 0.9 (Timer 1, Betriebsart 6, TH1 = 0x10) (Rot = Ausgang OP)
Erstellen sie ein Programm, das mit Hilfe des Inkrementalgebers das ti/T Verhältnis (Reloadwert von TH1) verändert. Da der Ausgang des PWM-Signals wie der Ch-B auf P0.7 liegt, muss der Eingang von CH-B auf P0.5 umgelegt werden. Ziehen sie die Jumper J7 und J9 und stellen sie mit Hilfe einer Brücke eine Verbindung zwischen J9 und P0.6 her. Dieses Projekt lässt sich sehr einfach aus den vorangegangenen Projekten „Test_OP_tiT“ und „Test_Encoder“ erstellen. Die einzige Anpassung, die sie durchführen müssen, ist die Umstellung der Definition und der Auswertung von Port 0.7 nach Port 0.6 (siehe Listing 11, ).
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
Test_OP_Inc |
Test_OP_Inc |
TestOp_Inc.c |
Tabelle 22 Projekt Test_OP_Inc
|
|
#include <REG932.H>
// Bourns EPS1D-F19-AE0036 (2-bit gray code) sbit EncChA = P0^5; // Kanal A sbit EncChB = P0^6; // Kanal B
unsigned char ucActEncVal; // akt. Position des Inkrementalgebers
void main(void) { KBMASK = 0x60; // Maske fuer Portpin 5, 6 und 7
ucActEncVal = P0 & 0x60; // Abspeichern der akt. Position KBPATN = P0 & 0x60; // Setzen des Keyboard-Patterns KBCON = 0x00;
EKBI = 1; // ISR fuer Keyboard-Int. freigeben EA = 1; // Allg. Interruptsperre aufheben
P0M1 = P1M1 & 0x7F; // Betriebsart Push/Pull P0M2 = P1M2 | 0x80; // fuer Portpin P0.7
TMOD = 0x20; // Timer 1, Betriebsart 6 TAMOD= 0x10; TH1 = 0x10; // Timer 1 mit Wert vorladen TL1 = TH1; AUXR1 = 0x20; // P0.7 freigeben TR1 = 1; // Timer 0 starten
while(1); // Endlosschleife }
// ISR des Keyboard void v_KeyboardInt(void) interrupt 7 { KBPATN = P0 & 0x60; // Neues Keyboard-Pattern setzen if (ucActEncVal != (P0 & 0x60)) // Abfrage, ob Aenderung beim { // Inkrementalgebers erfolgt ist switch(P0&0x60) { case 0x00: if (ucActEncVal == 0x40) TH1++; else TH1--; break; case 0x20: if (ucActEncVal == 0x00) TH1++; else TH1--; break; case 0x40: if (ucActEncVal == 0x60) TH1++; else TH1--; break; case 0x60: if (ucActEncVal == 0x20) TH1++; else TH1--; break; } ucActEncVal = P0 & 0x60; // Abspeichern der neuen Position } // des Inkrementalgebers KBCON = 0x00; // loeschen des Keyboard Flags } |
Listing 11 Inhalt von TestOp_tiT.c
Auf dem Experimentierboard sind die Bausteine PCF8574 (I/O-Expander), SAA1064 (7-Segment LED) und DS1621 (Temperatursensor) vorhanden. Diese können über das MCB900 bzw. EPM900 adressiert werden. Dafür müssen die Jumper J5 und J6 gesteckt sein (siehe Abbildung 29). Da der I²C-Bus mit einer Open-Drain Beschaltung arbeitet, werden die Leitungen mit den Widerständen R30 und R31 gegen VCC abgeschlossen.
|
|
|
Abbildung 29 Schalt-/ Bestückungsplan für den I²C-Bus
|
Position |
Wert/Bez. |
Anzahl |
Beschreibung |
|
R30, R31 |
5k6 |
2 |
|
|
J5, J6 |
Stiftleiste |
3 |
|
Tabelle 23 Bestückungsliste für den I²C-Bus
Mit einem ersten Test mit I²C-Bus sollen alle Adressen des I²C-Busses durchfahren werden. Wird ein Acknowledge (Ack) erkannt, wird die I²C-Bus Adresse gespeichert. Eine ausführliche Beschreibung zur Programmierung des I²C-Busses finden sie unter www.c51.de in der Rubrik „LPC900“ im Abschnitt „Auszüge zum Buch Keil C51 / Philips LPC900“ im File „LPC900_Kap10-Erg_I2C.pdf“.
Der I²C-Controller wird auf 100 kHz eingestellt (siehe ‚), da der SAA1064 nur diese Frequenz unterstützt. In der for-Schleife (siehe ƒ) werden jetzt nacheinander alle Adressen ausgesendet. Wird auf eine ausgesendete Adresse ein Ack empfangen, wird in der ISR die Bitvariable „btAckFound“ gesetzt (siehe „). In der main-Schleife wird die gefundene Adresse im Array „result“ abgespeichert (siehe Listing 12, ).
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
I2C_Test |
I2CTest_Device |
TestI2C.c |
Tabelle 24 Projekt I2C_Test
|
‚
ƒ
„
|
#include <REG932.H> unsigned char ucSlaveAdr, offset; unsigned char result[20]; bit btAckFound; bit I2cCheck;
void main(void) { unsigned char loop; P1M1 |= 0x0C; // SDA und SCL als Open-Drain P1M2 |= 0x0C; I2SCLH = 19; // I2C-Geschwindigkeit ~100 KHz I2SCLL = 19; I2CON = 0x44; // I2C-Hardware aktivieren // (STO, STA, SI = 0, ACK =1) EI2C = 1; // I2C Interrupt freigeben EA = 1; // allgemeine Interruptsperre aufheben
for (loop = 0; loop < 250; loop+=2) { I2cCheck = btAckFound = 0; ucSlaveAdr = loop; // slave address I2CON = 0x64; // Startbedingung setzen while (I2cCheck == 0); if (btAckFound == 1) result[offset++] = loop; } while(1); }
void v_I2CInterrupt(void) interrupt 6 { switch(I2STAT) // Auswertung des Statusregisters { case 0x08: // Status: "START transmitted" I2DAT = ucSlaveAdr; I2CON = 0x44; // (STO, STA, SI = 0, ACK =1) break; case 0x18: // Status: "SLA+W transmitted; ACK received" I2CON = 0x54; // Stoppbedingung setzen (STO =1) btAckFound = 1; I2cCheck = 1; break; case 0x20: // Status: "SLA+W transmitted; NOT ACK received" I2CON = 0x54; // Stoppbedingung setzen (STO =1) I2cCheck = 1; break; default: // Andere Statuswerte I2CON = 0x54; // Stoppbedingung setzen (STO =1) I2cCheck = 1; break; } } |
Listing 12 Inhalt von I2C_Test.c
Sie können sich die gefundenen Adressen in µVision anzeigen lassen, indem sie mit der rechten Maustaste auf die Variable „result“ klicken und den Menüpunkt „Add "result" to Watch Window...“ auswählen (siehe Abbildung 30). Mit den Unterpunkten #1 und #2 können sie noch wählen, ob die Variable im Watch-Window #1 oder #2 abgelegt wird.
|
|
Abbildung 30 Editor-Menüpunkt „Add "result" to Watch Window“
Öffnen sie das Watch-Window über den Menüpunkt „View/ Watch & Call Stack Window“. Über das +-Zeichen wird das Array „result“ aufgeklappt. Da noch keine I²C-Bausteine auf dem Experimentierboard vorhanden sind, enthalten alle Einträge nach Durchlauf des Programms den Wert 0x00 (siehe Abbildung 31).
|
|
Abbildung 31 Watch & Call Stack Window
Beim PCF8574 handelt es sich um einen I/O-Expander. Mit diesem können sie zusätzliche Ein-/Ausgänge für die Applikation bereitstellen. Der PCF8574 ist auf die Adresse 0x40 eingestellt (siehe Abbildung 32). Mit Hilfe des Jumpers J11 kann der Interrupt des PCF8574 auf den µController angeschlossen werden. Zudem kann die LCD-Anzeige über den PCF8574 angesteuert werden. In diesem Fall müssen die Jumper auf J21 bis J27 gesteckt sein.
|
|
Abbildung 32 Schaltplan für den PCF8574
Bestücken sie zuerst den Kondensator, den 16-poligen Sockel und die Stiftleiste für J11. Danach die Buchsen für die Verdrahtung. Stecken sie den Baustein in den Sockel und legen sie die Spannungsversorgung an.
|
|
Folgende Spannungen müssen am PCF8574 anliegen:
Tabelle 25 Spannungsversorgung
|
Abbildung 33 Bestückungsplan des PCF8574
|
Position |
Wert/Bez. |
Anzahl |
Beschreibung |
|
C8 |
100 n |
1 |
|
|
D2 |
16-pol. Sockel |
1 |
|
|
D2 |
PCF8574 |
1 |
!! Einbaurichtung beachten !! |
|
XP0D4-XPD7D4 |
2 mm Buchse |
8 |
|
|
J11 |
Stiftleiste |
1 |
|
Tabelle 26 Bestückungsliste für den PCF8574
Erstellen sie ein Projekt, um die Funktionalität des PCF8574 austesten zu können. Die Ausgänge des PCF8574 sollen nacheinander erhöht werden. Um die Zustände der Ausgänge beobachten zu können, werden diese an die LED-Zeile angeschlossen. Verbinden sie XP0D4 bis XP0D7 mit XLEDB0 bis XLEDB7.
Da die Kommunikation bei der I²C-Schnittstelle mit einer ISR durchgeführt wird, müssen die zu sendenden Daten global gespeichert werden. Am besten eignet sich hier eine Struktur (siehe Listing 13). In der Variablen „Adr“ wird die Adresse des I²C-Bausteins, in „DataLen“ die Anzahl der zu sendenden Daten abgespeichert. Die Daten selbst sind im Array „Val“ gespeichert.
|
|
struct stI2C { unsigned char Adr; unsigned char DataLen; unsigned char Val[10]; }; |
Listing 13 Strukturaufbau für die I²C-Kommunikation
Erstellen sie nun das Projekt aus Tabelle 27. Um eine bessere Lesbarkeit des Programms zu erreichen, wurden einige Programmteile in Funktionen ausgelagert. Die Funktion „v_InitI2C()“ (siehe Listing 14, ) übernimmt die komplette Initialisierung des I²C-Bus. Die Funktion „v_ SetNextI2Cval()“ (siehe ‚) schreibt ein Datenbyte in das Array und erhöht zudem die Variable „DataLen“. Die Funktion „v_StartI2Ctrans()“ (siehe ƒ) startet den Sendevorgang beim I²C-Bus. Mit der Funktion „v_WaitI2Cfinish()“ (siehe „) wird auf das Ende des Sendevorgangs gewartet.
Die I²C-ISR benötigt für dieses Verfahren zudem die eigene globale Variable „ucI2Coff“ (siehe …). Diese enthält den Offset für das zu sendende Datenarray. Wird nun ein Startvorgang eingeleitet, wird „ucI2Coff“ auf „0“ zurückgesetzt (siehe †). Wird ein Ack auf die gesendete Adresse empfangen, verzweigt das Programm der ISR in den case 18 (siehe ‡). Es wird nun überprüft, ob noch Daten zum Versenden vorhanden sind (siehe ˆ). Ist dies der Fall, wird das nächste Byte aus dem Array geholt und in den SFR I2DAT geschrieben (siehe ‰). Andernfalls wird die Stoppbedingung gesetzt (siehe Š).
Da das Aussenden an den PCF8574 sehr schnell geht, ist eine Zeitschleife nach jedem Sendevorgang eingebaut. Die Ausgabe auf die LEDs lässt sich mit dieser Zeitverzögerung gut beobachten.
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
Test_PCF8574 |
Test_PCF8574 |
Test_PCF8574.c |
Tabelle 27 Projekt Test_PCF8574
|
‚
ƒ
„
…
†
‡
ˆ
‰
Š
|
#include <REG932.H> struct stI2C { unsigned char Adr; unsigned char DataLen; unsigned char Val[10]; }; struct stI2C Slave; bit btI2cFinished;
v_InitI2C(void) { P1M1 |= 0x0C; // SDA und SCL als Open-Drain P1M2 |= 0x0C; I2SCLH = 19; // I2C-Geschwindigkeit ~100 KHz I2SCLL = 19; I2CON = 0x44; // I2C-Hardware aktivieren // (STO, STA, SI = 0, ACK =1) EI2C = 1; // I2C Interrupt freigeben }
v_SetNextI2CVal(unsigned char ucVal) { Slave.Val[Slave.DataLen] = ucVal; Slave.DataLen++; }
v_StartI2CTrans(void) { btI2cFinished = 0; I2CON = 0x64; // Startbedingung setzen }
void v_WaitI2CFinish(void) { while (btI2cFinished == 0); }
void main(void) { unsigned char ucVal; unsigned int uiWait; v_InitI2C(); EA = 1; // allgemeine Interruptsperre aufheben Slave.Adr = 0x40; // Adresse I/O-Expander while(1) { v_SetNextI2CVal(ucVal); v_StartI2CTrans(); v_WaitI2CFinish(); ucVal++; for (uiWait= 0; uiWait < 0xFFFF; uiWait++); } }
unsigned char ucI2COff; void v_I2CInterrupt(void) interrupt 6 { switch(I2STAT) // Auswertung des Statusregisters { case 0x08: // Status: "START transmitted" I2DAT = Slave.Adr; ucI2COff = 0; I2CON = 0x44; // (STO, STA, SI = 0, ACK =1) break; case 0x18: // Status: "SLA+W transmitted; ACK received" case 0x28: // Status: "byte transmitted; ACK received" if (ucI2COff < Slave.DataLen) { I2DAT = Slave.Val[ucI2COff]; // set next value ucI2COff++; I2CON = 0x44; // (STO, STA, SI = 0, ACK =1) } else { Slave.DataLen = 0; btI2cFinished = 1; I2CON = 0x54; // Stoppbedingung setzen (STO =1) } break; case 0x20: // Status: "SLA+W transmitted; NOT ACK received" I2CON = 0x54; // Stoppbedingung setzen (STO =1) break; default: I2CON = 0x54; // Stoppbedingung setzen (STO =1) break; } } |
Listing 14 Inhalt von Test_PCF8574.c
Die Schaltung des SAA1064 auf dem Experimentierboard ist so aufgebaut, dass bis zu vier 7-Segment LEDs angesteuert werden können (siehe Abbildung 34).
|
|
Abbildung 34 Schaltplan für den SAA1064
Bestücken sie zuerst die beiden Kondensatoren, den 24-poligen Sockel und die 7-Segment Anzeigen. Danach erst die beiden Transistoren. Stecken sie zum Schluss den Baustein in den Sockel.
|
|
|
Abbildung 35 Bestückungsplan des SAA1064
|
Position |
Wert/Bez. |
Anzahl |
Beschreibung |
|
C20 |
100 n |
1 |
|
|
C12 |
2.7 n |
1 |
|
|
VL1-VL4 |
SA36-11HWA |
4 |
!! Einbaurichtung beachten !! |
|
D6 |
24-pol. Sockel |
1 |
|
|
D6 |
SAA1064 |
1 |
!! Einbaurichtung beachten !! |
|
T4, T5 |
BC547B |
2 |
!! Einbaurichtung beachten !! |
Tabelle 28 Bestückungsliste für des SAA1064
|
|
Abbildung 36 enthält die Zuordnung der Bits im Datenbyte des SAA1064 und der 7-Segment Anzeige. |
Abbildung 36 Zuordnung der Bits zu den einzelnen LEDs
Abbildung 37 enthält die HEX-Werte für die Zahlen 0 bis 9.
|
|
|
Abbildung 37 Zahlendarstellung 0–9
Es soll nun ein Projekt erstellt werden, das im VL1 nacheinander die Zahlen 0 bis 9 anzeigt. Der SAA1064 kann für dieses Beispiel im „static mode“ oder im „dynamic mode“ für die LEDs betrieben werden (Funktionsweise siehe Datenblatt).
Für die Definition der HEX-Werte wird der Aufzählungstyp enum verwendet (siehe Listing 15, ).
F !! Aufbau und Funktionsweise von enum sind in [1], Kapitel 13.4 beschrieben. !!
Die Initalisierung des SAA1064 erfolgt am Anfang der main() (siehe ‚). Da die Daten ab Offset 1 im SAA1064 übergeben werden, wird zuerst die Offsetadresse gesetzt (siehe ƒ). Die Ausgabe der einzelnen Werte erfolgt in der switch-case Anweisung (siehe „).
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
Test_SAA1064 |
Test_SAA1064 |
Test_SAA1064.c |
Tabelle 29 Projekt Test_SAA1064
|
‚ ‚ ‚
ƒ „
|
#include <REG932.H>
enum enSAASEG {NULL = 0x3F, EINS = 0x06, ZWEI = 0x5B, DREI = 0x4F, VIER = 0x66, FUENF = 0x6D, SECHS = 0x7D, SIEBEN = 0x07, ACHT = 0x7F, NEUN = 0x67, PUNKT = 0x80};
struct stI2C { unsigned char Adr; unsigned char DataLen; unsigned char Val[10]; };
struct stI2C Slave; bit btI2cFinished;
v_InitI2C(void) { P1M1 |= 0x0C; // SDA und SCL als Open-Drain P1M2 |= 0x0C; I2SCLH = 19; // I2C-Geschwindigkeit ~100 KHz I2SCLL = 19; I2CON = 0x44; // I2C-Hardware aktivieren // (STO, STA, SI = 0, ACK =1) EI2C = 1; // I2C Interrupt freigeben }
v_SetNextI2CVal(unsigned char ucVal) { Slave.Val[Slave.DataLen] = ucVal; Slave.DataLen++; }
v_StartI2CTrans(void) { btI2cFinished = 0; I2CON = 0x64; // Startbedingung setzen }
void v_WaitI2CFinish(void) { while (btI2cFinished == 0); }
void main(void) { unsigned char ucVal; v_InitI2C(); EA = 1; // allgemeine Interruptsperre aufheben Slave.Adr = 0x70; // Adresse SAA1064 v_SetNextI2CVal(0); // set Subadresse auf 0 (Control-Byte) v_SetNextI2CVal(0xF7); // dynamic alternating mode v_StartI2CTrans(); v_WaitI2CFinish(); while(1) { v_SetNextI2CVal(1); switch (ucVal) { case 0x00: v_SetNextI2CVal(NULL); break; case 0x01: v_SetNextI2CVal(EINS); break; case 0x02: v_SetNextI2CVal(ZWEI); break; case 0x03: v_SetNextI2CVal(DREI); break; case 0x04: v_SetNextI2CVal(VIER); break; case 0x05: v_SetNextI2CVal(FUENF); break; case 0x06: v_SetNextI2CVal(SECHS); break; case 0x07: v_SetNextI2CVal(SIEBEN); break; case 0x08: v_SetNextI2CVal(ACHT); break; case 0x09: v_SetNextI2CVal(NEUN); break; default: v_SetNextI2CVal(0xF7); } v_StartI2CTrans(); v_WaitI2CFinish(); ucVal++; } }
unsigned char ucI2COff; void v_I2CInterrupt(void) interrupt 6 { switch(I2STAT) // Auswertung des Statusregisters { case 0x08: // Status: "START transmitted" I2DAT = Slave.Adr; ucI2COff = 0; I2CON = 0x44; // (STO, STA, SI = 0, ACK =1) break; case 0x18: // Status: "SLA+W transmitted; ACK received" case 0x28: // Status: "byte transmitted; ACK received" if (ucI2COff < Slave.DataLen) { I2DAT = Slave.Val[ucI2COff]; // set next value ucI2COff++; I2CON = 0x44; } else { Slave.DataLen = 0; btI2cFinished = 1; I2CON = 0x54; // Stoppbedingung setzen (STO =1) } break; case 0x20: // Status: "SLA+W transmitted; NOT ACK received" I2CON = 0x54; // Stoppbedingung setzen (STO =1) break; default: I2CON = 0x54; // Stoppbedingung setzen (STO =1) break; } } |
Listing 15 Inhalt von Test_SAA1064.c
Beim DS1621 handelt es sich um ein digitales Thermometer, das Temperaturen zwischen –55° C und + 125° C in 0,5° C Schritten messen kann. Außerdem kann ein Temperaturbereich überwacht werden. Ist die gemessene Temperatur höher als die eingestellte, wird das Signal Overtemp_S gesetzt. Die Polarität für dieses Signal ist programmierbar.
|
|
|
Abbildung 38 Schalt-/Bestückungsplan für den DS1621
|
Position |
Wert/Bez. |
Anzahl |
Beschreibung |
|
C9 |
100n |
1 |
|
|
N4 |
8 pol. Sockel |
1 |
|
|
N4 |
DS1621 |
1 |
|
Tabelle 30 Bestückungsliste für des DS1621
Erstellen sie ein Programm, das den aktuellen Temperaturwert aus dem Baustein ausliest. In den vorangegangenen Beispielen wurde immer nur ein Wert in die I²C-Bus Bausteine geschrieben. Die ISR für den I²C-Bus muss im switch-case Konstrukt um die I2STAT-Werte 0x40 (SLA+R gesendet ACK empfangen), 0x50 (Datenbyte empfangen, ACK gesendet) und 0x58 (Datenbyte empfangen, NACK gesendet) erweitert werden (siehe Listing 16, , ‚ und ƒ).
Der Empfang der Daten erfolgt nach dem gleichen Prinzip wie das Senden von Daten. Im Strukturelement „DataLen“ wird die Anzahl der zu lesenden Bytes angegeben. In der ISR wird der Wert 0x44 (Lesen mit ACK-Bestätigung) in I2CON geschrieben (siehe „), solange noch mehr als zwei Bytes zu lesen sind. Soll nur noch ein Byte gelesen werden, wird der Wert 0x40 (Lesen mit NACK) in I2CON geschrieben.
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
Test_DS1621 |
Test_DS1621 |
Test_DS1621.c |
Tabelle 31 Projekt Test_DS1621
|
„
‚
ƒ
|
#include <REG932.H>
struct stI2C { unsigned char Adr; unsigned char DataLen; unsigned char Val[10]; };
struct stI2C Slave; bit btI2cFinished;
v_InitI2C(void) { P1M1 |= 0x0C; // SDA und SCL als Open-Drain P1M2 |= 0x0C; I2SCLH = 19; // I2C-Geschwindigkeit ~100 KHz I2SCLL = 19; I2CON = 0x44; // I2C-Hardware (STO, STA, SI = 0, ACK =1) EI2C = 1; // I2C Interrupt freigeben }
v_SetNextI2CVal(unsigned char ucVal) { Slave.Val[Slave.DataLen] = ucVal; Slave.DataLen++; }
v_StartI2CTrans(void) { btI2cFinished = 0; I2CON = 0x64; // Startbedingung setzen }
void v_WaitI2CFinish(void) { while (btI2cFinished == 0); }
void main(void) { v_InitI2C(); EA = 1; // allgemeine Interruptsperre aufheben Slave.Adr = 0x92; // Adresse DS1621 + WR v_SetNextI2CVal(0xEE); //Command Byte: Start Convert v_StartI2CTrans(); v_WaitI2CFinish(); v_SetNextI2CVal(0xAA); //Command Byte:Read Temp v_StartI2CTrans(); v_WaitI2CFinish(); Slave.Adr = 0x92 + 1; // Adresse DS1621 + RD Slave.DataLen = 2; // zwei Bytes werden empfangen v_StartI2CTrans(); v_WaitI2CFinish(); while(1); }
unsigned char ucI2COff; void v_I2CInterrupt(void) interrupt 6 { switch(I2STAT) // Auswertung des Statusregisters { case 0x08: // Status: "START gesendet" case 0x10: // Status: "Repeat Start wurde gesendet" I2DAT = Slave.Adr; ucI2COff = 0; I2CON = 0x44; // (STO, STA, SI = 0, ACK =1) break; case 0x18: // Status: "SLA+W gesendet; ACK empfangen" case 0x28: // Status: "byte gesendet; ACK empfangen" if (ucI2COff < Slave.DataLen) { I2DAT = Slave.Val[ucI2COff]; // naechsten Wert ucI2COff++; // schreiben I2CON = 0x44; } else { Slave.DataLen = 0; btI2cFinished = 1; I2CON = 0x54; // Stopbedingung setzen (STO =1) } break; case 0x20: // Status: "SLA+W gesendet, NACK empfangen" I2CON = 0x54; // Stopbedingung setzen (STO =1) break; case 0x40: // Status: "SLA+R gesendet, ACK empfangen" if (ucI2COff < (Slave.DataLen )) { if (ucI2COff < (Slave.DataLen) ) I2CON=0x44; //ACK else I2CON=0x40; //NACK } break; case 0x50: // Status: "Datenbyte empfangen, ACK gesendet" if (ucI2COff < (Slave.DataLen )) { Slave.Val[ucI2COff] = I2DAT; ucI2COff++; if (ucI2COff < (Slave.DataLen - 1)) I2CON=0x44; // ACK gesendet else I2CON=0x40; // NACK gesendet } break; case 0x58: // Status: "Datenbyte empfangen, NACK gesendet" Slave.Val[ucI2COff] = I2DAT; ucI2COff++; I2CON = 0x54; // Stoppbedingung setzen (STO =1) btI2cFinished = 1; break; default: I2CON = 0x54; // Stoppbedingung setzen (STO =1) btI2cFinished = 1; break; } } |
Listing 16 Inhalt von Test_DS1621.c
Führen sie nach der kompletten Bestückung der I²C-Bausteine das Projekt „I2C_Test“ nochmals aus.
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
I2C_Test |
I2CTest_Device |
TestI2C.c |
Tabelle 32 Projekt I2C_Test
Folgende Einträge sind nun im Array „result“ vorhanden:
|
|
Abbildung 39 Watch & Call Stack Window (voll bestücktes Experimentierboard)
F !! Dieses Testprogramm können sie z. B. auch verwenden, wenn sie bei einem I²C-Baustein die Adresse nicht mehr wissen. !!
Auf dem Experimentierboard können sie zwei Relais ansteuern. Die Ansteuerung erfolgt mit Hilfe eines Transistors (siehe Abbildung 40). Die Freilaufdiode (V3/V4) verhindert, dass der Transistor beim Abschalten des Relais zerstört wird.
|
|
|
Abbildung 40 Schaltplan für die Relais-Ansteuerung
|
|
Bei der Bestückung sollten sie zuerst die liegenden Bauteile (Widerstände, Dioden) einlöten. |
Abbildung 41 Bestückungsplan für die Relais-Ansteuerung
|
Position |
Wert/Bez. |
Anzahl |
Beschreibung |
|
V3/V4 |
1N4401 |
1 |
!! Einbaurichtung beachten. !! |
|
R26, R28 |
2k2 |
2 |
|
|
R27, R29 |
4k7 |
2 |
|
|
T1, T2 |
BC557B |
2 |
!! Einbaurichtung beachten. !! |
Tabelle 33 Bestückungsliste für die Relais-Ansteuerung
Die Ansteuerung eines Lautsprechers kann z. B. über PWM oder auch mit dem D/A-Wandler des P89LPC935 erfolgen.
F !! Der Lautsprecher (Lautsprecheranschluss N6) ist nicht Bestandteil des Bausatzes. !!
|
|
|
Abbildung 42 Schalt-/Bestückungsplan Lautsprecher-Ansteuerung
|
Position |
Wert/Bez. |
Anzahl |
Beschreibung |
|
R32 |
2k2 |
1 |
|
|
R35 |
4k7 |
1 |
|
|
T1 |
BC557B |
1 |
!! Einbaurichtung beachten. !! |
Tabelle 34 Bestückungsliste für die Lautsprecher -Ansteuerung