Aufbau des LPC-Experimentierboards

Allgemeines

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.

Spannungsversorgung

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 Dio­den und des Spannungsreglers. Die Metallseite des 7805 muss zum Leiter­plat­ten­rand 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-Spannungs­ver­sor­gung 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,
XP1.x, XP2.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-Experi­men­tier­board und dem verwendeten Board (EPM900 bzw. MCB900), bevor sie die Spannung an die Boards anlegen. Ansonsten können beide Boards beschädigt wer­den. !!

F !! Wird das MCB900-Board verwendet, werden zwei 9 V-Steckernetzteile benötigt. Die 3.3 V werden vom EPM900-/MCB900-Board geliefert. !!

 

Taster und Schalter

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än­den 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, an­son­sten werden die LED nicht aktiv. Wenn sie den Debugmode gestartet haben, können sie den entsprechenden Dialog unter dem Menü­punkt Peripherals/Monitor Settings öf­fnen. !!

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 Steck­brücken sollten 200 mm lang sein. Sie können diese z. B. bei Conrad beziehen (sie­he 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.

Balken-LED

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 ausge­tauscht 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. !!
!! Das Netzwerk wird ohne Sockel eingelötet. !!

RW5

8x10 kOhm

1

!! Einbaurichtung (Punkt) beachten. !!
!! Das Netzwerk wird ohne Sockel eingelötet. !!

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 flexi­blen Steckbrücke die Buchse XLEDB0 mit dem Anschluss der XTa7 (Taste S16). Wird die Taste ge­drü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 Dar­stellung an Port 2 ausgibt. Mit Hilfe der Taste „XTa0“ soll die Variable inkre­men­tiert, mit „XTa1“ dekre­men­tiert 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 Ver­bin­dungen zwischen XP2.0 – 7 und XLEDB0 – 7, XTa0 mit XP0.0 und XTa1 mit XP0.1 ge­steckt 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 vor­kommt, dass die LED um zwei anstatt um eins weitergezählt wird. Dieses Verhalten wird durch den Prellvorgang der Tasten erzeugt.

RS232-Verbindung

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 Schnittstel­le des LPC932/935 angebunden werden (siehe Abbildung 10). Sie benötigen ihn z. B. zum Testen mit dem EPM900-Board. Folgende Signalleitungen sind mit­ein­an­der 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 Span­nung an den einzelnen Pins des MAX232. Folgende Werte sollten an ihrem Baustein anlie­gen:

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 Pegel­umsetzung testen. Verbinden sie XS0 (Schalter 1) mit XP1.0. Liegt an P1.0 ein „Lowpe­gel“ (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 Kapi­tel 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 wer­den. !!

Nach dem Start des Pro­gramms soll­te das COM Ter­mi­nal den Text „Hello World“ empfangen (siehe Abbildung 14).

Zur Messung der Zeiten zwi­schen den gesendeten Bytes können sie das Pro­gramm Port­mon verwenden.  (www.Sysinternals.com)

Abbildung 14  COM Terminal (Empfang von „Hello World“)

Aktivierung des Reset-Eingangs

Um den Reset-Eingang zu aktivieren, muss das Bit RPE im UCFG1 auf „1“ gesetzt wer­den. Dies wird am einfachsten dadurch erreicht, indem die START900.a51 zum Pro­jekt 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 „Con­fi­gu­ra­tion 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 festge­stellt (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

Ansteuerung der Analog-Komperatoren, A/D-Wandlers

Sie haben mit den Aufbau des Experimentierboards alle Möglichkeiten, die beiden Analog-Komperatoren bzw. die A/D-Wandler (P89LPC935) zu testen. Die Konfigu­ra­tion 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 Kon­densator, 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 Mo­dus „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

Auswertung des Inkrementalgebers (Bourns)

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
2-reihig

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 Inkremental­ge­ber 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 Inkremen­tal­gebers (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 Drehrich­tung 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

LCD-Ansteuerung (Port 2)

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 anlie­gen. An Pin 3 kann eine Spannung zwischen 0–5 V in Abhängigkeit der Stellung des PT1 an­liegen. Entfernen sie die Spannungsversorgung des Experimentier­boards und stecken sie die LCD-Anzeige ein. Stecken sie nun die Spannungsversorgung wieder ein und stel­len 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
2 reihig

7

 

Tabelle 17  Bestückungsliste der LCD

Erstellen sie nun ein Programm, das eine Ausgabe auf dem LCD realisiert. Eine aus­führ­liche 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

OP-Ansteuerung

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 er­rech­net 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, Ab­schnitt „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 Aus­gangssignal 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 Jum­per 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 durch­füh­ren 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

I²C-Bus (allgemein I)

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
2 reihig

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 Pro­gram­mierung 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 Adres­sen 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“ abge­spei­chert (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 Win­dow“. Ü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

I²C-Bus I/O-Expander (PCF8574)

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 anlie­gen:

 

Pin

Pin

Spannung

1

16

5 V

2

16

5 V

3

16

5 V

8

16

5 V

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
2-reihig

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 Aus­­gänge beobachten zu können, werden diese an die LED-Zeile angeschlossen. Ver­bin­den 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-Bau­steins, 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 einge­baut. Die Ausgabe auf die LEDs lässt sich mit dieser Zeitver­zö­ge­rung 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

I²C-Bus 7-Segment LED-Ansteuerung (SAA1064)

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-Seg­ment 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 an­zeigt. 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 be­schrie­ben. !!

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

I²C-Bus Temperaturüberwachung (DS1621)

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 Tem­pe­ra­tur­be­reich ü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 pro­gram­mierbar.

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 Bau­steine 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

I²C-Bus (allgemein II)

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-Bau­stein die Adresse nicht mehr wissen. !!

Relais-Ansteuerung

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

Lautsprecher-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