172
1 Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de Michael Baldischweiler Dokumentation zum LPC-Experimentierboard V0.22 MEBA

Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

  • Upload
    vokien

  • View
    217

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

1

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Michael Baldischweiler

Dokumentation zum LPC-Experimentierboard

V0.22

MEBA

Page 2: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

2 Inhaltsverzeichnis

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Michael Baldischweiler Dokumentation zum LPC-Experimentierboard ©2004 MEBA 1. Auflage 2004 Satz: Michael Baldischweiler, MEBA-Mikrocomputertechnik, München Filmherstellung: - Produktion: - Diese Beschreibung und die beschriebenen Schaltungen, Verfahren und Programme wurden sorgfältig erstellt und geprüft. Trotzdem können Fehler und Irrtümer nicht aus-geschlossen werden. Verlag und Autor sind dankbar für Hinweise auf Fehler, über-nehmen jedoch keinerlei Verantwortung für die uneingeschränkte Richtigkeit auf An-wendbarkeit des Buchinhaltes. Jegliche juristische Verantwortung und Haftung wird da-her ausgeschlossen. Die Informationen in der vorliegenden Beschreibung werden ohne Rücksicht auf einen eventuellen Patentschutz veröffentlicht. Alle in diesem Buch vorkommenden Marken- und Handelsnamen sind Eigentum ihrer jeweiligen Besitzer und unterliegen den einschlä-gigen gesetzlichen Bestimmungen. Das Fehlen einer gesonderten Kennzeichnung bedeu-tet nicht, dass es sich dabei um einen freien Namen handelt. Die vorliegende Publikation ist urheberrechtlich geschützt. Alle Rechte vorbehalten, auch die der fotomechanischen Wiedergabe und Speicherung in elektronischen Medien. ISBN – Keil C51TM ist ein Warenzeichen von Keil Elektronik GmbH. Microsoft®, MS-DOS® und WindowsTM sind Warenzeichen von Microsoft. IBM®, PC® und PS/2® sind eingetragene Warenzeichen von International Business Machines Corporation. Intel®, MSC®51, MCS®251, ASM-51® sind eingetragene Warenzeichen von Intel Corporation.

Page 3: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Inhaltsverzeichnis 3

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Datum: Version: 03.04.2004 0.1 Folgende Kapitel fehlen noch:

1. Beschreibung zu DS1621 2. Beschreibung zu Relais- und Lautsprecheransteuerung

10.05.2004 0.11 Ergänzungen: 1. Bilder der Bestückungs-/Lötseite Version „light 1.3“ hinzuge-fügt.

12.05.2004 0.12 Stückliste aufgenommen. 16.05.2004 0.13 DCF77-Auswertung aufgenommen

Kapitel 2.3 „Betriebsarten der Portpins“ mit aufgenommen. Kapitel 2.5 „Kalibrierung des RC-Oscillator“ mit aufgenommen.

20.05.2004 0.14 Beschreibung zu DS1621 ergänzt. 23.05.2004 0.15 Kapitel 2.7 „Temperaturausgabe auf der 7-Segment LED“

Kapitel 2.8 (in Vorbereitung) 29.05.2004 0.16 Kapitel 2.8 fertig gestellt.

Kapitel 2.9 „Arbeiten mit dem Inkrementalgeber“ aufgenommen. 06.06.2004 0.17 Kapitel 2.10 „Arbeiten mit Timern“ aufgenommen.

Kapitel 2.13 „Ansteuerung von Schrittmotoren“ aufgenommen. 30.06.2004 Kapitel 2.4 „Erweiterte Library-Funktion für den I²C-Bus“

aufgenommen. 01.07.2004 0.18 Kapitel 2.14 „I²C-Bus EEPROMs“ aufgenommen. 06.07.2004 0.19 Kapitel 2.15 „Ansteuerung von Reed-Relais“ aufgenommen. 25.07.2004 0.20 Kapitel 2.10 und Kapitel 2.15 erweitert.

Index hinzugefügt 16.09.2004 0.21 Kapitel 2.16 und Kapitel 2.17 aufgenommen. 24.10.2004 0.22 Kapitel 2.17 erweitert.

Kapitel 3 Beschreibung der Library-Funktionen

Page 4: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

4 Inhaltsverzeichnis

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Inhaltsverzeichnis Inhaltsverzeichnis___________________________________________________ 4

1. Zu dieser Beschreibung __________________________________________ 8 1.1 Beschreibungskonventionen ____________________________________ 8 1.2 Glossar______________________________________________________ 8

2. Arbeiten mit dem LPC-Experimentierboard ________________________ 12 2.1 Allgemeines_________________________________________________ 12 2.2 Aufbau des LPC-Experimentierboards___________________________ 12

Allgemeines __________________________________________________________12 Spannungsversorgung___________________________________________________12 Taster und Schalter_____________________________________________________15 Balken-LED __________________________________________________________17 RS232-Verbindung _____________________________________________________19 Aktivierung des Reset-Eingangs ___________________________________________24 Ansteuerung der Analog-Komperatoren, A/D-Wandlers ________________________27 Auswertung des Inkrementalgebers (Bourns) _________________________________29 LCD-Ansteuerung (Port 2) _______________________________________________32 OP-Ansteuerung_______________________________________________________34 I²C-Bus (allgemein I) ___________________________________________________39 I²C-Bus I/O-Expander (PCF8574) _________________________________________42 I²C-Bus 7-Segment LED-Ansteuerung (SAA1064) _____________________________46 I²C-Bus Temperaturüberwachung (DS1621)__________________________________50 I²C-Bus (allgemein II)___________________________________________________53 Relais-Ansteuerung_____________________________________________________53 Lautsprecher-Ansteuerung _______________________________________________54

2.3 Betriebsarten der Portpins _____________________________________ 54 Arbeiten mit der Libraryfunktion „v_PortConfig()“ ____________________________58

2.4 Erstellen von Library-Modulen _________________________________ 60 Library für den I²C-Bus _________________________________________________60 Erweiterte Library-Funktionen für den I²C-Bus _______________________________64

2.5 Expansionsverbindung X2_____________________________________ 65 2.6 Kalibrierung des RC-Oscillators ________________________________ 66 2.7 Temperaturausgabe auf der 7-Segment LED _____________________ 71

Modulares Gestalten von Projekten ________________________________________73 Ausgabe der Zeichen A–F auf der 7-Segment LED ____________________________76

2.8 Tastaturabfrage mit dem I/O-Expander _________________________ 77

Page 5: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Inhaltsverzeichnis 5

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Auswertung mit Interrupt des PCF8574 _____________________________________78 2.9 Arbeiten mit dem Inkrementalgeber_____________________________ 79

Erstellen einer Library für den Inkrementalgeber ______________________________79 Steuerung des Cursors auf dem LCD-Display mit Hilfe des Inkrementalgebers________81 Menüführung mit dem Inkrementalgeber ____________________________________83

2.10 Arbeiten mit Timern__________________________________________ 88 Erstellen von Rechtecksignalen____________________________________________88 Konfigurieren der Timer mit Hilfe von Libraryfunktionen _______________________91

2.11 DCF77-Auswertung __________________________________________ 93 2.12 Speichererweiterung für Aufzeichnung (A/D-Wandler) _____________101 2.13 Ansteuerung von Schrittmotoren mit dem IMT901 ________________ 104

Auswertung des optischen Impulsgebers (HEDS-Familie) ______________________ 107 2.14 I²C-Bus EEPROMs _________________________________________ 107

Library-Funktionen für das Beschreiben von EEPROMs _______________________ 113 2.15 Ansteuerung von Reed-Relais __________________________________115 2.16 Library für die serielle Schnittstelle_____________________________ 120

Automatische Reloadberechnung _________________________________________ 124 Arbeiten mit der Funktion printf() ________________________________________ 126 Arbeiten mit der Funktion scanf()_________________________________________ 128

2.17 Arbeiten mit dem RTC_______________________________________ 129 Allgemeines _________________________________________________________ 129 Anpassungen für die Verwendung des externen Quarzes _______________________ 129 Arbeiten mit den Baugruppen MCB900/ EPM900 ____________________________ 130 Aufbau einer Software-Uhr______________________________________________ 130 Auswertung eines Alarms bzw. Schaltzeit ___________________________________ 141 Auswerten von mehreren Alarm-/Schaltzeiten _______________________________ 144

2.18 Leiterplatte ________________________________________________ 148 2.19 Stückliste __________________________________________________ 152 2.20 Artikelübersicht ____________________________________________ 153

3. Beschreibung der Library-Funktionen ____________________________ 154 3.1 Libraryfunktionen zu DS1621_Lib.c ____________________________ 154 3.2 Libraryfunktionen zu Encoder_Lib.c ___________________________ 155 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____________________ 155 3.4 Libraryfunktionen zu I2C_Lib.c _______________________________ 156 3.5 Libraryfunktionen zu PCF8574_Lib.c___________________________ 158 3.6 Libraryfunktionen zu PortConfig.c _____________________________ 159 3.7 Libraryfunktionen zu RS232DynLib.c __________________________ 160

Page 6: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

6 Inhaltsverzeichnis

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

3.8 Libraryfunktionen zu RTCLib.c ________________________________161 3.9 Libraryfunktionen zu SAA1064_Lib.c ___________________________ 163 3.10 Libraryfunktionen zu TimerLibrary.c___________________________ 163

4. Index _______________________________________________________ 165

5. Literaturverzeichnis ___________________________________________ 172

Page 7: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

7

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Kapitel 1 Zu dieser Beschreibung

Page 8: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

8 Kapitel 1

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

1. Zu dieser Beschreibung

1.1 Beschreibungskonventionen Um die Übersichtlichkeit für den Leser zu gewährleisten, wurden verschiedene Gestal-tungsformen verwendet. Somit haben sie einen leichteren Überblick und können schnel-ler an einzelne Informationen gelangen.

Ausdruck Bezeichner 1 Bezeichner n Ausdruck: Beschreibung des Ausdrucks Bezeichner 1: Beschreibung des Bezeichners 1 ... : ... Bezeichner n: Beschreibung des Bezeichners n

Abbildung 1 Syntaxaufbau

Die Syntax eines Befehls oder eines Steuerparameters wird mit einer Beschreibungsregel dargestellt (siehe Abbildung 1 dunkelgrau hinterlegt). Der Ausdruck, um den es sich han-delt, wird fett dargestellt. Ausdruck und Bezeichner werden im darunterliegenden Ab-schnitt erklärt (hellgrau hinterlegt). Im Buch sind die einzelnen Kapitel bzw. Abschnitte mit graphischen Symbolen versehen. Diese zeigen den Informationsgehalt an. Hier finden sie eine Erklärung zu allen im Buch verwendeten Symbolen.

Wenn sie dieses Symbol im Kapitel finden, dann sollten sie diese Informationen unbedingt beachten, um Fehler zu vermeiden.

Dieses Symbol wird als Tipp-Marker verwendet. Hier wird ein Verfahren oder ein Trick angegeben.

NEW Alle mit NEW gekennzeichneten Beschreibungen sind ab Version 6.0 enthal-ten.

Tabelle 1 Erklärung der verwendeten Symbole

1.2 Glossar Erklärung technischer Begriffe: Adresse: Zahl oder symbolischer Name zur Identifizierung eines Registers, Speicher-

worts, Speicherbereichs, Eingabe- / Ausgabe-Kanals. ANSI-C: Eine Definitionsnorm für die Programmiersprache C. ANSI-C wurde 1989

vom American National Standards Institute definiert. Anweisung: Eine Anweisung kann eine Operation oder ein Funktionsaufruf sein. Jede

Anweisung wird mit einem Semikolon abgeschlossen. Argument: Werden bei einem Funktionsaufruf Werte übergeben, so spricht man von

einer Argumentübergabe. A51-Assembler: Ein Programm zur Übersetzung eines in Assemblersprache geschrie-

benen Programms in ein auf dem Zielprozessor ablauffähiges Maschinenprogramm. CISC-Architektur (Complex Instruction Set Computer). Typisch für diese Architektur

ist die große Anzahl von unterschiedlichen Befehlen und Befehlsgruppen.

Page 9: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Zu dieser Beschreibung 9

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Compiler: Ein Programm zum Übersetzen von Sourcemodulen in einen Objektcode. Cross-Compiler: Ein Compiler, der aus Sourcemodulen einen Objektcode für andere

Prozessoren erzeugt. DCF77: Die Physikalisch-Technische Bundesanstalt Braunschweig betreibt eine Cäsium-

Atomuhr. Diese Uhrzeit wird im DCF Format kodiert und über einen Langwellensen-der ausgesendet. Das vom Sender ausgestrahlte Signal ist impulskodiert.

Definition: Bei der Definition einer Variablen, Funktion usw. wird vom C-Compiler Speicherplatz, z. B. im RAM oder ROM, reserviert.

Deklaration: Einem Sourcemodul wird eine Variable oder Funktion bekanntgegeben. Bei einer Deklaration wird kein Speicherplatz reserviert.

Funktion: Eine Funktion ist eine in sich abgeschlossene Operation. Die Funktion wird über ein CALL aufgerufen und mit einem RET abgeschlossen.

Harvard-Architektur: Die Speicherbereiche von ROM und RAM werden mit eigenen Befehlsgruppen verarbeitet. ROM und RAM können denselben Adressraum verwen-den.

von-Neumann-Architektur (VNM): Die Speicherbereiche ROM und RAM werden mit derselben Befehlsgruppe abgearbeitet.

H-File (Header-File): In diesem File stehen alle Definitionen und Deklarationen, die ein Programm benötigt.

IDE (Integrated Development Environment): Unter einer IDE wird eine integrierte Entwicklungsumgebung verstanden, die alle Tools für die Entwicklung einer bestimmten Software beinhaltet.

Ini-File: Mit diesem File können Kommandos im Simulator über das Command-Fenster eingelesen werden.

I-File (Preprint-File): Zusätzliches Output-File des C51-Compilers, wenn der Steuerpa-rameter PREPRINT verwendet wurde.

ISD (In System Debugging): Bei diesem Debug-Verfahren wird die Software für die Steuerung des Debuggers mit zum Sourcecode hinzugebunden.

ISP (In System Programing): Während der Programmlaufzeit kann im Programm-FLASH Änderungen vorgenommen werden.

ISR (Interrupt Service Routine): Diese Funktion wird von der Hardware aufgerufen, da sie an einer speziellen Startadresse (z.B. C:0x0003) liegt.

BL51-Linker: Ein Programm zum Binden von OBJ-Files zu einem ablauffähigen Pro-gramm.

LNK-File: Eingabefile für den Linker. In diesem sind die Informationen enthalten, welche OBJ-Files und welche Libraries mit hinzugebunden werden sollen. Zudem können in ihm Angaben enthalten sein, wie die einzelnen Programmsegmente im Speicher abzulegen sind.

LST-File: Compiler und Assembler liefern als Output ein File mit der Erweiterung LST. Dieses File enthält in Abhängigkeit von Steuerparametern Informationen über den Verlauf einer Compilierung bzw. Assemblierung.

main(): Jedes C-Programm wird mit dieser Funktion gestartet. Dies gilt auch für die C51-Umgebung.

Makro: Ein im Sourcecode erzeugter Ausdruck, der während des Compilerlaufes in einen Sourcecode expandiert wird.

Page 10: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

10 Kapitel 1

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

M51-File: Der BL51 Linker erzeugt beim Linken ein File mit der Erweiterung M51. In ihm sind alle Informationen über die Aufteilung des Adressraumes sowie den be-nötigten Speicherbereich vorhanden.

OBJ-File: Der Output von Compiler und Assembler. Dieser Output wird dem Linker als Input übergeben.

Operation: Arithmetischer oder logischer Ausdruck OPT-File: Das OPT-File ist Bestandteil eines µVision2/3 Projekts. Es enthält alle Ein-

stellungen für den Simulator, ROM-Monitor bzw. Emulator. #pragma Steuerparameter: Sie beeinflussen die Tools, z. B. C51-Compiler bei der

OBJ-Code Erstellung oder den BL51-Linker bei der Adressvergabe. Diese Steuerpara-meter sind Schlüsselwörter.

PAP (Programm Ablauf Plan): Graphische Darstellung für ein Programm bzw. für eine Programmsequenz.

PC (Program Counter): Er enthält die Speicheradresse des Programmspeichers, die im Mikrocontroller ausgeführt wird.

RAM: Random Access Memory RISC (Reduced Instruction Set Computer): Diese Architektur verwendet nur einfache

Befehlsgruppen. Jeder Befehl wird in einem Maschinenzyklus ausgeführt. ROM: Read Only Memory RTC (Real Time Clock): Der RTC enthält Register mit denen es möglich ist es eine Uhr

aufzubauen. Schlüsselwort: Der C-Compiler hat einige englische Wörter reserviert. Diese dürfen

nicht anderweitig verwendet werden. SFR (Special Function Register): Über diese Register kann die Peripherie des jeweiligen

8051-Derivats angesprochen werden. Simulator: Der Simulator ist ein Programm, das einen Zielprozessor mittels Software

nachbildet. Es können damit Programme ohne die Zielhardware getestet werden. Sourcemodul: Ein File, in dem der Sourcecode enthalten ist. Ein Programm wird meist

in mehrere Module aufgeteilt. Ein Modul sollte nicht mehr als fünf DIN A4 Seiten Sourcecode enthalten, da alles darüber Hinausgehende unübersichtlich wird.

SRC-File: Über den Steuerparameter SRC erzeugt der C51-Compiler als Output ein Assemblerfile. Dieses Modul hat die Extension SRC und kann direkt als Input für den A51 Assembler genommen werden.

Target: Das Target enthält den Zielprozessor (8051-Derivat) und die Tool spezifischen Einstellungen.

Tool-Chain: Sie enthält die Programmierwerkzeuge (C-Compiler, Assembler, Linker) für das ausgewählte Mikrocontroller Derivat.

uv2-File: Dieses File enthält alle Projektinformationen. XRAM: eXternal Random Access Memory

Page 11: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Kapitel 2 Arbeiten mit dem LPC-Experimentierboard

Page 12: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

12 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

2. Arbeiten mit dem LPC-Experimentierboard

2.1 Allgemeines Um die Beispiele im LPC900-Buch austesten bzw. weitere Übungen durchführen zu können, ist das LPC-Experimentierboard entstanden. Die Beschreibung bezieht sich auf das Board mit der Bezeichnung „LPC-Experimentierboard-light V1.3“. Die verwendete Hardware wurde so ausgewählt, dass sie im Einzelhandel (z. B. über Conrad) erhältlich ist. Jeder geübte Hobby-Elektroniker kann die Bauteile selbst einlöten. Das LPC-Experimentierboard verfügt über eine eigene Spannungsversorgung. Die Verbindung zwischen dem MCB900/EPM900 und dem LPC-Experimentierboard erfolgt über ein 28-poliges Flachbandkabel. Dieses Kabel ist Bestandteil des EPM900-Kits.

!! Das LPC-Experimentierboard kann auch für jeden anderen Controller eingesetzt werden. !!

2.2 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.

!! 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 Leiterplattenrand zeigen. !!

Abbildung 2 Spannungsversorgung LPC-Experimentierboard (Stromlaufplan)

Page 13: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 13

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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 XVCC1 2mm Buchse 1

Optional kann eine Pfostenbuchse eingelötet werden.

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

Page 14: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

14 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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

!! Überprüfen sie immer zuerst den korrekten Anschluss zwischen dem LPC-Experi-mentierboard und dem verwendeten Board (EPM900 bzw. MCB900), bevor sie die Spannung an die Boards anlegen. Ansonsten können beide Boards beschädigt wer-den. !!

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

Page 15: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 15

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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.

Page 16: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

16 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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

!! 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-sonsten 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 (sie-he Tabelle 81, Seite 153). 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

Page 17: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 17

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

„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 Non-Inver-ting Line-Driver 74HC541 (siehe Abbildung 8). Die Balken-LED wird über ein Wider-stands-Netzwerk (8x330 Ohm) auf VCC gelegt. Damit der 74HC541 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

!! Die Widerstandsnetzwerke werden ohne Sockel bestückt. !!

Page 18: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

18 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Abbildung 9 Schalt-/Bestückungsplan für Balken-LED

Position Wert/Bez. Anzahl Beschreibung D4 20pol.

Sockel 1 !! Einbaurichtung beachten. !!

D4 74HC541 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 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 Dar-stellung 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 Verbin-dungen 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) {

Page 19: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 19

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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 Schnittstelle des LPC932/935 angebunden werden (siehe Abbildung 10). Sie benötigen ihn z. B. zum Testen mit dem EPM900-Board. Folgende Signalleitungen sind miteinan-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.

Page 20: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

20 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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

Page 21: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 21

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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).

Page 22: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

22 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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

Page 23: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 23

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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

!! 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.

!! 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. !!

Page 24: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

24 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Nach dem Start des Pro-gramms sollte das COM Ter-minal den Text „Hello World“ empfangen (siehe Abbildung 14). Zur Messung der Zeiten zwi-schen den gesendeten Bytes können sie das Programm Portmon 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 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

Page 25: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 25

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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

Page 26: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

26 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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

Page 27: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 27

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

{ 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 Konfigura-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

Page 28: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

28 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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

Page 29: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 29

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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

Page 30: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

30 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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 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 Inkremen-talgebers (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 ).

Page 31: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 31

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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:

Page 32: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

32 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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 anliegen. Entfernen sie die Spannungsversorgung des Experimentierboards 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.

Page 33: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 33

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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

Page 34: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

34 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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 ausfü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.

!! 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 errechnet sich wie folgt:

Page 35: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 35

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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, XDA2mm

Buchsen 3

Tabelle 19 Bestückungsliste für den LM258

Page 36: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

36 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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)

Page 37: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 37

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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)

Page 38: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

38 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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 durchfü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

Page 39: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 39

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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)

Page 40: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

40 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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 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 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“ 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;

Page 41: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 41

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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.

Page 42: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

42 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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.

Page 43: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 43

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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

Page 44: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

44 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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ö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++; }

Page 45: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 45

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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;

Page 46: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

46 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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

Page 47: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 47

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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, ).

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

Page 48: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

48 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

{ 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)

Page 49: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 49

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

{ 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;

Page 50: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

50 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

} }

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 Temperatur-bereich ü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;

Page 51: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 51

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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); }

Page 52: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

52 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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;

Page 53: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 53

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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)

!! Dieses Testprogramm können sie z. B. auch verwenden, wenn sie bei einem I²C-Baustein 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.

Page 54: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

54 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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.

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

2.3 Betriebsarten der Portpins Die Portpins der LPC900-Reihe unterstützen vier verschiedene Betriebsarten. Eine ge-naue Funktionsbeschreibung der Portpins und deren Betriebsarten finden sie im Buch

Page 55: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 55

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Kapitel 10.6 „Aufbau der Ports“ [3]. Da die Portpins selbst mit unterschiedlichen Funk-tionen belegt sind, sollte die Umschaltung auf die jeweilige Betriebsart immer nur auf das benötigte Portpin und nicht auf den gesamten Port durchgeführt werden. Die Funktion „v_PortConfig()“ ermöglicht eine Konfiguration der Portpins. Im ersten Parameter wird der Port, im zweiten der Pin und im dritten die einzustellende Betriebsart übergeben (siehe Listing 17, ). Damit die Übergabeparameter besser gelesen werden können, wurde der Aufzählungstyp enum für die einzelnen Parameter verwendet (siehe ). Aufbau und Funktionsweise des Aufzählungstyps enum können sie im Kapitel 13.4 [1] nachlesen. Sollen alle Portpins eines Ports auf eine Betriebsart gesetzt werden, wird die Definition „AllPins“ verwendet (siehe ). Sollen mehrere Portpins auf eine Betriebsart gesetzt werden, kann dies mit einer Oder-Verknüpfung bei der Übergabe erfolgen (siehe

). Erstellen sie das Projekt aus Tabelle 35 und fügen das Programm aus Listing 17 in das Sourcemodul ein.

Projektname Verzeichnis Verwendete Sourcemodule PortConfig Test_PortConfig TestPortConfig.c

Tabelle 35 Projekt PortConfig

#include <REG932.H> enum enPinADDR{Pin0 = 0x01, Pin1 = 0x02, Pin2 = 0x04, Pin3 = 0x08, Pin4 = 0x10, Pin5 = 0x20, Pin6 = 0x40, Pin7 = 0x80, AllPins = 0xFF}; enum enPort {Port0 = 0, Port1, Port2, Port3}; enum enConfig {BiDir = 0, PushPull, InpOnly, OpenDrain}; void v_PortConfig(unsigned char ucPortAddr, unsigned char ucPin, unsigned char Config) { if (Config == BiDir) { ucPin ^= 0xFF; switch(ucPortAddr) { case Port0: P0M1 = P0M1 & ucPin; P0M2 = P0M2 & ucPin; break; case Port1: P1M1 = P1M1 & ucPin; P1M2 = P1M2 & ucPin; break; case Port2: P2M1 = P2M1 & ucPin; P2M2 = P2M2 & ucPin; break; case Port3: P3M1 = P3M1 & ucPin; P3M2 = P3M2 & ucPin; break; default: break; } } else if (Config == PushPull) { switch(ucPortAddr) { case Port0: P0M1 = P0M1 & (ucPin ^ 0xFF);

Page 56: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

56 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

P0M2 = P0M2 | ucPin; break; case Port1: P1M1 = P1M1 & (ucPin ^ 0xFF); P1M2 = P1M2 | ucPin; break; case Port2: P2M1 = P2M1 & (ucPin ^ 0xFF); P2M2 = P2M2 | ucPin; break; case Port3: P3M1 = P3M1 & (ucPin ^ 0xFF); P3M2 = P3M2 | ucPin; break; default: break; } } else if (Config == InpOnly) { switch(ucPortAddr) { case Port0: P0M1 = P0M1 | ucPin; P0M2 = P0M2 & (ucPin ^ 0xFF); break; case Port1: P1M1 = P1M1 | ucPin; P1M2 = P1M2 & (ucPin ^ 0xFF); break; case Port2: P2M1 = P2M1 | ucPin; P2M2 = P2M2 & (ucPin ^ 0xFF); break; case Port3: P3M1 = P3M1 | ucPin; P3M2 = P3M2 & (ucPin ^ 0xFF); break; default: break; } } else // Open-Drain { switch(ucPortAddr) { case Port0: P0M1 = P0M1 | ucPin; P0M2 = P0M2 | ucPin; break; case Port1: P1M1 = P1M1 | ucPin; P1M2 = P1M2 | ucPin; break; case Port2: P2M1 = P2M1 | ucPin; P2M2 = P2M2 | ucPin; break; case Port3: P3M1 = P3M1 | ucPin; P3M2 = P3M2 | ucPin; break; default: break; } } } void main(void) { v_PortConfig (Port0, AllPins, BiDir); v_PortConfig (Port2, Pin4 | Pin 7, PushPull); v_PortConfig (Port0, Pin2, InpOnly); v_PortConfig (Port2, Pin5, OpenDrain); while(1); }

Page 57: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 57

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Listing 17 Inhalt von TestPortConfig.c Da die Konfiguration der Portpins bei jedem Projekt wieder benötigt wird, wird die Funktion „v_PortConfig()“ in ein eigenes Sourcemodul ausgelagert (siehe Listing 18). Die Funktionsdeklaration sowie die Aufzählungstypen werden in einem eigenen H-File abgespeichert (siehe Listing 19). Damit die Aufzählungstypen im Sourcemodul PortConfig.c für den C51-Compiler bekannt sind, muss das H-File mit eingefügt werden (siehe Listing 18, ). Speichern sie diese beiden Dateien im Verzeichnis Library ab.

Projektname Verzeichnis Verwendete Sourcemodule - Library PortConfig.c

Tabelle 36 Projekt -

#include <REG932.H> #include <PortConfig.H> void v_PortConfig(unsigned char ucPortAddr, unsigned char ucPin, unsigned char Config) { if (Config == BiDir) { ucPin ^= 0xFF; switch(ucPortAddr) { case Port0: P0M1 = P0M1 & ucPin; P0M2 = P0M2 & ucPin; break; case Port1: P1M1 = P1M1 & ucPin; P1M2 = P1M2 & ucPin; break; case Port2: P2M1 = P2M1 & ucPin; P2M2 = P2M2 & ucPin; break; case Port3: P3M1 = P3M1 & ucPin; P3M2 = P3M2 & ucPin; break; default: break; } } else if (Config == PushPull) { switch(ucPortAddr) { case Port0: P0M1 = P0M1 & (ucPin ^ 0xFF); P0M2 = P0M2 | ucPin; break; case Port1: P1M1 = P1M1 & (ucPin ^ 0xFF); P1M2 = P1M2 | ucPin; break; case Port2: P2M1 = P2M1 & (ucPin ^ 0xFF); P2M2 = P2M2 | ucPin; break; case Port3: P3M1 = P3M1 & (ucPin ^ 0xFF); P3M2 = P3M2 | ucPin; break; default: break; } } else if (Config == InpOnly)

Page 58: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

58 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

{ switch(ucPortAddr) { case Port0: P0M1 = P0M1 | ucPin; P0M2 = P0M2 & (ucPin ^ 0xFF); break; case Port1: P1M1 = P1M1 | ucPin; P1M2 = P1M2 & (ucPin ^ 0xFF); break; case Port2: P2M1 = P2M1 | ucPin; P2M2 = P2M2 & (ucPin ^ 0xFF); break; case Port3: P3M1 = P3M1 | ucPin; P3M2 = P3M2 & (ucPin ^ 0xFF); break; default: break; } } else // Open-Drain { switch(ucPortAddr) { case Port0: P0M1 = P0M1 | ucPin; P0M2 = P0M2 | ucPin; break; case Port1: P1M1 = P1M1 | ucPin; P1M2 = P1M2 | ucPin; break; case Port2: P2M1 = P2M1 | ucPin; P2M2 = P2M2 | ucPin; break; case Port3: P3M1 = P3M1 | ucPin; P3M2 = P3M2 | ucPin; break; default: break; } } }

Listing 18 Inhalt von PortConfig.c

enum enPinADDR{Pin0 = 0x01, Pin1 = 0x02, Pin2 = 0x04, Pin3 = 0x08, Pin4 = 0x10, Pin5 = 0x20, Pin6 = 0x40, Pin7 = 0x80, AllPins = 0xFF}; enum enPort {Port0 = 0, Port1, Port2, Port3}; enum enConfig {BiDir = 0, PushPull, InpOnly, OpenDrain}; extern void v_PortConfig(unsigned char ucPortAddr, unsigned char ucPin, unsigned char Config);

Listing 19 Inhalt von PortConfig.h

Arbeiten mit der Libraryfunktion „v_PortConfig()“ Soll die Libraryfunktion „v_PortConfig()“ in ein Projekt aufgenommen werden, muss das Sourcemodul „Portconfig.c“ ebenfalls in das Projekt aufgenommen werden. Damit der C51-Compiler das H-File „PortConfig.h“ findet, muss das Verzeichnis, in dem das H-File abgespeichert ist, im Window „Options for Target“, Reiter „C51“ im Eingabefeld „Include Paths“ angegeben werden (siehe Abbildung 43). Erstellen sie das Projekt aus Tabelle 57. Der C51-Compiler sowie der BL51-Linker müssen ohne Fehler durchlaufen.

Page 59: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 59

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Wenn sie das Projekt anschließend durchsteppen, müssen die LEDs an Port 2 den Zustand wechseln.

Abbildung 43 Window Options for Target, Reiter C51

Projektname Verzeichnis Verwendete Sourcemodule Test_ConfigLib Test_PortConfigLib TestPortConfigLib.c

..\Library PortConfig.c Tabelle 37 Projekt Test_ConfigLib

#include <REG932.H> #include <PortConfig.h> void main(void) { v_PortConfig(Port2, AllPins, BiDir); while(1) { P2 = 0x00; P2 = 0xFF; } }

Listing 20 Inhalt von TestPortConfigLib.c

Die Funktion „v_PortConfig()“ ist gegenüber einer Zuweisung (siehe Listing 21) im Codeverbrauch größer. Dennoch sollte berücksichtigt werden, dass die Lesbarkeit und die Wartung von Programmen eine entscheidende Rolle bei der Erstellung und Weiter-entwicklung spielen. Zudem wird die Fehlermöglichkeit eingeschränkt, da nur noch der Portpin angegeben wird und die logischen Verknüpfungen in der Funktion passend auf die jeweiligen SFR durchgeführt werden.

P2M1 = 0x00; P2M2 = 0x00;

Listing 21 Einstellung der Betriebsart Quasi-Bidir mit Hilfe der direkten Zuweisung

Page 60: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

60 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

2.4 Erstellen von Library-Modulen Im vorangegangenen Abschnitt wurde die Funktion „v_PortConfig()“ in ein eigenes Sourcemodul ausgelagert und mit einem eigenen H-File versehen. Die Dateien wurden im Verzeichnis Library gespeichert. Somit kann diese Funktion auch von anderen Pro-jekten verwendet werden. Dieses Verfahren hat zudem den Vorteil, dass eine Änderung bzw. Fehlerbeseitigung nur einmal durchgeführt werden muss.

Library für den I²C-Bus Wie sie den Projekten Test_SAA1064.uv2 (siehe Seite 47), Test_DS1621.uv2 (siehe Seite 50) und Test_PCF8574.uv2 (siehe Seite 44) entnehmen können, werden die Funktionen „v_SetNextI2CVal()“, „v_StartI2CFrans()“, „v_WaitI2CFinish()“, „v_InitI2C()“, die ISR „v_I2CInterrupt()“ und die Struktur „Slave“ immer wieder für die Programmierung des I²C-Busses benötigt. Erstellen sie ein Projekt, in dem die oben aufgezählten Funktionen im Sourcemodul „I2C_LIB.c“ abgespeichert sind, sowie ein H-File mit den Funktions- und Variablende-klarationen. Das Sourcemodul „I2C_LIB.c“ und das H-File „I2C_LIB.h“ sollen im Ver-zeichnis „Library“ abgespeichert werden. Das Testprogramm soll die Zahl „2004“ auf den vier Segmenten ausgeben.

!! Vergessen sie nicht, den Eintrag „..\library“ im Eingabefeld des C51-Compilers vorzunehmen (siehe Abbildung 43, Seite 59). !!

Die Variable „btI2cFinished“ und „ucI2Coff” werden mit dem Schlüsselwort static ver-sehen (siehe Listing 22, und ). Dieses Schlüsselwort bewirkt, dass die Variable nicht von einem anderen Sourcemodul aus angesprochen werden kann. Das Schlüsselwort static gehört zu den Definitionen der Gültigkeitsbereiche. Eine ausführliche Beschrei-bung zu allen Schlüsselwörtern für die Gültigkeitsbereiche finden sie im Kapitel 6 „Gültigkeitsbereiche von Variablen“ [1].

Projektname Verzeichnis Verwendete Sourcemodule I2C_LIB Test_I2C_Lib Test_I2C_Lib.c

..\Library I2C_LIB.c Tabelle 38 Projekt I2C_Lib

#include <REG932.H> #include <I2C_LIB.H> struct stI2C Slave; static 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 EI2C = 1; // I2C Interrupt freigeben }

Page 61: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 61

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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); } static 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; // Stoppbedingung setzen (STO =1) } break; case 0x20: // Status: "SLA+W gesendet, NACK empfangen" I2CON = 0x54; // Stoppbedingung setzen (STO =1) break; case 0x40: // Status: "SLA+R gesendet, ACK empfangen" if (ucI2COff < (Slave.DataLen )) { if (ucI2COff < (Slave.DataLen) )

Page 62: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

62 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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 22 Inhalt von I2C_LIB.c

// Strukturdeklaration struct stI2C { unsigned char Adr; unsigned char DataLen; unsigned char Val[10]; }; // Variablendeklarationen extern struct stI2C Slave; // Funktionsdeklarationen extern v_InitI2C(void); extern v_SetNextI2CVal(unsigned char ucVal); extern v_StartI2CTrans(void); extern void v_WaitI2CFinish(void);

Listing 23 Inhalt von I2C_LIB.h

#include <REG932.H> #include <I2C_LIB.H>

Page 63: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 63

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

enum enSAASEG {NULL = 0x3F, EINS = 0x06, ZWEI = 0x5B, DREI = 0x4F, VIER = 0x66, FUENF = 0x6D, SECHS = 0x7D, SIEBEN = 0x07, ACHT = 0x7F, NEUN = 0x67, PUNKT = 0x80}; void main(void) { v_InitI2C(); EA = 1; // allgemeine Interruptsperre aufheben Slave.Adr = 0x70; // Adresse SAA1064 v_SetNextI2CVal(0); // Subadresse auf 0 (Control-Byte) v_SetNextI2CVal(0xF7); // dynamic alternating mode v_StartI2CTrans(); v_WaitI2CFinish(); v_SetNextI2CVal(1); // Ausgabe der Zahl 2004 v_SetNextI2CVal(ZWEI); v_SetNextI2CVal(NULL); v_SetNextI2CVal(NULL); v_SetNextI2CVal(VIER); v_StartI2CTrans(); v_WaitI2CFinish(); while(1); }

Listing 24 Inhalt von Test_I2C_Lib.c

Erweitern sie das Projekt so, dass die Initialisierung der Portpins in „v_InitI2C()“ mit Hilfe der Funktion „v_PortConfig()“ durchgeführt wird. Fügen sie das Sourcemodul PortConfig.c zum Projekt hinzu (siehe Tabelle 39). Im Sourcemodul I2C_Lib.c muss das H-File PortConfig.h eingebunden (siehe Listing 25,

) und in der Funktion „v_InitI2C()“ die Oder-Verknüpfungen auf den Port 1 gegen den Funktionsaufruf „v_PortConfig()“ ausgetauscht werden (siehe ).

Projektname Verzeichnis Verwendete Sourcemodule I2C_LIB Test_I2C_Lib Test_I2C_Lib.c

..\Library I2C_LIB.c, PortConfig.c Tabelle 39 Projekt I2C_Lib

#include <REG932.H> #include <I2C_LIB.H> #include <PortConfig.H> struct stI2C Slave; static bit btI2cFinished; v_InitI2C(void) { // SDA und SCL als Open-Drain konfigurieren v_PortConfig(Port1, Pin3 | Pin4, OpenDrain); I2SCLH = 19; // I2C-Geschwindigkeit ~100 KHz I2SCLL = 19;

Page 64: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

64 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

I2CON = 0x44; // I2C-Hardware aktivieren EI2C = 1; // I2C Interrupt freigeben }

Listing 25 Auszug aus von I2C_Lib.c

Erstellen sie die Funktion „v_StartI2CandWait()“ (siehe Listing 26). Sie soll die Funk-tionalität der Funktionen „v_StartI2CTrans()“ und „v_WaitI2CFinish()“ enthalten. Der Vorteil dieser Funktion ist, dass gleich auf das Ende der I²C-Übertragung gewartet wird. Der Nachteil dieser Funktion besteht darin, dass das Programm in der Zwischenzeit keine anderen Aufgaben durchführen kann.

void v_StartI2CandWait(void) { btI2cFinished = 0; I2CON = 0x64; // Startbedingung setzen while (btI2cFinished == 0); // Auf Stoppdingung warten }

Listing 26 Auszug aus von I2C_Lib.c

Erweiterte Library-Funktionen für den I²C-Bus Für das Beschreiben und Auslesen von I²C-Bausteinen ist es zweckmäßig, eigene Funk-tionen zu erstellen, die das Beschreiben der I²C-Struktur, das Setzen der Startadresse sowie der Werte übernehmen. Das Beschreiben eines I²C-Bausteins übernimmt die Funktion „uc_Data2I2C()” (siehe Listing 27, ), das Auslesen von Werten die Funktion „uc_I2C2Data()“ (siehe ). Eine ausführliche Beschreibung der Funktionsweise dieser Funktionen finden sie im Kapitel 11 I²C-Bus [2]. Sollen mehr als 8 Werte auf dem I²C-Baustein geschrieben werden, muss die Größe des Arrays in der Strukturdefinition „stI2C“ (siehe Listing 23, ) vergrößert werden. Ist die Offset-Adresse im verwendeten Baustein nur ein Byte groß, haben sie folgende Möglichkeiten: 1. Wenn sie nur I²C-Bausteine verwenden, die über eine 1-Byte Offset-Adresse ange-

sprochen werden, können sie den zweiten Übergabeparameter auf den Datentyp „unsigned char“ ändern und die Zeile mit der MSB-Zuweisung (siehe ) löschen.

2. Verwenden sie I²C-Bausteine, die eine 1-Byte Adresse benötigen, müssen sie eine zusätzliche Funktion definieren, die diese unterstützt oder einen weiteren Parameter mit übergeben, der diese Information enthält.

#include <I2C_LIB.H> #include <I2C_EEPROM_LIB.h> unsigned char uc_Data2I2C(unsigned char ucI2CDev, unsigned int uiI2CAddr, unsigned char *pucSrc) { unsigned char ucLen = *pucSrc; pucSrc++; Slave.Adr = ucI2CDev; v_SetNextI2CVal(uiI2CAddr/256); // Subadresse (MSB) v_SetNextI2CVal((unsigned char)uiI2CAddr); // Subadresse (LSB)

Page 65: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 65

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

while (ucLen--) { v_SetNextI2CVal(*pucSrc); pucSrc++; } v_StartI2CandWait(); return (ucI2CError); } unsigned char uc_I2C2Data(unsigned char ucI2CDev, unsigned int uiI2CAddr, unsigned char *pucSrc) { unsigned char ucLen = *pucSrc; pucSrc++; Slave.Adr = ucI2CDev; // Startadresse setzen v_SetNextI2CVal(uiI2CAddr/256); // Subadresse (MSB) v_SetNextI2CVal((unsigned char)uiI2CAddr); // Subadresse (LSB) v_StartI2CandWait(); // Werte aus dem EEPROM auslesen Slave.Adr = Slave.Adr | 1; // Adresse AT24C256 + RD Slave.DataLen = ucLen; // ein Bytes wird gelesen v_StartI2CandWait(); // Werte in ResBuf kopieren if (ucI2CError == I2C_OK) { unsigned char ucLoop; for (ucLoop = 0; ucLoop < ucLen; ucLoop++) { *pucSrc = Slave.Val[ucLoop]; } } return (ucI2CError); }

Listing 27 Auszug aus von I2C_EEPROM_Lib.c

2.5 Expansionsverbindung X2 Über die 34-polige Verbindung des Experimentierboards kann eine weitere Leiterplatte bzw. ein Flachbandkabel angeschlossen werden. Werden Leiterplatten aufgesteckt, so wird eine Buchse in X2 eingelötet, bei Verwendung eines Flachbandkabels eine Stift-leiste.

Page 66: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

66 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Abbildung 44 Bestückungsplan für die Expansionsverbindung X2

X2, Pin 1 2 3 4 5 6 7 8 9 10 11 12 Bezeichnung P0.0 P0.1 P0.2 P0.3 P0.4 P0.5 P0.6 P0.7 Vcc GND P1.0 P1.1

X2, Pin 13 14 15 16 17 18 19 20 21 22 23 24 Bezeichnung P1.2 P1.3 P1.4 P1.5 P1.6 P1.7 Vcc GND P2.0 P2.1 P2.2 P2.3

X2, Pin 25 26 26 28 29 30 31 32 33 34 Bezeichnung P2.4 P2.5 P2.6 P2.7 Vcc GND P3.0 P3.1 V3.3 V3.3

Tabelle 40 Belegung der Expansionsverbindung X2

Position Wert/Bez. Anzahl Beschreibung X2 34-pol.

Sockel 1

C18 100 n 1 Tabelle 41 Bestückungsliste für Expansionsverbindung X2

2.6 Kalibrierung des RC-Oscillators Der interne RC-Oscillator arbeitet mit einer internen Frequenz von 7.3728 MHz und einer Toleranz von +/-2,5 %. Damit die Timer mit zeitlich korrekten Reloadwerten arbeiten, muss die Abweichung des RC-Oscillators ermittelt werden. Erstellen sie ein Programm, in dem der Timer 0 in der Betriebsart 1 und mit einem Re-loadwert von 1 ms arbeitet. Aufbau und Funktionsweise des Timers sind in Kapitel 10.10 [3] beschrieben. Die ISR des Timer 0 soll den Zustand des Portpins P1.0 wechseln. Das Rechtecksignal von P1.0 wird als Messkriterium für die Toleranz verwendet. Um die Kalibrierung zu vereinfachen, wird die Variable „ucValue“ für den Reloadwert verwen-det, die mit Hilfe des Inkrementalgeber beeinflusst wird. Wird der Inkrementalgeber im Uhrzeigersinn gedreht, wird „ucValue“ um „1“ erhöht, ansonsten um „1“ erniedrigt. Er-stellen sie das Projekt aus Tabelle 42.

Projektname Verzeichnis Verwendete Sourcemodule CallRCOsci Test_CallRCOsci TestCalibration.c,

..\Library PortConfig.c Tabelle 42 Projekt CallRCOsci

#include <REG932.H>

Page 67: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 67

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

#include <PortConfig.H> // Bourns EPS1D-F19-AE0036 (2-bit gray code) sbit EncSwitch = P0^6; // Taster (Jumper 7) sbit EncChA = P0^5; // Kanal A (Jumper 8) sbit EncChB = P0^7; // Kanal B (Jumper 9) sbit sb1ms = P1^0; unsigned int ucValue = 0xF196; // Reloadvalue 1 ms unsigned char ucActEncVal; // akt. Position des Inkrementalgebers void v_InitTimer0_1ms(void) { // Timer 0 für 1msec initialisieren TMOD = TMOD | 0x01; TL0 = (unsigned char) ucValue; TH0 = ucValue/256; TF0 = 0; ET0 = 1; EA = 1; } void v_InitEncoder(void) { 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 } void main(void) { v_PortConfig(Port1, Pin0, BiDir); // P2 als Quasi-bidir. v_InitTimer0_1ms(); TR0 = 1; // Timer 0 starten v_InitEncoder(); while(1); } void v_Timer0Int(void) interrupt 1 using 1 { TL0 = (unsigned char)ucValue; TH0 = ucValue/256; sb1ms = !sb1ms; } // ISR des Keyboard void v_KeyboardInt(void) interrupt 7 {

Page 68: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

68 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

KBPATN = P0 & 0xE0; // Neues Keyboard-Pattern setzen if (ucActEncVal != (P0 & 0xA0)) // Abfrage, ob Aenderung beim { // Inkrementalgeber 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 Positon } // des Inkrementalgebers KBCON = 0x00; // Loeschen des Keyboard Flags }

Listing 28 Inhalt von TestCalibration.c

Erweitern sie das Programm so, dass der aktuelle Reloadwert von Timer 0 und die Ab-weichung auf dem LCD-Display ausgegeben werden. Dazu müssen sie die Sourcemodule „LCDLib_4bitPort.c“ und „CGRAM_V7.c“ zu ihrem Projekt hinzufügen.

Projektname Verzeichnis Verwendete Sourcemodule CallRCOsci Test_CallRCOsci TestCalibration.c,

..\Library PortConfig.c CGRAM_V7.c, LCDLib_4bitPort.c

Tabelle 43 Projekt CallRCOsci (mit LCD-Ausgabe an Port 2)

#include <REG932.H> #include <PortConfig.H> #include <lcd_def.h> #include <stdio.h>

Page 69: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 69

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

// Bourns EPS1D-F19-AE0036 (2-bit gray code) sbit EncSwitch = P0^6; // Taster (Jumper 7) sbit EncChA = P0^5; // Kanal A (Jumper 8) sbit EncChB = P0^7; // Kanal B (Jumper 9) sbit sb1ms = P1^0; unsigned int ucValue = 0xF196; // Reloadvalue 1 ms unsigned char ucActEncVal; // akt. Position des Inkrementalgebers void v_InitTimer0_1ms(void) { // Timer 0 für 1msec initialisieren TMOD = TMOD | 0x01; TL0 = (unsigned char) ucValue; TH0 = ucValue/256; TF0 = 0; ET0 = 1; EA = 1; } void v_InitEncoder(void) { 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 } void main(void) { v_PortConfig(Port2, AllPins, BiDir); // P2 als Quasi-bidir. uc_LCDIni(_2LINE | _7DOTS); // Initialisierung des LCD-Displays uc_Clrscr(); // Loeschen des HD44780 Speichers. v_PortConfig(Port1, Pin0, BiDir); // P2 als Quasi-bidir. v_InitTimer0_1ms(); TR0 = 1; // Timer 0 starten v_InitEncoder(); do { printf("\n%cAct. Val:0x%x ",_1_LINE,ucValue); printf("\n%cDiv. Val:%i ",_2_LINE,0xF196 - ucValue); } while(1); }

Page 70: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

70 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

void v_Timer0Int(void) interrupt 1 using 1 { TL0 = (unsigned char)ucValue; TH0 = ucValue/256; sb1ms = !sb1ms; } // ISR des Keyboard void v_KeyboardInt(void) interrupt 7 { 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 Positon } // des Inkrementalgebers KBCON = 0x00; // loeschen des Keyboard Flags }

Listing 29 Inhalt von TestCalibration.c

Page 71: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 71

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

2.7 Temperaturausgabe auf der 7-Segment LED Mit dem Experimentierboard können sie die Raumtemperatur mit Hilfe des DS1621 messen und ausgeben. Erstellen sie ein Programm, das die Temperatur misst und auf der 7-Segment LED ausgibt. In diesem Projekt werden zwei I²C-Bus-Bausteine verwendet. Da der Zugriff abwech-selnd auf die Bausteine erfolgt, muss die I²C-Bus-Adresse immer mitgesetzt werden (siehe Listing 30, ).

Projektname Verzeichnis Verwendete Sourcemodule TemperaturMes Test_Temperatur TestTemperatur.c

..\Library I2C_LIB.c, PortConfig.c Tabelle 44 Projekt TemperaturMes

#include <REG932.H> #include <I2C_LIB.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, Minus = 0x40, BLANK = 0x00}; void uc_ConvVal(unsigned char ucValue) { switch(ucValue) { 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: break; } } void main(void) { char cValue; bit btHalf; unsigned char ucLoop; v_InitI2C(); EA = 1; // allgemeine Interruptsperre aufheben Slave.Adr = 0x70; // Adresse SAA1064 v_SetNextI2CVal(0); // Subadresse auf 0 (Control-Byte)

Page 72: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

72 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

v_SetNextI2CVal(0xF7); // dynamic alternating mode v_StartI2CandWait(); Slave.Adr = 0x92; // Adresse DS1621 + WR v_SetNextI2CVal(0xEE); //Command Byte: Start Convert v_StartI2CandWait(); v_SetNextI2CVal(0xAA); //Command Byte:Read Temp v_StartI2CandWait(); while(1) { Slave.Adr = 0x92 + 1; // Adresse DS1621 + RD Slave.DataLen = 2; // zwei Bytes werden empfangen v_StartI2CandWait(); cValue = Slave.Val[0]; if (Slave.Val[1] == 0x80) btHalf = 1; else btHalf = 0; Slave.DataLen = 0; Slave.Adr = 0x70; // Adresse SAA1064 v_SetNextI2CVal(1); // Subadresse auf 1 (Daten-Byte) // Ausgabe der gelesenen Temperatur if (cValue < 0) { v_SetNextI2CVal(Minus); cValue = cValue * -1; } else { uc_ConvVal(cValue/100); cValue = cValue % 100; // Rest ermitteln uc_ConvVal(cValue/10); cValue = cValue % 10; // Rest ermitteln uc_ConvVal(cValue); } // Dezimalpunkt setzen Slave.Val[Slave.DataLen-1] |= PUNKT; // Ueberpruefung auf .5 if (btHalf) v_SetNextI2CVal(FUENF); else v_SetNextI2CVal(NULL); v_StartI2CandWait(); } }

Listing 30 Inhalt von TestTemperatur.c

Page 73: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 73

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Modulares Gestalten von Projekten Die Funktion „main()“ enthält Programmteile zur Initialisierung (siehe Listing 30, , ) und die Auswertung der einzelnen I²C-Bus-Bausteine (siehe , ). Diese Programm-teile können als eigene Funktionen in einzelne Sourcemodule ausgelagert werden und somit in anderen Projekten wieder verwendet werden. Erstellen sie das Projekt aus Tabelle 45. Das Sourcemodul DS1621_LIB.c enthält die Funktionen „v_DS1621StartCov() (siehe Listing 31, )“, „v_DS1621SetCMD()“ (siehe

) und v_ DS1621ReadTemp()“ (siehe ). Die Funktionsdeklarationen sind im H-File DS1621_LIB.h abgespeichert. Das Sourcemodul SAA1064_LIB.c enthält die Funktionen „v_InitSAA1064()“ und „v_ConvVal()“ (siehe Listing 33). Die Funktionsdeklarationen sowie die Definitionen für die LED-Segmente sind im H-File DS1621_LIB.h enthalten (siehe Listing 32). Das Sourcemodul TestTemperatur.c enthält nur noch die Funktion „main()“ (siehe Listing 35). Diese wiederum enthält nur noch die Initialisierungsaufrufe für die I²C-Bus-Bausteine und die Umwandlung der Temperatur für die 7-Segment- Dar-stellung. Damit die Funktionen von DS1621 und SAA1064 im Sourcemodul TestTemperatur.c bekannt sind, müssen die H-Files inkludiert werden (siehe Listing 35,

). Projektname Verzeichnis Verwendete Sourcemodule

Test_TempModular Test_DS1621_SAA1064_Lib TestTemperatur.c ..\Library DS1621_LIB.c, I2C_LIB.c,

SAA1064_LIB.c, PortConfig.c Tabelle 45 Projekt Test_TempModular

#include <I2C_LIB.H> #include <DS1621_LIB.h> void v_DS1621StartCov(void) { Slave.Adr = 0x92; // Adresse DS1621 + WR v_SetNextI2CVal(0xEE); //Command Byte: Start Convert v_StartI2CandWait(); } void v_DS1621SetCMD(unsigned char ucCmd) { Slave.Adr = 0x92; // Adresse DS1621 + WR v_SetNextI2CVal(ucCmd); //Command Byte:Read Temp v_StartI2CandWait(); } void v_DS1621ReadTemp(void) { Slave.Adr = 0x92 + 1; // Adresse DS1621 + RD Slave.DataLen = 2; // zwei Bytes werden empfangen v_StartI2CandWait(); }

Listing 31 Inhalt von DS1621_LIB.c

Page 74: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

74 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

// Definitionen enum enDS161Config {READ_TEMP = 0xAA}; // Funktionsdeklarationen void v_DS1621StartCov(void); void v_DS1621ReadTemp(void); void v_DS1621SetCMD(unsigned char ucCmd);

Listing 32 Inhalt von DS1621_LIB.h

#include <I2C_LIB.H> #include <SAA1064_LIB.h> void v_InitSAA1064(unsigned char ucMode) { Slave.Adr = 0x70; // Adresse SAA1064 v_SetNextI2CVal(0); // Subadresse auf 0 (Control-Byte) v_SetNextI2CVal(ucMode); // Betriebsart setzen v_StartI2CandWait(); } void v_ConvVal(unsigned char ucValue) { switch(ucValue) { 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: break; } }

Listing 33 Inhalt von SAA1064_LIB.c

// Definitionen enum enSAASEG {NULL = 0x3F, EINS = 0x06, ZWEI = 0x5B, DREI = 0x4F, VIER = 0x66, FUENF = 0x6D, SECHS = 0x7D, SIEBEN = 0x07, ACHT = 0x7F, NEUN = 0x67, PUNKT = 0x80, Minus = 0x40, BLANK = 0x00}; enum enSAACONFIG {DYNAMIC_MODE = 0xF7}; // Funktionsdeklarationen void v_InitSAA1064(unsigned char ucMode); void v_ConvVal(unsigned char ucValue);

Listing 34 Inhalt von SAA1064_LIB.h

Page 75: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 75

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

#include <REG932.H> #include <I2C_LIB.H> #include <SAA1064_LIB.h> #include <DS1621_LIB.h> void main(void) { char cValue; bit btHalf; v_InitI2C(); EA = 1; // allgemeine Interruptsperre aufheben v_InitSAA1064(DYNAMIC_MODE); v_DS1621StartCov(); v_DS1621SetCMD(READ_TEMP); while(1) { v_DS1621ReadTemp(); // Ausgabe der gelesenen Temperatur cValue = Slave.Val[0]; if (Slave.Val[1] == 0x80) btHalf = 1; else btHalf = 0; Slave.DataLen = 0; Slave.Adr = 0x70; // Adresse SAA1064 v_SetNextI2CVal(1); // Subadresse auf 1 (Daten-Byte) if (cValue < 0) { v_SetNextI2CVal(Minus); cValue = cValue * -1; } v_ConvVal(cValue/100); cValue = cValue % 100; // Rest ermitteln v_ConvVal(cValue/10); cValue = cValue % 10; // Rest ermitteln v_ConvVal(cValue); // Dezimalpunkt setzen Slave.Val[Slave.DataLen-1] |= PUNKT; if (btHalf) // Ueberpruefung auf .5 v_SetNextI2CVal(FUENF); else v_SetNextI2CVal(NULL); v_StartI2CandWait(); } }

Listing 35 Inhalt von TestTemperatur.c

Page 76: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

76 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Ausgabe der Zeichen A–F auf der 7-Segment LED Die Zeichen A – F können auf der 7-Segment LED ausgegeben werden. Die Buchstaben „b“ und „d“ werden dabei als Kleinbuchstaben dargestellt (siehe Abbildung 45).

Abbildung 45 Buchstabendarstellung A–F

Erweitern sie die SAA1064_LIB.c und SAA1064_lib.h um die Buchstabeneinträge. Bei den Definitionen der Buchstaben im Aufzählungstyp enum muss ein Unterstrich davor gesetzt werden, da der Buchstabe B bereits bei den SFR-Definitionen verwendet wurde (siehe Listing 36, ).

// Definitionen enum enSAASEG {NULL = 0x3F, EINS = 0x06, ZWEI = 0x5B, DREI = 0x4F, VIER = 0x66, FUENF = 0x6D, SECHS = 0x7D, SIEBEN = 0x07, ACHT = 0x7F, NEUN = 0x67, PUNKT = 0x80, MINUS = 0x40, BLANK = 0x00, _A = 0x77, _B = 0x7C, _C = 0x39, _D = 0x5E, _E = 0x79, _F = 0x71 }; enum enSAACONFIG {DYNAMIC_MODE = 0xF7}; // Funktionsdeklarationen void v_InitSAA1064(unsigned char ucMode); void v_ConvVal(unsigned char ucValue);

Listing 36 Erweiterungen in der SAA1064_LIB.h (enum enSAASEG)

In der Funktion „v_ConvVal()“ muss zudem der switch-case Konstrukt um die Einträge 0x0A bis 0x0F erweitert werden (siehe Listing 37, ).

void v_ConvVal(unsigned char ucValue) { switch(ucValue) { 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; case 0x0A: v_SetNextI2CVal(_A); break; case 0x0B: v_SetNextI2CVal(_B); break; case 0x0C: v_SetNextI2CVal(_C); break; case 0x0D: v_SetNextI2CVal(_D); break;

Page 77: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 77

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

case 0x0E: v_SetNextI2CVal(_E); break; case 0x0F: v_SetNextI2CVal(_F); break; default: break; } }

Listing 37 Auszug aus SAA1064_LIB.c (erweitertes switch()-Konstrukt)

2.8 Tastaturabfrage mit dem I/O-Expander Mit Hilfe des PCF8574 I/O-Expanders können sie Daten ausgeben und die Zustände „Low“ und „High“ an den Pins einlesen. Das Einlesen der Daten erfolgt, indem zur I²C-Bus Adresse + „Read“ gesetzt wird. Erstellen sie das Projekt aus Tabelle 46, das den Zustand der Tasten S9 bis S16 einliest und das Ergebnis an Port 2 ausgibt. Wird eine Taste gedrückt, soll die entsprechende LED dazu ausgehen. Stellen sie mit den Steckbrücken eine Verbindungen zwischen XTa0-7 mit XP4D0-7 her.

!! Vergessen sie nicht die Jumper J14 bis J20 zu entfernen, da sonst die LCD mit am Port des I/O-Expanders hängt und sich somit undefinierte Ergebnisse ergeben. !!

Um die Portpins am PCF8574 beschreiben und auslesen zu können, sollen die Funktio-nen „v_PCF8574WriteVal()“ und „v_PCF8574ReadVal()“ im Sourcemodul PCF8574-_LIB.c erstellt werden (siehe Listing 39). In der Funktion „main()“ wird zuerst die Initialisierung des I²C-Busses (siehe Listing 40,

), die Freigabe des Interrupts (siehe ) und die Konfiguration des Port 2 durchgeführt (siehe ). Da die Ports am PCF8574 als Eingänge arbeiten sollen, müssen die Portpins noch mit einer „1“ beschrieben werden (siehe ). In der while-Schleife wird nun konti-nuierlich der Port des PCF8574 ausgelesen (siehe ), und das Ergebnis an Port 2 ausge-geben (siehe ).

Projektname Verzeichnis Verwendete Sourcemodule Test_IOExp_Lib Test_PCF8574_Lib TestIOExp_Lib.c

..\Library PCF8574_LIB.c, I2C_LIB.c, PortConfig.c

Tabelle 46 Projekt Test_IOExp_Lib

// Funktionsdeklarationen void v_PCF8574WriteVal(unsigned char ucVal); void v_PCF8574ReadVal(void);

Listing 38 Inhalt von PCF8574_LIB.h

#include <I2C_LIB.H> #include <PCF8574_Lib.h> void v_PCF8574WriteVal(unsigned char ucVal) { Slave.Adr = 0x40; // Adresse PCF8574 + WR v_SetNextI2CVal(ucVal); //ein Byte wird geschrieben v_StartI2CandWait();

Page 78: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

78 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

} void v_PCF8574ReadVal(void) { Slave.Adr = 0x40 + 1; // Adresse PCF8574 + RD Slave.DataLen = 1; // ein Bytes wird gelesen v_StartI2CandWait(); }

Listing 39 Inhalt von PCF8574_LIB.c

#include <REG932.H> #include <I2C_LIB.H> #include <PortConfig.H> #include <PCF8574_Lib.h> void main(void) { v_InitI2C(); EA = 1; // allgemeine Interruptsperre aufheben v_PortConfig(Port2, AllPins, BiDir); v_PCF8574WriteVal(0xFF); // Alle Portpins auf 1 setzen while(1) { v_PCF8574ReadVal(); // Wert einlesen P2 = Slave.Val[0]; // Ergebnis an Port 2 ausgeben } }

Listing 40 Inhalt von TestIOExp_Lib.c

Auswertung mit Interrupt des PCF8574 Der PCF8574 verfügt über ein Interruptsignal, wenn sich an den Porteingängen der Zustand ändert. Die Zustandsänderung für das Auslösen des Interrupts bezieht sich auf den eingeschriebenen und an den Ausgängen übernommenen Wert. Das Experimentier-board kann über den Jumper 11 eine Verbindung zwischen dem Interruptsignal des PCF8574 und dem externen Interrupt 1 herstellen. Erstellen sie das Projekt aus Tabelle 47, das den externen Interrupt 1 auswertet, in der ISR den Wert aus dem PCF8574 einliest und die Ergebnisse wieder an Port 2 ausgibt. Bei dieser Aufgabe ist zu beachten, dass die Priorität des I²C-Bus Interrupts hochgesetzt wird (siehe Listing 41, ). Ansonsten kann der PCF8574 (I²C-ISR) nicht ausgelesen werden, da der ext. Interrupt 1 in der Abarbeitungssequenz höher angesiedelt ist. Eine ausführliche Beschreibung zu den Interrupt Prioritäten finden sie in Kapitel 10.8 „Interrupt Priorität“ [3]. Damit die Zustandsänderung beim Loslassen der Taste wieder einen Interrupt beim PCF8574 auslöst, wird der eingelesene Wert in der ISR wieder in den PCF8574 einge-schrieben (siehe ).

Page 79: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 79

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Projektname Verzeichnis Verwendete Sourcemodule Test_IOExp_Int Test_PCF8574_Int TestIOExp_Int.c

..\Library PCF8574_LIB.c, I2C_LIB.c, PortConfig.c

Tabelle 47 Projekt Test_IOExp_Int

#include <REG932.H> #include <I2C_LIB.H> #include <PortConfig.H> #include <PCF8574_Lib.h> void main(void) { v_InitI2C(); IT1 = 1; // ext. Interrupt 1, flankengetriggert EX1 = 1; // ext. Interrupt freigeben EA = 1; // allgemeine Interruptsperre aufheben v_PortConfig(Port2, AllPins, BiDir); v_PCF8574WriteVal(0xFF); // Alle Portpins auf 1 setzen IP1 =0x01; // Interruptprio für I²C-Bus hochsetzen while(1); // Endlosschleife } void v_ExtInt1(void) interrupt 2 using 1 { unsigned char ucVal; v_PCF8574ReadVal(); // Wert einlesen ucVal = Slave.Val[0]; // Ergebnis an Port 2 ausgeben v_PCF8574WriteVal(ucVal); P2 = ucVal; }

Listing 41 Inhalt von TestIOExp_Int.c

2.9 Arbeiten mit dem Inkrementalgeber Erstellen einer Library für den Inkrementalgeber Die Auswertung des Inkrementalgebers erfolgt mit dem Keyboard Interrupt (siehe Pro-jekt Test_Encoder (Kapitel 2.2, Seite 31). Die Konfiguration und Freigabe des Key-board-Interrupts soll in der Funktion „v_InitEncoder()“ erfolgen. Diese Funktion und die ISR sollen im Sourcemodul Encoder_Lib.c abgespeichert werden. Die Bewegung des Encoders wird in der Variablen ucValue abgespeichert. Die LEDs an Port 2 sollen den Wert von ucValue enthalten. Erstellen sie das Projekt aus Tabelle 48.

Projektname Verzeichnis Verwendete Sourcemodule Test_EncoderLib Test_EncoderLib TestEncLib.c

..\Library Encoder_Lib.c, PortConfig.c Tabelle 48 Projekt Test_EncoderLib

Page 80: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

80 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

#include <REG932.H> #include <Encoder_Lib.h> #include <PortConfig.H> void main(void) { v_PortConfig(Port2, AllPins, BiDir); // Port 2 konfiguriert v_InitEncoder(); // Keyboard-Interrupt initialisiert EA = 1; // allgemeine Interruptsperre aufheben while(1) // Endlosschleife { P2 = cValue; // Wertuebernahme an Port 2 } }

Listing 42 Inhalt von TestEncLib.c

#include <REG932.H> #include <Encoder_Lib.h> static unsigned char ucActEncVal; char cValue; void v_InitEncoder(void) { ucActEncVal = P0 & 0xA0; // Abspeichern der akt. Position cValue = 0; // Ruecksetzen KBPATN = P0 & 0xE0; // Setzen des Keyboard-Patterns KBCON = 0x00; KBMASK = 0xE0; // Maske fuer Portpin 5, 6 und 7 EKBI = 1; // ISR fuer Keyboard-Int. freigeben } void v_KeyboardInt(void) interrupt 7 { 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) cValue++; else cValue--; break; case 0x20: if (ucActEncVal == 0xA0) cValue++;

Page 81: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 81

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

else cValue--; break; case 0x80: if (ucActEncVal == 0x00) cValue++; else cValue--; break; case 0xA0: if (ucActEncVal == 0x80) cValue++; else cValue--; break; } ucActEncVal = P0 & 0xA0; // Abspeichern der neuen Positon } // des Inkrementalgebers KBCON = 0x00; // Loeschen des Keyboard Flags }

Listing 43 Inhalt von Encoder_Lib.c

Steuerung des Cursors auf dem LCD-Display mit Hilfe des Inkrementalgebers Jedes moderne Gerät wird seit einiger Zeit mit einer „Einknopf“-Bedienung ausgeliefert. Das Bedienelement für diese Funktion besteht aus einer Kombination aus Taster und Inkrementalgeber. Mit dem Taster wird zwischen den Rubriken ausgewählt bzw. die Eingabe bestätigt. Der Inkrementalgeber scrollt zwischen den Rubriken bzw. zwischen den Unterpunkten. Erstellen sie ein Projekt, das den Cursor auf dem LCD mit dem Inkrementalgeber bewegt. Die Umschaltung zwischen horizontal und vertikal erfolgt mit der Taste des In-krementalgebers. Die LCD wird über den Port 2 angesteuert. Das Kommando „Cursor and Display Shift“ des HD44780 (siehe [2], Kapitel 5, „Kurzbeschreibung der einzelnen Befehle“) setzt den Cursor auf eine Adresse im DD-RAM. Dieses Kommando zur Umsetzung des Cursors kann mit der Steueranwiesung „\n“ (printf(), v_SM_Printf()) erreicht werden. Die Adresszuordnung der Cursorposition im DD-RAM können sie der Tabelle 49 entnehmen. Die Tabelle 50 enthält die Projektstruktur.

Display Position 1 2 3 4 5 ... 13 14 15 16 DD-RAM Adr (Zeile 1) 0x00 0x01 0x02 0x03 0x04 ... 0x0C 0x0D 0x0E 0x0F

Zeile 2 0x40 0x41 0x42 0x43 0x44 ... 0x4C 0x4D 0x4E 0x4F

Tabelle 49 DD-RAM-Adressen bei einem 2x16 Zeichen Display

Die Variablen „ucHPos“ und „ucVPos“ enthalten die aktuelle Position des Cursors. Sie sind lokal in der Funktion „main()“ vom Datentyp unsigned char definiert (siehe Listing 44, ). Die Bitvariable „btIsHor“ speichert den Wechsel zwischen horizontaler und ver-tikaler Bewegung (siehe ). Nach der Initalisierung von Port 2, dem Inkrementalgeber und der LCD-Anzeige wird auf eine Zustandsänderung des Inkrementalgebers gewartet (siehe ). Bei einer Betätigung der Taste oder Bewegung des Inkrementalgebers wird die

Page 82: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

82 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Auswertung begonnen. Ist die Taste betätigt worden, wird der Zustand von btIsHor gewechselt (siehe ). Danach wird abgewartet, bis die Taste wieder losgelassen wird (sie-he ). Wurde der Inkrementalgeber gedreht, wird zuerst die Richtung überprüft (siehe

). Ist der Wert von cValue positiv, wird jetzt noch geprüft, ob es sich um eine horizontale Bewegung handelt (btIsHor = 1) und ob der Cursor bereits am linken Ende der Zeile steht (siehe ). Ist dies der Fall, wird „ucHPos“ um eins erhöht. Enthält btIsHor den Wert 0, wird „ucVPos“ auf 1 gesetzt (siehe ). Ist der Wert negativ, finden die gleichen Überprüfungen statt, in diesem Fall auf die Minimalwerte. Vor dem Umset-zen des Cursors wird „cValue“ auf 0 gesetzt (siehe ). Das Umsetzen des Cursors erfolgt in diesem Beispiel mit der Funktion „v_SM_Printf()“ (siehe ). Die Variable „ucVPos“ wird mit 0x40 multipliziert, da die zweite Zeile mit dieser Startadresse beginnt (siehe Tabelle 49).

Projektname Verzeichnis Verwendete Sourcemodule Test_LCDCursor Test_SteuerungLCDCursor TestSteuerungLCDCursor.c

..\Library Encoder_Lib.c, PortConfig.c, CGRAM_V7.c, sm_printf.c, LCDLib_4bitPort.c, itoa.a51,

bcd2hex.a51 Tabelle 50 Projekt Test_LCDCursor

#include <REG932.H> #include <Encoder_Lib.h> #include <PortConfig.H> #include <lcd_def.h> #include <sm_printf.h> void main(void) { unsigned char ucHPos =0, ucVPos =0; bit btIsHor = 1; v_PortConfig(Port2, AllPins, BiDir); // Port 2 konfigurieren v_InitEncoder(); // Inkrementalgeber konfigurieren uc_LCDIni(_2LINE | _7DOTS); // Initialisierung des HD44780 EA = 1; // allg. Interruptsperre aufheben while(1) { while(cValue == 0 && EncSwitch == 1); if (EncSwitch == 0) { // wechseln zwischen hor. und ver. Bewegung btIsHor = !btIsHor; while (EncSwitch == 0); // Warten bis Taste losgelassen } else // Auswertung der Cursorbewegung { if (cValue >0) { if (btIsHor == 1 && ucHPos < 0x0F)

Page 83: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 83

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

ucHPos++; else if (btIsHor == 0) ucVPos = 1; } else { if (btIsHor == 1 && ucHPos > 0) ucHPos--; else if (btIsHor == 0) ucVPos = 0; } cValue = 0; v_SM_Printf( "\n%c",ucVPos * 0x40 + ucHPos); } } }

Listing 44 Inhalt von TestSteuerungLCDCursor.c

Menüführung mit dem Inkrementalgeber Im vorangegangenen Abschnitt haben sie den Umgang mit dem Inkrementalgeber in Verbindung mit dem LCD gelernt. Jetzt soll eine Menüführung mit Hilfe des Inkremen-talgebers entstehen. In Abhängigkeit der Drehrichtung sollen unterschiedliche Menü-punkte aus dem Array „aucHauptMenu“ (siehe Listing 45, ) angezeigt werden. Das Array selbst liegt im Speicherbereich „code“. Als Endekennung für die Liste ist eine Zeile mit Minuszeichen vorhanden (siehe ). Damit man erkennt, dass die obere Zeile selektierbar ist, wird der Cursor nach Ausgabe des Textes an das erste Zeichen gesetzt (siehe ). Nach dem Start des Programms werden die ersten zwei Zeilen des Arrays auf dem LCD ausgegeben. Das Programm wartet nun solange, bis der Inkrementalgeber gedreht wurde (siehe ). Ist der Wert von cValue positiv, wird überprüft, ob das untere Ende des Menüs ausgegeben ist. Diese Längenüberprüfung erfolgt mit dem sizeof()-Operator (siehe ). Dieser Operator liefert eine Konstante, in diesem Fall die Gesamtlänge des Arrays (sizeof(aucHauptmenu)) und die Länge eines Eintrags (sizeof(aucHauptmenu[0])), zurück. Damit lässt sich errechnen, wie viele Menüeinträge vorhanden sind. Man hätte an dieser Stelle auch eine Konstante mit der Länge 5 einfügen können. Wird ein weiterer Eintrag hinzugefügt bzw. ein Eintrag entfernt, müsste in diesem Fall die Konstante um eins erhöhen bzw. erniedrigt werden. Beim sizeof()-Operator wird dies automatisch beim Compilieren angepasst.

!! Eine ausführliche Beschreibung zum sizeof()-Operator finden sie im Kapitel 11.9 [1]. !!

Nachdem der neue Offsetwert in der Variablen „ucMenuOff“ abgespeichert ist, wird die Variable cValue auf den Wert 0 gesetzt (siehe ). Das Programm gibt nun den zweiten und dritten Eintrag auf dem LCD aus und wartet danach wieder auf eine Änderung des Inkrementalgebers.

Page 84: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

84 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Projektname Verzeichnis Verwendete Sourcemodule Test_LCDMenu Test_SteuerungLCDMenu TestSteuerungLCDMenu.c

..\Library Encoder_Lib.c, PortConfig.c, CGRAM_V7.c, sm_printf.c, LCDLib_4bitPort.c, itoa.a51,

bcd2hex.a51 Tabelle 51 Projekt Test_LCDMenu

#include <REG932.H> #include <Encoder_Lib.h> #include <PortConfig.H> #include <lcd_def.h> #include <stdio.h> unsigned char code aucHauptMenu[][17] ={"Ausgabe ", "Einstellungen ", "Test ", "Reset ", "----------------"}; void main(void) { unsigned char ucMenuOff = 0; v_PortConfig(Port2, AllPins, BiDir); // Port 2 konfigurieren v_InitEncoder(); // Inkrementalgeber konfigurieren uc_LCDIni(_2LINE | _7DOTS); // Initialisierung des HD44780 EA = 1; // allg. Interruptsperre aufheben while(1) { printf( "\n%c%s",0, aucHauptMenu[ucMenuOff]); printf( "\n%c%s",0x40, aucHauptMenu[ucMenuOff + 1]); printf("\n%c",0x0); while(cValue == 0 && EncSwitch == 1); if (cValue > 0) { if (ucMenuOff < ((sizeof(aucHauptMenu)/ sizeof(aucHauptMenu[0]))-2)) ucMenuOff++; } else { if (ucMenuOff > 0) ucMenuOff--; } cValue =0; } }

Listing 45 Inhalt von TestSteuerungLCDMenu.c

Page 85: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 85

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Erstellen sie ein Projekt, das Untermenüs für jeden Eintrag anbietet. Mit Drücken der Taste des Inkrementalgebers soll der ausgewählte Menüeintrag übernommen werden. In der zweiten Zeile sollen die Untereinträge angezeigt und mit Hilfe des Inkrementalgebers verändert werden. Die Untermenüs sind als eigenständige Arrays angelegt worden (siehe Listing 46, ). Somit wird nur soviel Speicherplatz belegt, wie jedes Untermenü benötigt. Bei einem mehrdimensionalen Array würde der Platzverbrauch immer vom größten Untermenü berechnet werden. Die Ausgabe auf dem LCD hängt jetzt von der Variablen „ucMenu“ ab. Enthält sie den Wert HAUPTMENU, werden beide Zeilen beschrieben, ansonsten nur die zweite Zeile (siehe ). Beim drücken der Taste wird „ucMenu“ überprüft (siehe

). Befindet man sich im Hauptmenü, wird der aktuelle Offset von „ucMenuOff“ direkt als Menüeintrag übernommen. Diese direkte Zuweisung ist nur deshalb möglich, weil dem HAUPTMENU der Wert „-1“ zugewiesen ist (siehe ). Andernfalls wird überprüft, ob man sich im ersten Untereintrag befindet (siehe ). In dem Fall wird zurück ins Hauptmenü verzweigt. Das switch-Konstrukt wurde um die Untereinträge erweitert (siehe ).

Projektname Verzeichnis Verwendete Sourcemodule Test_2DimLCDMenu Test_SteuerungLCDUnterMenu Test_2DimLCDMenu.c

..\Library Encoder_Lib.c, PortConfig.c, CGRAM_V7.c, sm_printf.c, LCDLib_4bitPort.c, itoa.a51,

bcd2hex.a51 Tabelle 52 Projekt Test_2DimLCDMenu

#include <REG932.H> #include <Encoder_Lib.h> #include <PortConfig.H> #include <lcd_def.h> #include <stdio.h> enum enMenu {HAUPTMENU = -1, AUSGABE, EINSTELLUNGEN, TEST, RESET}; unsigned char code aucHauptMenu[][17] ={"Ausgabe ", "Einstellungen ", "Test ", "Reset ", "----------------"}; unsigned char code aucAusgabeMenu[][17] ={"Aus. Hauptmenu ", "Aus. Eintrag 2 ", "Aus. Eintrag 3 ", "Aus. Eintrag 4 ", "----------------"}; unsigned char code aucEinstellMenu[][17] ={"Ein. Hauptmenu ", "Ein. Eintrag 2 ", "Ein. Eintrag 3 ", "Ein. Eintrag 4 ",

Page 86: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

86 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

"----------------"}; unsigned char code aucTestMenu[][17] ={"Test Hauptmenu ", "Test Eintrag 2 ", "Test Eintrag 3 ", "Test Eintrag 4 ", "----------------"}; unsigned char code aucResetMenu[][17] ={"Res. Hauptmenu ", "Res. Eintrag 2 ", "Res. Eintrag 3 ", "Res. Eintrag 4 ", "----------------"}; void main(void) { unsigned char ucMenuOff = 0; char ucMenu = HAUPTMENU; v_PortConfig(Port2, AllPins, BiDir); // Port 2 konfigurieren v_InitEncoder(); // Inkrementalgeber konfigurieren uc_LCDIni(_2LINE | _7DOTS); // Initialisierung des HD44780 EA = 1; // allg. Interruptsperre aufheben while(1) { if (ucMenu == HAUPTMENU) { printf( "\n%c%s",0, aucHauptMenu[ucMenuOff]); printf( "\n%c%s",0x40, aucHauptMenu[ucMenuOff + 1]); printf("\n%c",0x0); } else { switch(ucMenu) { case AUSGABE: printf( "\n%c%s",0x40, aucAusgabeMenu[ucMenuOff]); break; case EINSTELLUNGEN: printf( "\n%c%s",0x40, aucEinstellMenu[ucMenuOff]); break; case TEST: printf( "\n%c%s",0x40, aucTestMenu[ucMenuOff]); break; case RESET: printf( "\n%c%s",0x40, aucResetMenu[ucMenuOff]); break; } printf("\n%c",0x40); } while(cValue == 0 && EncSwitch == 1); if (EncSwitch == 0) { if (ucMenu == HAUPTMENU)

Page 87: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 87

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

{ ucMenu = ucMenuOff; ucMenuOff = 0; } else { if (ucMenuOff == 0) ucMenu = HAUPTMENU; } while (EncSwitch == 0); } if (cValue > 0) { switch(ucMenu) { case HAUPTMENU: if (ucMenuOff < ((sizeof(aucHauptMenu)/ sizeof(aucHauptMenu[0]))-2)) ucMenuOff++; break; case AUSGABE: if (ucMenuOff < ((sizeof(aucAusgabeMenu)/ sizeof(aucAusgabeMenu[0]))-2)) ucMenuOff++; break; case EINSTELLUNGEN: if (ucMenuOff < ((sizeof(aucEinstellMenu)/ sizeof(aucEinstellMenu[0]))-2)) ucMenuOff++; break; case TEST: if (ucMenuOff < ((sizeof(aucTestMenu)/ sizeof(aucTestMenu[0]))-2)) ucMenuOff++; break; case RESET: if (ucMenuOff < ((sizeof(aucResetMenu)/ sizeof(aucResetMenu[0]))-2)) ucMenuOff++; break; } } else { if (ucMenuOff > 0) ucMenuOff--; } cValue =0; printf("\n%c",0x3); } }

Listing 46 Inhalt von Test_2DimLCDMenu.c

Page 88: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

88 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

2.10 Arbeiten mit Timern Erstellen von Rechtecksignalen Mit der ISR des Timers kann ein kontinuierliches Rechtecksignal an einem Portpin er-zeugt werden. Die minimale bzw. maximale Frequenz hängt von der Betriebsart des Timers ab. Die Taktfrequenz des Timers errechnet sich wie folgt: PCLK = CCLK/2 = OSCCLK/(DIVM *4) Mit der Betriebsart 2 des Timers kann eine maximale Frequenz von 200 kHz, mit Be-triebsart 1 des Timers kann eine minimale Frequenz von 28 Hz bei Verwendung des RC-Oscillator erreicht werden. Erstellen sie eine Rechteckspannung von ti/T = 0.5 und einer Frequenz von 1 kHz. Der Reloadwert für den Timer beträgt somit 0.5 ms/PCLK = 0.5 ms/0.2712 µs = 1843. Dieser Wert kann nur mit den Betriebsarten 1 und 2 verarbeitet werden. Verwenden sie für dieses Beispiel die Betriebsart 2. In der ISR des Timers soll der Zustand des Portpins P2.0 invertiert werden. Der Reloadwert ist in der Variablen „uiTime“ abgespeichert (siehe Listing 47, ). Die Initialisierung des Timers und das Setzen der ersten Timerwer-te werden in der Funktion „v_ InitTimer0()“ vorgenommen (siehe , ). Der Reload-wert für den Timer 0 wird am Anfang der ISR durchgeführt (siehe ). Das Toggeln des Ausgangssignals wird erst danach durchgeführt (siehe ).

Projektname Verzeichnis Verwendete Sourcemodule Test_TimRec Test_TimerRectangle Test_Timer0Rectangle.c

..\Library PortConfig.c Tabelle 53 Projekt Test_TimRec

#include <REG932.H> #include <PortConfig.H> sbit btClk = P2^0; unsigned int uiTime = 0xF8CC; void v_InitTimer0(void) { TMOD = 0x01; TH0 = uiTime/256; TL0 = (unsigned char) uiTime; TF0 = 0; ET0 = 1; } void main(void) { v_PortConfig(Port2, Pin0 | Pin1 | Pin2, PushPull); v_InitTimer0(); TR0 = 1; EA = 1;

Page 89: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 89

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

while(1); } void v_Timer0Int(void) interrupt 1 { TH0 = uiTime/256; TL0 = (unsigned char) uiTime; btClk = !btClk; }

Listing 47 Inhalt von Test_Timer0Rectangle.c

Abbildung 46 enthält das Signal vom Portpin btClk (P2.0). Die geringfügige Abweichung von der 1 kHz-Frequenz ergibt sich aus der Toleranz des RC-Oscillators.

Abbildung 46 Timer 0, Betriebsart 1, 1kHz

Erstellen sie ein Projekt, bei dem mit Hilfe des Inkrementalgebers die Frequenz einstell-bar ist.

Projektname Verzeichnis Verwendete Sourcemodule Test_TrimFreq Test_TrimFreq Test_TrimFreq.c

..\Library PortConfig.c, Encoder_Lib.c Tabelle 54 Projekt Test_TrimFreq

#include <REG932.H> #include <Encoder_Lib.h> #include <PortConfig.H> sbit btClk = P2^2; unsigned int uiTime = 0xF8D2; // 1 kHz beim RC-Oscillator void v_InitTimer0(void) { TMOD = 0x01; TH0 = uiTime/256; TL0 = (unsigned char) uiTime; TF0 = 0; ET0 = 1; } void main(void) { v_InitEncoder();

Page 90: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

90 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

v_PortConfig(Port2, Pin0 | Pin1 | Pin2, PushPull); v_InitTimer0(); TR0 = 1; EA = 1; while(1) { while (cValue == 0); // Warten bis Encoder gedreht wurde if (cValue > 0 & uiTime < 0xFFFF) uiTime++; else if (uiTime > 0) uiTime--; cValue = 0; } } void v_Timer0Int(void) interrupt 1 { TH0 = uiTime/256; TL0 = (unsigned char) uiTime; btClk = !btClk; }

Listing 48 Inhalt von Test_Timer0Rectangle.c

Erweitern sie das Projekt so, dass der Reloadwert für den Timer 1 auf der 7-Segment-Anzeige ausgegeben wird. Um die Ausgabe zu realisieren, müssen die Sourcemodule „I2C_Lib.c“ und „SAA1064_Lib.c“ mit in das Projekt aufgenommen werden (siehe Tabelle 55, Abschnitt „Verwendete Sourcemodule“). Um die Funktionen im Sourcemo-dul „Test_TrimFreq.c“ bekannt zu machen, müssen die H-Files inkludiert werden (siehe Listing 49, und ). Die Initialisierung des I²C-Busses erfolgt in der Funktion „v_InitI2C()“ (siehe ). Um den SAA1064 zu initialisieren, muss zuerst die allgemeine Interruptsperre aufgehoben werden (siehe ). Die Umrechnung des Reloadwertes und die Ausgabe erfolgt am Anfang der while-Schleife (siehe ).

Projektname Verzeichnis Verwendete Sourcemodule Test_TrimFreq Test_TrimFreq Test_TrimFreq.c

..\Library PortConfig.c, Encoder_Lib.c, I2C_Lib.c, SAA1064_Lib.c

Tabelle 55 Projekt Test_TrimFreq (erweitert)

#include <REG932.H> #include <Encoder_Lib.h> #include <I2C_LIB.H> #include <SAA1064_LIB.h> #include <PortConfig.H> sbit btClk = P2^2; unsigned int uiTime = 0xF8D2; // 1 kHz beim RC-Oscillator void v_InitTimer0(void) { TMOD = 0x01;

Page 91: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 91

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

TH0 = uiTime/256; TL0 = (unsigned char) uiTime; TF0 = 0; ET0 = 1; } void main(void) { v_InitI2C(); v_InitEncoder(); v_PortConfig(Port2, Pin0 | Pin1 | Pin2, PushPull); v_InitTimer0(); TR0 = 1; EA = 1; v_InitSAA1064(DYNAMIC_MODE); while(1) { Slave.DataLen = 0; Slave.Adr = 0x70; // Adresse SAA1064 v_SetNextI2CVal(1); // Subadresse auf 1 (Daten-Byte) v_ConvVal(uiTime/0x1000); // Umrechung des Reloadwertes (MSB) v_ConvVal((uiTime & 0xF00)/0x100); v_ConvVal((uiTime & 0xF0)/0x10); v_ConvVal(uiTime & 0x0F); // Umrechung des Reloadwertes (LSB) v_StartI2CandWait(); while (cValue == 0); // Warten bis Encoder gedreht wurde if (cValue > 0 & uiTime < 0xFFFF) uiTime++; else if (uiTime > 0) uiTime--; cValue = 0; } } void v_Timer0Int(void) interrupt 1 { TH0 = uiTime/256; TL0 = (unsigned char) uiTime; btClk = !btClk; }

Listing 49 Inhalt von Test_TrimFreq.c

Konfigurieren der Timer mit Hilfe von Libraryfunktionen Da die beiden Timer 0 und 1 über die SFR TMOD und TAMOD konfiguriert werden, ist es sinnvoll, diese mit Hilfe von Funktionen zu initialisieren. Die Funktionen übernehmen das nötige Ausmaskieren und Setzen der jeweiligen Bits in den SFR. Damit der Übergabewert an die Initialisierungsfunktion nicht in einem HEX-Wert geschrieben werden muss, sind für die einzelnen Betriebsarten des Timers enum-Aufzählungstypen im H-File definiert (siehe Listing 50, und ). Für jeden der beiden Timer ist eine

Page 92: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

92 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

eigene Funktion zur Initialisierung des Timers erstellt worden (siehe , ). Die Definitionen in den enum-Aufzählungstypen sind so gelegt worden, dass alle zulässigen Kombinationen in einem Byte abgespeichert werden können. Dadurch ist der Programmcode klein.

enum enTimerMode {MODE0 =0, MODE1, MODE2, MODE3, MODE6 = 0x12}; enum enTimerFunc {TIMER = 0, COUNTER = 4, GATE_OFF = 0, GATE_ON = 8, PWM_OFF = 0, PWM_ON = 0x20}; // Funktionsdeklaration void v_InitTimer0(unsigned char ucMode); void v_InitTimer1(unsigned char ucMode);

Listing 50 Inhalt von TestTimerLib.h

Am Anfang der Initialisierung des Timers werden zuerst alle Bits in den SFR TMOD und AUXR1 auf „0“ gesetzt (siehe Listing 51, ). Als nächstes wird überprüft, ob der Timer in der Betriebsart 6 (Mode 6) arbeiten soll (siehe ). Ist dies der Fall, wird das jeweilige Bit im SFR TAMOD gesetzt (siehe ). In dieser Programmverzweigung wird auch überprüft, ob das PWM-Signal aktiviert werden soll (siehe ). Ist dies der Fall wird das jeweilige Bit im SFR AUXR1 gesetzt. Trifft die Betriebsart 6 nicht zu, wird das jeweilige Bit im SFR TAMOD gelöscht (siehe ). In der letzten Zeile (siehe ) wird die Betriebsart in das TMOD-Register geschrieben.

#include <REG932.H> #include <TimerLibrary.h> void v_InitTimer0(unsigned char ucMode) { // Einstellung der Betriebsart TMOD = TMOD & 0xF0; AUXR1 = AUXR1 & 0xEF; // Externen PWM-Ausgang abschalten if ((ucMode & MODE6) == MODE6) // Ueberpruefung auf Betriebsart { // 6 (PWM) TAMOD = TAMOD | 0x01; if ((ucMode & PWM_ON) == PWM_ON) AUXR1 = AUXR1 | 0x10; ucMode = ucMode & 0x0F; // MODE6-Codierung und PWM-Info ausb. } else TAMOD = TAMOD & 0xFE; TMOD = TMOD | ucMode; } void v_InitTimer1(unsigned char ucMode) { // Einstellung der Betriebsart TMOD = TMOD & 0x0F; AUXR1 = AUXR1 & 0xDF; // Externen PWM-Ausgang abschalten if ((ucMode & MODE6) == MODE6) // Ueberpruefung auf Betriebsart { // 6 (PWM) TAMOD = TAMOD | 0x10;

Page 93: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 93

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

if ((ucMode & PWM_ON) == PWM_ON) AUXR1 = AUXR1 | 0x20; ucMode = ucMode & 0x0F; // MODE6-Codierung und PWM-Info ausb. } else TAMOD = TAMOD & 0xEF; TMOD = TMOD | (ucMode * 16); }

Listing 51 Inhalt von TestTimerLib.c

Erstellen sie nun das Projekt aus Tabelle 56, das die Funktionen „v_InitTimer0()“ und „v_InitTimer1()“ austestet. Timer 0 soll in der Betriebsart 2 als Counter (siehe Listing 52,

) und Timer 2 in Betriebsart 6 als Timer mit aktiver PWM laufen (siehe ). Um die Aufzählungstypen MODE2, MODE6, ... verwenden zu können, muss das H-File Timerlibrary.h über die #include-Anweisung eingebunden werden (siehe ).

Projektname Verzeichnis Verwendete Sourcemodule Test_TimerLib Test_TimerLib Test_TimerLib.c

..\Library PortConfig.c, TimerLibrary.c Tabelle 56 Projekt Test_TimerLib

#include <REG932.H> #include <TimerLibrary.h> #include <PortConfig.H> void main(void) { v_InitTimer0(MODE2 | COUNTER); v_InitTimer1(MODE6 | TIMER | PWM_ON); v_PortConfig(Port0, Pin7, PushPull); TH1 = 0xF0; P0 = 0xFF; TR1 = 1; while(1); }

Listing 52 Inhalt von TestTimerLib.c

2.11 DCF77-Auswertung Das Zeitsignal der physikalisch-technischen Bundesanstalt in Braunschweig wird gerne für das Stellen des RTC verwendet. Die Funktionsweise der Amplitudenmodulation und den Aufbau der DCF77-Kodierung finden sie im Kapitel 12 [2]. Um das DCF77-Signal auswerten zu können, muss das Verhältnis ti/T ermittelt werden. Ist das Verhältnis 1/10, ist eine „0“ kodiert, bei 2/10 eine „1“. Abbildung 47 enthält ei-nen Ausschnitt des DCF77-Signals. Mit dem Beginn jeder Sekunde mit Ausnahme der 59sten, wird eine „0“, bzw. eine „1“ gesendet. Somit ist zu erkennen, wann die nächste Minute anfängt.

Page 94: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

94 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Abbildung 47 Ausschnitt aus dem DCF77-Signal

Je nach verwendetem DCF77-Empfänger weicht das Verhältnis von ti/T um einige % ab (siehe Abbildung 48 und Abbildung 49).

Abbildung 48 Empfang des Wertes „0“

Abbildung 49 Empfang des Wertes „1“

Erstellen sie ein Programm, das die Breite des LOW-Pulses auswertet. Wird eine „0“ erkannt, wird die LED an P2.0, bei einer „1“ die LED an P2.1 eingeschaltet. Liegt die Zeit außerhalb des erlaubten Bereiches von +- 10 %, so sollen die LEDs P2.4–P2.7 ein-geschaltet werden. Um die Zeit messen zu können, wird der Timer 0 mit einem Reloadwert von 10 ms geladen (siehe Listing 53, ) und bei fallender Flanke gestartet (siehe ). Alle 10 ms (siehe ) wird die Variable „ucTime“ inkrementiert und der Zustand des Portpins P2.3 gewechselt (siehe ). Wechselt der Zustand des DCF77-

Page 95: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 95

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Signals von „0“ -> „1“, wird der Timer 0 gestoppt (siehe ) und „ucTime“ wird ausge-wertet (siehe ). Danach wird der Reloadwert gesetzt (siehe ) und auf die nächste fal-lende Flanke gewartet (siehe ).

Projektname Verzeichnis Verwendete Sourcemodule DCF77_Tick Test_DCF77_Tick TestDCF77.c, PortConfig.c

Tabelle 57 Projekt DCF77_Tick

#include <REG932.H> #include <PortConfig.h> sbit sbDCF77 = P0^0; sbit sb10msec = P2^3; unsigned char ucTime; void main(void) { v_PortConfig(Port2, AllPins, BiDir); P2 = 0xFF; TMOD = 0x01; // Timer 0, Betriebsart 1 TL0 = 0xDD; // fuer 10 msec initialisieren TH0 = 0x6F; TF0 = 0; // Timer 0 Flag zuruecksetzen ET0 = 1; // Interrupt fuer Timer 1 freigeben EA = 1; // Warten bis fallende Flanke gefunden while (sbDCF77 == 0); while (sbDCF77 == 1); while (1) { TR0 = 1; // Timer 1 starten ucTime = 0; while (sbDCF77 == 0); TR0 = 0; // Timer 1 stoppen if (ucTime >= 10 & ucTime <= 11) P2 = 0x01; else if (ucTime > 20 & ucTime <= 21) P2 = 0x02; else P2 = 0xF0; // Timerwert auf Reloadwert setzen TL0 = 0xDD; TH0 = 0x6F; while (sbDCF77 == 1); // Warten auf fallende Flanke

Page 96: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

96 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

} } void v_Timer0Int(void) interrupt 1 using 1 { TL0 = 0xDD; TH0 = 0x6F; ucTime++; sb10msec = !sb10msec; }

Listing 53 Inhalt von TestDCF77.c Um eine volle Minute aufzeichnen und auswerten zu können, muss zuerst die 59ste Sekunde gefunden werden. Erstellen sie ein Programm, das diese Sekunde findet und bei der fallenden Flanke von der nächsten Sekunde stoppt. Die Initialisierung des Timers ist zur besseren Lesbarkeit in eine eigene Unterfunktion ausgelagert worden (siehe Listing 54, ). Für die Konfiguration von Port 2 wurde die Libraryfunktion „v_PortConfig()„ aus Kapitel 2.3 verwendet (siehe ). Im Gegensatz zum vorangegangenen Beispiel wird auf die steigende Flanke des DCF77-Signals gewar-tet (siehe ). Ist sie gefunden, wird die Zeitmessung gestartet (siehe ). Es wird jetzt so lange gewartet, bis eine fallende Flanke erkannt wird (siehe ). Ist die gemessene Zeit größer 1,8 s (siehe ), ist die 59ste gefunden worden.

Projektname Verzeichnis Verwendete Sourcemodule DCF77_59sec Test_DCF77_59sec FindDCF77_59sec.c

Tabelle 58 Projekt DCF77_59sec

#include <REG932.H> #include <PortConfig.H> sbit sbDCF77 = P0^0; sbit sb10msec = P2^3; unsigned char ucTime; void v_InitTimer10msec(void) { // Timer 0 für 10 msec initialisieren TMOD = 0x01; TL0 = 0xDD; TH0 = 0x6F; TF0 = 0; ET0 = 1; EA = 1; } void main(void) { unsigned char Low, High; v_PortConfig(Port2, AllPins, BiDir); // P2 als Quasi-bidir. v_InitTimer10msec();

Page 97: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 97

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

while (sbDCF77 == 1); // Warten bis fallende Flanke gefunden while (sbDCF77 == 0); // Warten bis steigende Flanke gefunden TR0 = 1; // Timer 0 starten while (1) { ucTime = 0; while (sbDCF77 == 1); if (ucTime >= 180) { TR0 = 0; // Timer 0 stoppen } while (sbDCF77 == 0); TL0 = 0xDD; TH0 = 0x6F; } } void v_Timer0Int(void) interrupt 1 using 1 { TL0 = 0xDD; TH0 = 0x6F; ucTime++; sb10msec = !sb10msec; }

Listing 54 Inhalt von FindDCF77_59sec.c

Abbildung 50 DCF77-Lücke bei der 59sec

Meist sehen die DCF77-Signale aber nicht so sauber aus, wie bisher dargestellt. Leichte Änderungen des Ferritkerns zur Senderichtung oder ein störendes Umfeld, z. B. durch Radiosender ergeben folgendes DCF77-Signalbild für die Auswertung:

Page 98: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

98 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Abbildung 51 DCF77 gestörter Empfang

Um eine Spikeunterdrückung durchzuführen, startet der Flankenwechsel des DCF77-Signals den zweiten Timer. Ist diese Zeit abgelaufen und kein erneuter Flankenwechsel aufgetreten, wird der Flankenwechsel an Portpin 2.3 ausgegeben. Abbildung 52 enthält eine Filterfunktion mit einem Timer1 Intervall von 5 ms.

Abbildung 52 DCF77 gestörter Empfang (P0.0), Filter 5ms (P2.3)

Um den Softwareaufbau und die Funktionsweise der Spikeunterdrückung nachvollziehen zu können, erstellen sie das Projekt aus Tabelle 59. Mit Hilfe des Makros „#define FILTER“ (siehe Listing 55, ) wird die Zeit für den Timer 1 definiert.

!! Aufbau und Funktionsweise des Makros #define können sie im Kapitel 5 [1], in der Rubrik Makro Definitionen nachlesen. !!

Am Anfang des Programms wird der Timer 1 initialisiert (siehe ). Die Initialisierung selbst ist in Funktionen ausgelagert worden (siehe ). Das Programm wartet so lange, bis eine fallende Flanke gefunden wurde (siehe ). Es wird nun die Spikeunterdrückung gestartet (siehe ). Ist die Zeit des Timer 1 abgelaufen und es hat kein weiterer Flankenwechsel am DCF77-Signal stattgefunden, wird der aktuelle Zustand des DCF77-Signals an P2.3 ausgegeben (siehe ). Der Timer 1 wird zudem gestoppt. Erfolgt ein Flankenwechsel während der Timer 1 läuft, wird der Timer 1 erneut aufgesetzt. Somit wird erreicht, das kurzzeitige Spikes kleiner der Timer 1 Zeit unterdrückt werden.

Projektname Verzeichnis Verwendete Sourcemodule DCF77_DetectSpike Test_DCF77_DetectSpike DetectSpike.c

..\Library PortConfig.c Tabelle 59 Projekt DCF77_ DetectSpike

#include <REG932.H> #include <PortConfig.H>

Page 99: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 99

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

sbit sbDCF77 = P0^0; sbit sbCleanDCF77 = P2^3; unsigned char ucTime; // Reload value 1ms (RC-Oscillator) = 0xE6A #define FILTER 0x10000 - (5 * 0xE6A) void v_InitTimer1(void) { // Timer 1 für initialisieren TMOD = TMOD | 0x10; TL1 = (unsigned char) FILTER; TH1 = FILTER / 256; TF1 = 0; ET1 = 1; EA = 1; } void v_StartFilter(void) { TH1 = FILTER / 256; TL1 = (unsigned char) FILTER; TR1 = 1; // Timer 1 starten } void main(void) { // unsigned char Low, High; v_PortConfig(Port2, AllPins, BiDir); // P2 als Quasi-bidir. v_InitTimer1(); while (sbDCF77 == 1); // Warten bis fallende Flanke gefunden v_StartFilter(); while (1) { while (sbDCF77 == 1); v_StartFilter(); while (sbDCF77 == 0); v_StartFilter(); } } void v_Timer1Int(void) interrupt 3 using 1 { sbCleanDCF77 = sbDCF77; TR1 = 0; // Timer 1 stoppen }

Page 100: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

100 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Listing 55 Inhalt DetectSpike.c

Dieser Filtermechanismus erkennt allerdings nicht, wenn die Spikes > 5 ms sind. In die-sem Fall entsteht ein Signalwechsel mit einer Zeitbreite >= 5 ms (siehe Abbildung 53). Um diese kurzzeitigen Wechsel unterdrücken zu können, muss die Startzeit des letzten Flankenwechsels abgespeichert werden.

Abbildung 53 DCF77 gestörter Empfang (P0.0), Filter 5ms (P2.3)

Page 101: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 101

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

2.12 Speichererweiterung für Aufzeichnung (A/D-Wandler) Da der P89LPC932/935 nur über einen 512-Byte großen XRAM-Bereich verfügt, kön-nen größere Datenmengen, die z. B. bei einer kontinuierlichen A/D-Wandlung über ei-nen gewissen Zeitraum entstehen, nicht zwischengespeichert werden. Um den RAM-Speicher zu vergrößern, sind folgende Möglichkeiten denkbar: • Verwendung eines zusätzlichen FIFOs

Es werden handelsübliche FIFOs verwendet. Vorteile:

Einfache Ansteuerung des µControllers Nachteile:

Hoher Preis Geringe Speichertiefe Es kann nicht auf eine beliebige Speicheradresse zugegriffen werden.

• Verwendung von SPI/I²C-RAM-Speicher(n) Es werden handelsübliche RAM-Speicher verwendet, die via SPI- bzw. mit dem I²C-Bus angesteuert werden. Vorteile:

Sehr einfache Ansteuerung (es werden nur zwei bis drei zusätzliche Portpins belegt). Nachteile:

Es gibt nur kleine RAM-Speicher. Langsame Übertragungsgeschwindigkeit (I²C-Bus)

• Aufbau eines eigenen Adress-/Datenbusses mit externem RAM Es wird der komplette Adress-/Datenbus mit Adress-Latch nachgebildet. Die Schreib-/Lesesignale werden mit zusätzlichen Portpins realisiert. Vorteile:

Beliebige Speichergröße möglich Nachteile:

Es werden sehr viele zusätzliche Portpins für die Nachbildung des Adress-/Daten-busses und der Steuersignale benötigt.

• Vereinfachter Aufbau eines eigenen Adress-/Datenbusses mit externem RAM Für den Adressbus wird ein 12-bit Counter eingesetzt. Dieser kann mit Hilfe von Portpins zurückgesetzt, bzw. getaktet werden. Die Steuersignale für den Schreib-/Leseimpuls werden mit zwei zusätzlichen Portpins realisiert. Vorteile:

Beliebige Speichergröße möglich. Nur wenige zusätzliche Steuerleitungen werden benötigt.

Nachteile: Keine direkte Adressierung einer bestimmten RAM-Adresse möglich.

Page 102: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

102 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Für die Speichererweiterung wurde der vereinfachte Aufbau verwendet, da die A/D-Daten nur in zeitlicher Reihenfolge in aufeinander folgenden Adressen zwischengespei-chert werden müssen. Den Schaltungsaufbau können sie der Abbildung 54 entnehmen. Port 2 wird nur während dem Schreib-/Lesevorgang der Daten benötigt. Ansonsten ist er frei verfügbar. Die Ansteuerung von A12 kann auch über einen kaskadierten 74HC4040 erfolgen. Dies hätte auch noch den Vorteil, dass größere SRAM-Bausteine eingesetzt werden können.

Abbildung 54 Aufbau einer externen Speichererweiterung 8k (getaktete Adressierung)

Erstellen sie das folgende Projekt, um die Ansteuerung und das SRAM testen zu können. Für das Schreiben bzw. Auslesen des SRAMs werden zwei eigenständige Funktionen (siehe Listing 56, und ) erstellt. In main() wird das SRAM mit Hilfe einer Schleife zuerst beschrieben (siehe ) und danach ausgelesen (siehe ). Entspricht der ausgele-sene Wert nicht dem erwarteten, wird das Programm bei der while(1) Bedingung ge-stoppt. An diese Stelle kann jetzt eine Fehlerausgabe, z. B. über die serielle Schnittstelle oder eine Ausgabe auf dem LCD, erfolgen.

Projektname Verzeichnis Verwendete Sourcemodule TestExtRAM Test_ExtRAM TestExtRAM.c

Tabelle 60 TestExtRAM

#include <REG932.H> // Definition der SRAM-Groesse #define SRAMSIZE 8192 // Definition der Steuerleitungen (SRAM)

Page 103: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 103

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

sbit A12 = P0^2; sbit _WE = P0^3; sbit _CS1= P0^5; // Definition der Steuerleitungen (74HC4040) sbit CLR = P0^6; sbit CLK = P0^7; v_ClearCnt(void) { CLR = 1; // Counter loeschen CLR = 0; A12 = 0; // A12 zuruecksetzen } void v_WriteVal(unsigned char ucVal) { P2M1 = 0x00; // Port 2 in Push-Pull P2M2 = 0xFF; P2 = ucVal; // Wert einschreiben // Schreibimpuls erzeugen (Inhalt von P2 wird eingeschrieben) _CS1 = 0; _WE = 0; _WE = 1; _CS1 = 1; CLK = 0; CLK = 1; // auf naechste Adresse setzen } unsigned char uc_ReadVal(void) { unsigned char ucResult; P2M2 = 0x00; // Quasi-Bidir. P2M1 = 0x00; P2 = 0xFF; // Port freigeben _WE = 1; _CS1 = 0; ucResult = P2; // Wert einlesen _CS1 = 1; CLK = 0; CLK = 1; // auf naechste Adresse setzen return (ucResult); } void main(void) { unsigned int uiLoop; P0M1 = P0M1 & 0x13; // Port 0 in Push-Pull P0M2 = P0M2 | 0xEC; P0 = P0 | 0xEC; // Portpins auf 1 setzen v_ClearCnt(); // Speicher mit Werten beschreiben

Page 104: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

104 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

for (uiLoop = 0; uiLoop < SRAMSIZE; uiLoop++) { v_WriteVal((unsigned char)uiLoop); if (uiLoop == 4096) A12 = 1; } v_ClearCnt(); // Speicher auslesen und Werte ueberpruefen for (uiLoop = 0; uiLoop < SRAMSIZE; uiLoop++) { if (uc_ReadVal() != (unsigned char) uiLoop) { // Haelt im Fehlerfall an, wenn ein RAM-Inhalt while(1); // nicht dem erwarteten Wert entspricht. } if (uiLoop == 4096) A12 = 1; } while(1); }

Listing 56 Inhalt von TestExtRAM.c

Das Schreiben und Lesen kann noch optimiert werden, wenn der Port P2 nicht ander-weitig benutzt wird. In diesem Fall kann die Umschaltung des Ports zwischen Quasi-Bidirektional und Push-Pull (siehe und ) vor dem Schleifendurchlauf (siehe und

) erfolgen.

2.13 Ansteuerung von Schrittmotoren mit dem IMT901 !! Dieser Abschnitt ist nur für die Vollversion des LPC-Experimentierboards relevant, bzw. wenn sie eine eigene Hardwarebeschaltung mit dem IMT901 (z. B. SMC42-Mo-dul) verwenden. !!

Die Firma Nanotec (www.nanotec.de) bietet den sehr leistungsfähigen Schrittmotorbau-stein IMT901 an. Dieser lässt sich sehr einfach vom µController, in diesem Fall vom P89LPC932, ansteuern. Eine ausführliche Beschreibung und die notwenige Hardwarebe-schaltung zum IMT 901 finden sie im Kapitel 12.6 [2]. Erstellen sie ein Projekt, das die Geschwindigkeit des Schrittmotors regelt. Die Regelung soll über den Inkrementalgeber vorgenommen werden. Die aktuelle Frequenz soll auf der 7-Segment-Anzeige ausgegeben werden.

!! Die Werte für die Grenzfrequenzen sind dem Datenblatt des jeweiligen Schritt-motors zu entnehmen. !!

Projektname Verzeichnis Verwendete Sourcemodule TestIMT901 Test_IMT901 Test_IMT901.c

..\Library PortConfig.c, Encoder_Lib.c, TimerLibrary.c, I2C_Lib.c,

SAA1064_Lib.c Tabelle 61 Projekt TestIMT901

Page 105: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 105

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Die Grenzgeschwindigkeiten sind in den #define-Anweisungen „GRENZ_U“ und „GRENZ_O“ enthalten (siehe Listing 57, ). In „PCLK“ (siehe ) ist die Frequenz von PCLK eingetragen. In diesem Fall ist es der Wert bei Verwendung des RC-Oscillators. Wenn sie z. B. einen externen Quarz mit 12 MHz verwenden, muss der Wert „6000000“ eingetragen werden. In „RELOAD_TIME_U“ und „RELOAD_TIME“ wird der Reloadwert berechnet. Es wird von Betriebsart 1 eines Timers ausgegangen. In den nachfolgenden drei Definitionen (siehe ) werden die Portpins für die Ansteuerung des IMT901 definiert. In der Variablen „uiTime“ (siehe ) ist der Reloadwert für den Timer enthalten. In den lokalen Variablen von main() (siehe ) werden Zwischenwerte gespeichert, die für die Ausgabe auf der 7-Segment LED benötigt werden. Nachdem der Timer0 gestartet wurde (siehe ), läuft das Programm in der while-Schleife. In der Va-riablen „uiFreq“ (siehe ) wird aus dem Reloadwert die aktuelle Frequenz am Portpin „btCLk“ ermittelt. Um den Wert auf der 7-Segment LED ausgeben zu können, muss er voher in ASCII konvertiert werden. Dies wird mit der Funktion „sprintf()“ erreicht (siehe ). Das Ergebnis der Wandlung wird im Array „ucBuf[]“ abgespeichert. Zudem gibt die Funktion zurück, wie viele Bytes gewandelt wurden. Dieser Wert wird in „ucLength“ gespeichert. Damit die Frequenzausgabe immer rechtsbündig ist, müssen noch führende Nullen eingefügt werden. Dies wird sehr einfach mit dem switch-case Konstrukt erreicht (siehe ). Im zweiten Konstrukt (siehe ) erfolgt die eigentliche Ausgabe der Frequenz. Vom gewandelten Wert wird der Wert 0x30 abgezogen, da die Funktion „v_ConvVal()“ nur binäre Übergabewerte verarbeitet.

#include <REG932.H> #include <PortConfig.H> #include <Encoder_Lib.h> #include <TimerLibrary.h> #include <I2C_LIB.H> #include <SAA1064_LIB.h> #include <stdio.h> #define GRENZ_U 300 // Hz ti/T = 0.5 #define GRENZ_O 1000 // Hz ti/T = 0.5 #define PCLK 3686400 // Hz (RC-Oscillator/2) = PCLK #define RELOAD_TIME_U ((PCLK/GRENZ_U)/2) #define RELOAD_TIME_O ((PCLK/GRENZ_O)/2) sbit btDir = P2^0; // Pin-Definitionen fuer die Ansteuerung sbit btEna = P2^1; // des IMT901. sbit btClk = P2^2; unsigned int uiTime = (0xFFFF - RELOAD_TIME_U); void main(void) { unsigned int uiFreq; // Hilfsvariablen für die Ausgabe unsigned char ucBuf[5], ucLength, ucOff; //auf der 7-Segment LED v_InitI2C(); v_InitEncoder();

Page 106: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

106 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

v_PortConfig(Port2, Pin0 | Pin1 | Pin2, PushPull); v_InitTimer0(MODE1 | TIMER); // Initialisierung des Timers 1 TH0 = uiTime/256; // Setzen des Reloadwertes TL0 = (unsigned char) uiTime; TF0 = 0; ET0 = 1; btDir = 0; // Initialisierung des IMT901 btEna = 1; btClk = 0; EA = 1; // allgemeine Interruptsperre aufheben v_InitSAA1064(DYNAMIC_MODE); TR0 = 1; // Timer 0 starten while(1) { // aktuelle Frequenz berechnen und ausgeben uiFreq = 0xFFFF - uiTime *2; uiFreq = PCLK / uiFreq; ucLength = sprintf(ucBuf,"%u", uiFreq); Slave.DataLen = 0; Slave.Adr = 0x70; // Adresse SAA1064 v_SetNextI2CVal(1); // Subadresse auf 1 (Daten-Byte) switch (ucLength) { case 0: v_ConvVal(0); case 1: v_ConvVal(0); case 2: v_ConvVal(0); case 3: v_ConvVal(0); } ucOff = 0; switch (ucLength) { case 4: v_ConvVal(ucBuf[ucOff++] - 0x30); case 3: v_ConvVal(ucBuf[ucOff++] - 0x30); case 2: v_ConvVal(ucBuf[ucOff++] - 0x30); case 1: v_ConvVal(ucBuf[ucOff++] - 0x30); } v_StartI2CandWait(); // Ausgabe auf dem SAA1064 while (cValue == 0); // Warten bis Encoder gedreht wurde if (cValue > 0 & uiTime < (0xFFFF - RELOAD_TIME_O)) uiTime++; else if (uiTime > (0xFFFF - RELOAD_TIME_U)) uiTime--; cValue = 0; } } // ISR fuer die Takterzeugung

Page 107: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 107

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

void v_Timer0Int(void) interrupt 1 { TH0 = uiTime/256; TL0 = (unsigned char) uiTime; btClk = !btClk; }

Listing 57 Inhalt von Test_IMT901.c

Auswertung des optischen Impulsgebers (HEDS-Familie) Optional werden die Schrittmotoren mit einem optischen 3-Kanal-Encoder ausgeliefert. Mit diesem Encoder wird überprüft, ob Schritte verloren gehen. Dies kann z. B. der Fall sein, wenn der Schrittmotor in die Eigenresonanz gerät, wenn die Taktfrequenz außer-halb des zulässigen Bereichs des Schrittmotors liegt oder wenn die Last am Motor zu groß ist. Als Impulsgeber wird der HEDL-5540 H14 von der Firma HP eingesetzt. Erstellen sie ein Projekt, bei dem der Inkrementalgeber des Schrittmotors ausgewertet wird. Sie können zur Vereinfachung das Projekt TestIMT901 in das neue Verzeichnis kopieren und die Dateien TestIMT901.uv2 und TestIMT901.opt umbenennen. Außer-dem muss unter „Options for Target“ im Reiter „Output“ der Eintrag im Feld „Name of Executable“ auf den Projektnamen „TestIMT901Enc“ angepasst werden. Werten sie für den ersten Test den Nulldurchgang des Inkrementalgebers aus. Wird der Nulldurchgang erkannt, werden die Impulse des btClk gezählt. Beim nächsten Null-durchgang wird überprüft, ob die Anzahl der Impulse mit dem Nulldurchgang überein-stimmen. Der Nulldurchgang soll mit dem externen Interrupt 1 ausgewertet werden. Die ISR überprüft auch die Anzahl der Impulse.

!! Aufbau und Funktionsweise der externen Interrupts sind in Kapitel 10 [3] beschrie-ben. !!

Projektname Verzeichnis Verwendete Sourcemodule TestIMT901Enc Test_IMT901Enc Test_IMT901Enc.c

..\Library PortConfig.c, Encoder_Lib.c, TimerLibrary.c, I2C_Lib.c,

SAA1064_Lib.c Tabelle 62 Projekt TestIMT901Enc

2.14 I²C-Bus EEPROMs Um Daten bzw. Konstanten auslagern zu können und dessen Zugriffszeit auf den Speicher nicht kritisch ist, werden in den meisten Applikationen für die Abspeicherung serielle EEPROMs verwendet. Diese Bausteine sind sehr günstig und bieten Speicherbereiche von 128 Byte (z. B. AT24C01) bis zu 128 kByte (z. B. AT24C1024) an. Für die folgende Beschreibung wird der AT24C256 mit einer Speichergröße von 32 kByte verwendet. Um diese zusätzliche Schaltung am Experimentierboard aufbauen zu können, wurde die Steckplatine TYP II verwendet. Die Bestellbezeichnung finden sie im Kapitel 2.21, Seite 153. Abbildung 55 enthält den Schaltungsaufbau für den AT24C256. Die Adressen A0 und A1 sind auf VCC gelegt. Somit lässt sich der Baustein auf der Adresse 0xA0 anspre-

Page 108: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

108 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

chen. Das Signal WP (Write Protect) ist mit GND verbunden. Somit kann der Baustein programmiert werden. Abbildung 56 enthält den zusätzlichen Aufbau mit der Steck-platine. Die Spannungsversorgung wird mit den Buchsen XVCC1 und GND (siehe rechte Bildseite) realisiert.

Abbildung 55 Schaltungsaufbau für den AT24C256 ( I²C EEPROM)

Abbildung 56 Aufbau der zusätzlichen Schaltung für das I²C EEPROM

Um zu überprüfen, ob sich das serielle EEPROM ansprechen lässt, verwenden sie das Projekt I2C_TEST.uv2 von Seite 40. Ist der Baustein korrekt angeschlossen, muss das Array „result“ die Einträge aus Abbildung 57 enthalten.

Page 109: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 109

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Abbildung 57 Watch & Call Stack Window mit AT24C256 I²C EEPROM (0xA0)

Es soll ein Projekt erstellt werden, das das EEPROM beschreibt und wieder ausliest. Der Schreibzyklus für das 24C256 EEPROM ist wie folgt aufgebaut: 1. Startbedingung 2. Schreiben der Baustein-Adresse (0xA0) 3. Schreiben der MSB Adresse 4. Schreiben der LSB Adresse 5. Schreiben eines oder mehrere Werte 6. Stoppbedingung Nachdem die Stoppbedingung gesetzt ist, muss gewartet werden, bis die interne Pro-grammierung beendet ist. Solange die Programmierung erfolgt, wird bei der Adressierung des EEPROMs ein „NACK“ zurückgesendet. Erst wenn ein „ACK“ zurückgeliefert wird, kann mit der nächsten Programmierung bzw. mit dem Auslesen des EEPROMs begonnen werden. Um das Ergebnis von ACK und NACK des EEPROMs auswerten zu können, muss die I²C-Library um die globale Variable ucI2CError erweitert werden (siehe Listing 59, ). Sie enthält den Status des I²C-Protokolls. Beim Start des Protokolls wird ucI2CError auf „I2C_OK“ gesetzt (siehe ). Wird in der ISR eine unerwartete case-Anweisung durch-laufen, wird ucI2CError auf einen Fehler gesetzt (siehe und ). Somit kann im Hauptprogramm mit Hilfe von ucI2CError überprüft werden, ob das I²C-Protokoll kor-rekt durchgeführt wurde. Die Definitionen für ucI2CError sind im H-File „I2C_LIB.h“ abgespeichert (siehe Listing 58, ).

// Aktueller Stand: V1.1 // Aenderungen bei: // V1.1: Variable ucI2CError eingefuehrt // Die Fehlercodes sind im enum-Feld enI2CERROR abgelegt. // Strukturdeklaration struct stI2C { unsigned char Adr; unsigned char DataLen; unsigned char Val[10]; }; enum enI2CERROR {I2C_OK, NACK_WRADR, NACK_WRDATA, UNDEFINED}; // Variablendeklarationen extern struct stI2C Slave;

Page 110: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

110 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

extern bit btI2cFinished; extern unsigned char ucI2CError; // Funktionsdeklarationen extern void v_InitI2C(void); extern void v_SetNextI2CVal(unsigned char ucVal); extern void v_StartI2CTrans(void); extern void v_WaitI2CFinish(void); extern void v_StartI2CandWait(void);

Listing 58 Inhalt von I2C_LIB.h

// Aktueller Stand: V1.1 // Aenderungen bei: // V1.1: Variable ucI2CError eingeführt #include <REG932.H> #include <I2C_LIB.H> #include <PortConfig.H> struct stI2C Slave; unsigned char ucI2CError; static bit btI2cFinished; void v_InitI2C(void) { // SDA und SCL als Open-Drain konfigurieren v_PortConfig(Port1, Pin3 | Pin4, OpenDrain); I2SCLH = 19; // I2C-Geschwindigkeit ~100 KHz I2SCLL = 19; I2CON = 0x44; // I2C-Hardware aktivieren EI2C = 1; // I2C Interrupt freigeben } void v_SetNextI2CVal(unsigned char ucVal) { Slave.Val[Slave.DataLen] = ucVal; Slave.DataLen++; } void v_WaitI2CFinish(void) { while (btI2cFinished == 0); } void v_StartI2CTrans(void) { btI2cFinished = 0; ucI2CError = I2C_OK; I2CON = 0x64; // Startbedingung setzen } void v_StartI2CandWait(void)

Page 111: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 111

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

{ btI2cFinished = 0; ucI2CError = I2C_OK; I2CON = 0x64; // Startbedingung setzen while (btI2cFinished == 0); // Auf Stoppbedingung warten } static 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; // Stoppbedingung setzen (STO =1) } break; case 0x20: // Status: "SLA+W gesendet, NACK empfangen" I2CON = 0x54; // Stoppbedingung setzen (STO =1) ucI2CError = NACK_WRADR; btI2cFinished = 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;

Page 112: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

112 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

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) ucI2CError = UNDEFINED; btI2cFinished = 1; break; } }

Listing 59 Auszug aus I2C_LIB.c

Nachdem sie die Anpassungen in der I²C-Library durchgeführt haben, erstellen sie das Projekt aus Tabelle 63. Es sollen auf die ersten vier Adressen im EEPROM die Werte 0x01 bis 0x04 abspeichert und danach die Werte zur Überprüfung ausgelesen werden. Nach dem Programmieren der Werte muss die Startadresse im EEPROM wieder gesetzt werden (siehe Listing 60, ). Bei diesem Setzen wird gleichzeitig überprüft, ob die Pro-grammierung des EEPROMs beendet ist. Ist dies nicht der Fall, wird die while-Schleife durchlaufen (siehe ). Erst wenn die Variable ucI2CError den Wert I2C_OK enthält, liefert das EEPROM ein „ACK“ zurück. Jetzt kann der Inhalt des EEPROMs wieder ausgelesen werden (siehe ). Das Ergebnis können sie sich im Watch- &Call Stack Window anzeigen lassen.

Projektname Verzeichnis Verwendete Sourcemodule I2C_EEPROM Test_I2C_EEPROM TestI2CEEPROM.c

..\Library PortConfig.c, I2C_Lib.c Tabelle 63 Projekt I2C_EEPROM

#include <REG932.H> #include <I2C_LIB.H> #include <PortConfig.H> void main(void) { v_InitI2C(); EA = 1; // Werte in das EEPROM schreiben Slave.Adr = 0xA0; // Adresse AT24C256 v_SetNextI2CVal(0x00); // Subadresse (MSB)

Page 113: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 113

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

v_SetNextI2CVal(0x00); // Subadresse (LSB) v_SetNextI2CVal(0x01); // Wert schreiben v_SetNextI2CVal(0x02); // Wert schreiben v_SetNextI2CVal(0x03); // Wert schreiben v_SetNextI2CVal(0x04); // Wert schreiben v_StartI2CandWait(); // Startadresse setzen v_SetNextI2CVal(0x00); // Subadresse (MSB) v_SetNextI2CVal(0x00); // Subadresse (LSB) v_StartI2CandWait(); // Warten bis EEPROM wieder bereit while (ucI2CError != I2C_OK) v_StartI2CandWait(); // Werte aus dem EEPROM auslesen Slave.Adr = 0xA0 + 1; // Adresse AT24C256 + RD Slave.DataLen = 4; // ein Bytes wird gelesen v_StartI2CandWait(); while(1); }

Listing 60 Inhalt von Test_I2C_EEPROM.c

Abbildung 58 Watch & Call Stack Window mit Ergebnis EEPROM lesen

Library-Funktionen für das Beschreiben von EEPROMs Für das Programmieren von EEPROMs ist es zweckmäßig, eine eigene Funktion zu er-stellen, die das Beschreiben des EEPROMs übernimmt. Diese Funktion soll auch in der Lage sein, die Programmierung von EEPROM-Pages zu unterstützen. Die Größe einer EEPROM-Page wird mit der Definition „PAGESIZE“ angegeben (siehe Listing 61, ). Die Berechnung der noch zu beschreibenden EEPROM-Page wird mit der Modulo-Operation durchgeführt (siehe ).

!! Vergessen sie nicht, das Array in der Deklaration der I²C-Struktur „stI2C“ (H-File I2C_LIB.h) auf die Größe der EEPROM-Page anzupassen. !!

In der ersten while-Schleife (siehe ) wird auf die Anzahl der noch zu schreibenden Werte geprüft. Solange „ucLen” ungleich “0” ist, wird diese Schleife wiederholt. In der zweiten Schleife wird eine zusätzliche Überprüfung auf die Pagegrenze durchgeführt (siehe ). Die innere while-Schleife wird erst verlassen, wenn entweder ucLen den Wert

Page 114: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

114 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

„0“ enthält oder die Pagegrenze erreicht ist. Ist eine der beiden Bedingungen eingetreten, wird die EEPROM-Page beschrieben (siehe ). Mit diesem Schleifenaufbau wird auch sichergestellt, dass die innere I²C-Struktur „Slave“ nicht überschrieben wird. Im Testbeispiel wird der Inhalt vom Array „ucStartBuf“ (siehe Listing 62, ) in das EEPROM ab der Adresse 0x00FE mit Hilfe der Funktion „uc_Data2I2C_EEPROM()“ geschrieben (siehe ). Mit der Funktion „uc_I2C2Data()“ wird der Inhalt ab der Adres-se 0x00FB ausgelesen (siehe ). Die Anzahl der zu lesenden Bytes wird mit dem ersten Byte im Array „ucResBuf“ festgelegt (siehe ).

Projektname Verzeichnis Verwendete Sourcemodule Test_I2C_EEPROM_LIB Test_I2C_EEPROM_LIB TestEEPROM_Lib.c

..\Library PortConfig.c, I2C_Lib.c I2C_EEPROM_Lib.c

Tabelle 64 Projekt Test_I2C_EEPROM_LIB

#include <I2C_LIB.H> #include <I2C_EEPROM_LIB.h> #define PAGESIZE 64 unsigned char uc_Data2I2C_EEPROM(unsigned char ucI2CDev, unsigned int uiI2CAddr, unsigned char *pucSrc) { unsigned char ucLen = *pucSrc; unsigned char ucPageOffset; pucSrc++; Slave.Adr = ucI2CDev; while (ucLen) { ucPageOffset = uiI2CAddr % PAGESIZE; v_SetNextI2CVal(uiI2CAddr/256); // Subaddr.(MSB) v_SetNextI2CVal((unsigned char)uiI2CAddr); // Subaddr.(LSB) while(ucLen && ucPageOffset < PAGESIZE) { v_SetNextI2CVal(*pucSrc); pucSrc++; ucPageOffset++; uiI2CAddr++; ucLen--; } v_StartI2CandWait(); // Warten bis Schreiben einer Page beendet v_StartI2CandWait(); while(ucI2CError != I2C_OK) v_StartI2CandWait(); } return (ucI2CError); }

Listing 61 Auszug aus I2C_EEPROM_Lib.c

Page 115: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 115

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

#include <REG932.H> #include <PortConfig.H> #include <I2C_LIB.H> #include <I2C_EEPROM_LIB.h> unsigned char xdata ucStartBuf[100]={16, "123-Hello World"}; unsigned char xdata ucResBuf[100]; void main(void) { v_InitI2C(); EA = 1; uc_Data2I2C_EEPROM(0xA0, 0xfe, ucStartBuf); ucResBuf[0] = 20; uc_I2C2Data(0xA0, 0xfe, ucResBuf); while(1); }

Listing 62 Inhalt von TestEEPROM_Lib.c

2.15 Ansteuerung von Reed-Relais Ein Reed-Relais besteht aus einer Spule und einem Reedkontakt. Der Spulendraht ist um den Reedkontakt gewickelt. Fließt durch die Spule ein Strom, wird der Reedkontakt durch die erzeugte Magnetkraft betätigt. Das Reed-Relais hat eine wesentlich kleinere Bauform als ein normales Relais, kann aber nur bis zu 100 V betrieben werden und maximal 2 A schalten. Das Reed-Relais hat durch seinen Aufbau eine Schaltleistung von 100 Millionen Schaltspielen. Die maximale Schaltfrequenz beträgt 300 Hz. Bauen sie die Schaltung aus Abbildung 59 auf. Da der Pullup Widerstand des Taster S16 zu hochohmig (10 k) ist, muss das Reed-Relais über die Relais-Schaltung angesteuert werden. Wird die Taste betätigt, schließt sich der Kontakt im Reed-Relais und die LEDB0 in der LED-Zeile leuchtet auf.

!! Die dick eingezeichneten Linien stellen die Steckverbindungen dar. !! !! Das Reed-Relais können sie z. von Conrad Best-Nr. 504572-14. !!

Abbildung 59 Aufbau einer Reed-Relais Schaltung mit einem Taster

Page 116: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

116 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Abbildung 61 enthält die Steckverbindungen für die Reed-Relais Schaltung.

Abbildung 60 Steckverbindungen für die Reed-Relais Schaltung

Erstellen sie ein Programm, das das Reed-Relais anstatt über den Taster mit dem Portpin P2.0 ansteuert. Die Schaltung muss wie in Abbildung 61 aufgebaut werden. Der Portpin kann in der Betriebsart „Quasi-Bidirektional“ betrieben werden.

Abbildung 61 Aufbau einer Reed-Relais Schaltung mit dem Portpin P2.0

Page 117: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 117

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Für den Portpin P2.0 wird eine sbit-Deklaration verwendet (siehe Listing 63, ). Die Be-triebsart „Quasi-Bidirektional“ wird mit der Funktion „v_PortConfig()“ eingestellt (siehe

). In der while-Schleife wird jetzt das Reed-Relais ein- und ausgeschaltet (siehe ). Damit die Schaltfrequenz klein ist, wird die Variable „uiLoop“ hochgezählt (siehe ).

Projektname Verzeichnis Verwendete Sourcemodule Test_ReedRelais Test_ReedRelais TestReedRelais.c

..\Library PortConfig.c Tabelle 65 Projekt Test_ReedRelais

#include <REG932.H> #include <PortConfig.H> sbit sbReedRel = P2^0; void main(void) { unsigned int uiLoop; v_PortConfig(Port2, Pin0, BiDir); while(1) { sbReedRel = !sbReedRel; for (uiLoop=0; uiLoop < 65000; uiLoop++); } }

Listing 63 Inhalt von TestReedRelais.c

Für die Reed-Relais wird eine Ansprechzeit und eine Prellzeit angegeben. Diese liegt je nach verwendetem Typ zwischen 0,5 und 2 ms. Abbildung 62 zeigt das Verhalten des Typs „3563 1231 053“ (1 Umschalter).

Abbildung 62 Ansprech-/Prellzeit beim Reed-Relais

Erstellen sie ein Programm, das die Ansprechzeit des Reed-Relais (Zeit zwischen H-L-Flanke des Ports und H-L-Flanke an Pin 1 des Relais: 301µs in Abbildung 62) ermittelt. Verwenden sie für die Messung der Zeit den Timer 1. Der Timer 1 soll gestoppt werden, wenn am Reed-Relais eine fallende Flanke erkannt wird. Dieses Verhalten kann mit der Gate-Funktion des Timers 1 realisiert werden. In der ISR des externen Interrupts 1 soll

Page 118: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

118 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

die Ansprechzeit ermittelt werden. Für das Abspeichern der Ansprechzeit wird eine globale Variable verwendet (siehe Listing 64, ). Der Timer 1 wird in der Betriebsart 1 (16-bit Timer) betrieben (siehe ). Der externe Interrupt 1 wird auf „fallende Flanke“ eingestellt und freigegeben (siehe ). Nach der Aktivierung des Reed-Relais (siehe ) wird der Timer 1 gestartet (siehe ). Das Programm befindet sich nun solange in der while(1)-Schleife, bis eine fallende Flanke am externen Interrupt 1 anliegt. In der ISR wird zuerst der Timer 1 gestoppt (siehe ). Danach wird die Ansprechzeit ermittelt. Ein Timerwert entspricht 1 PCLK (0.27µs bei CCLK = 7.3728 MHz). Da bei der 4k-Version keine float-Arithmetik zugelassen ist, kann die Zeit auch über eine Multiplikation und Division errechnet werden (siehe ). In der Variablen ist der gerundete Wert in µs abgespeichert.

!! Eine ausführliche Beschreibung zur Gate-Funktion des Timers 0/1 finden sie im „Kapitel 10.10 Timer 0/1 [3]“.

Projektname Verzeichnis Verwendete Sourcemodule Mess_ReedRelais Mess_ReedRelais MessReedRelais.c

..\Library PortConfig.c, TimerLibrary.c Tabelle 66 Projekt Mess_ReedRelais

#include <REG932.H> #include <PortConfig.H> #include <TimerLibrary.H> sbit sbReedRel = P2^0; unsigned int uiDelayTime = 0; void main(void) { sbReedRel = 1; v_PortConfig(Port2, Pin0, BiDir); v_InitTimer1(MODE1 | TIMER); IT1 = 1; // getriggert auf fallende Flanke EX1 = 1; // ext. Interrupt 1 freigeben EA = 1; sbReedRel = 0; TR1 = 1; // Timer starten while(1); } void v_ExtInt1(void) interrupt 2 { TR1 = 0; uiDelayTime = TH1 * 256 + TL1; uiDelayTime = (uiDelayTime * 27)/100; // Berechnung in µs }

Listing 64 Inhalt von MessReedRelais.c

Page 119: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 119

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Erweitern sie das Projekt Mess_ReedRelais so, das die Ansprechzeit auf der 7-Segment LED in µs ausgegeben wird.

!! Da die Ausgabe auf der 7-Segment LED muss außerhalb der ISR vom externen Interrupt 2 erfolgen, weil die I²C-Funktionen auch mit einer ISR arbeiten. !!

Um zu erkennnen, dass die ISR des externen Interrupts 2 abgearbeitet ist, wird die globa-le Variable btFinish benötigt (siehe Listing 65, ). Diese wird nach dem Start des Timers 1 gelöscht (siehe ). Danach wird solange gewartet, bis die ISR durchlaufen wurde (siehe ). Am Ende der ISR wird die Variable auf „1“ gesetzt (siehe ). Der Wert wird jetzt in Dezimal umgerechnet (siehe ).

Projektname Verzeichnis Verwendete Sourcemodule Mess_ReedRelais Mess_ReedRelais MessReedRelais.c

..\Library PortConfig.c, TimerLibrary.c, I2C_LIB.c, SAA1064_LIB.c

Tabelle 67 Projekt Mess_ReedRelais (erweitert um Ausgabe auf 7-Segment LED)

#include <REG932.H> #include <PortConfig.H> #include <TimerLibrary.H> #include <I2C_LIB.H> #include <SAA1064_LIB.h> sbit sbReedRel = P2^0; unsigned int uiDelayTime = 0; bit btFinish; void main(void) { sbReedRel = 1; v_PortConfig(Port2, Pin0, BiDir); v_InitTimer1(MODE1 | TIMER); v_InitI2C(); IT1 = 1; // getriggert auf fallende Flanke EX1 = 1; // ext. Interrupt 1 freigeben EA = 1; v_InitSAA1064(DYNAMIC_MODE); sbReedRel = 0; TR1 = 1; // Timer starten btFinish =0; while(btFinish == 0); Slave.DataLen = 0; Slave.Adr = 0x70; // Adresse SAA1064 v_SetNextI2CVal(1); // Subadresse auf 1 (Daten-Byte) v_ConvVal(uiDelayTime/1000); // Umrechnung (MSB) uiDelayTime = uiDelayTime % 1000; v_ConvVal(uiDelayTime/100); uiDelayTime = uiDelayTime % 100; v_ConvVal(uiDelayTime /10);

Page 120: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

120 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

uiDelayTime = uiDelayTime % 10; v_ConvVal(uiDelayTime); // Umrechnung des Reloadwertes (LSB) v_StartI2CandWait(); while(1); } void v_ExtInt1(void) interrupt 2 { TR1 = 0; uiDelayTime = TH1 * 256 + TL1; uiDelayTime = (uiDelayTime * 27)/100; // Berechnung in µsec btFinish = 1; }

Listing 65 Inhalt von MessReedRelais.c

2.16 Library für die serielle Schnittstelle In Kapitel 2.2, Abschnitt RS232-Verbindung (Seite 19) wurde schon einmal auf die seri-elle Schnittstelle eingegangen. In diesem Kapitel soll eine Library erstellt werden, mit der die Kommunikation von und zum PC ermöglicht wird. Die Library soll Funktionen zur Initialisierung des UARTs sowie das Senden und Empfangen mit Hilfe des UART-Interrupts enthalten. Die Funktionen für die serielle Schnittstelle sind in der RS232Lib.c abgelegt. Für die Übergabeparameter (Baudrate, Betriebsart des UARTs, usw.) werden Felder des Aufzählungstyps enum angelegt (siehe Listing 66, ). Somit sind die Übergabeparameter besser zu lesen, da nicht der Reloadwert, sondern die Baudrate angegeben wird. Der Unterstrich vor dem Wert z. B. „_300“ ist nötig, da eine Konstante nicht mit einem numerischen Wert beginnen darf.

!! Die Berechnung der Reloadwerte können sie den Formeln aus dem Kapitel 10.11 UART, „Abschnitt Baudraten erzeugen“ [3] entnehmen. !!

Die Funktion „uc_Init_Serial()“ übernimmt die Initialisierung des UARTs (siehe Listing 67, ). Im ersten Übergabeparameter wird die Baudrate und im zweiten Parameter die Betriebsart übergeben. Als nächstes wird der Baudratengenerator gestoppt und das SM1 Flag im SFR PCON für die Initialisierung der Betriebsart freigegeben (siehe ). Es folgt das Setzen der Betriebsart und die Initialisierung des Baudratengenerators (siehe ). Zum Schluss wird der Baudratengenerator gestartet und das SM1 für die Erkennung des „Framing Error“ freigegeben (siehe ). Die Funktionsweise des „Framing Error“ können sie im Kapitel 10, Abschnitt „Framing Error“ [3] nachlesen. Für das Senden eines Zeichens bzw. einer Zeichenkette wird die Struktur RS232BUF verwendet. Der Aufbau der Struktur befindet sich im H-File RS232Lib.h (siehe Listing 66, ). Er entspricht der LV-Codierung. Im ersten Byte wird die Länge der Daten abgespeichert. Das Array „ucBuf[]” enthält die Daten. Es können bis zu 16 Bytes gespeichert werden. Sollen mehr Bytes gespeichert werden, ist der Index des Arrays zu erhöhen. Für das Senden bzw. Empfangen stehen zwei separate Strukturen (stRecRS232, stSendRS232) zur Verfügung. Somit kann gleichzeitig gesendet und Empfangen werden. Erstellen sie das Projekt aus Tabelle 68. Der Start eines Sendevorgangs wird mit Hilfe der Funktion „uc_SendRS232()“ eingeleitet. Dieser Funktion wird die Startadresse des zu

Page 121: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 121

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

sendenden Bytes bzw. der Zeichenkette und die Länge übergeben (siehe ). Der Start-vorgang des Sendens wird mit einem Schreibzugriff in das SFR SBUF begonnen (siehe

). In der ISR wird mit Hilfe des RI-Flags (siehe ) zuerst überprüft, ob ein Zeichen empfangen wurde. Ist dies der Fall, wird der Wert aus SBUF ausgelesen und in das Array der Struktur „stRecRS232“ geschrieben. Der Offsetzeiger für die Verwaltung des Arrays (stRecRS232.ucLen) wird danach um eins erhöht (siehe ).

!! Zum Schluss muss noch das RI-Flag gelöscht werden, da es nicht per Hardware zu-rückgesetzt wird. !!

Danach wird geprüft, ob das TI-Flag gesetzt ist (siehe ). Ist dies der Fall, kann ein neues Zeichen gesendet werden. Mit Hilfe der Variablen „ucSendOffset“ wird überprüft, ob noch Zeichen gesendet werden müssen (siehe ). Ist dies der Fall, wird das nächste Zeichen in das SFR SBUF geschrieben und „ucSendOffset“ um eins erhöht. Sind schon alle Zeichen gesendet worden, wird „stSendRS232.ucLen“ auf „0“ gesetzt (siehe ). So-mit kann vom Hauptprogramm erkannt werden, dass alle Zeichen aus dem Array ausge-sendet worden sind.

!! Am Ende muss noch das TI-Flag gelöscht werden, da es nicht per Hardware zu-rückgesetzt wird. !!

Projektname Verzeichnis Verwendete Sourcemodule RS232Library Test_RS232Lib Test_RS232Lib.c

..\Library RS232Lib.c, PortConfig.c Tabelle 68 Projekt RS232Library

// Definitionen // Berechnung Reloadwert fuer Baudratengenerator bei 7.3728 MHz enum enUARTBaudrate { _600= 0x2FF0, _1200= 0x17F0, _2400= 0x0BF0, _4800= 0x05F0, _9600= 0x02F0, _19200=0x0170, _38400= 0x00B0,_57600= 0x0070,_115200= 0x0030}; enum enUARTConfig { _8BIT= 0x40, _9BIT= 0xC0}; struct RS232BUF { unsigned char ucLen; unsigned char ucBuf[16]; }; // Funktionsdeklarationen extern unsigned char uc_Init_Serial(unsigned int uiBaudRate, unsigned char ucUARTMode); extern unsigned char uc_SendRS232(unsigned char * ucPtr, unsigned char ucLen); // Variablendeklarationen extern struct RS232BUF stRecRS232, stSendRS232;

Listing 66 Inhalt von RS232Lib.h

#include <REG932.H> #include <RS232Lib.H>

Page 122: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

122 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

#include <string.h> struct RS232BUF stRecRS232, stSendRS232; unsigned char ucSendOffset; // Funktion fuer Baudratengenerator unsigned char uc_Init_Serial(unsigned int uiBaudRate, unsigned char ucUARTMode) { PCON = PCON & 0xBF; // SMOD0 (SFR PCON) auf "0" setzen BRGCON = 0x02; // Baudratengenerator stoppen SCON = ucUARTMode; // Betriebsart (8/9-bit), Flags loeschen BRGR1 = uiBaudRate /256; // Baudrate setzen BRGR0 = (unsigned char)uiBaudRate; BRGCON = 0x03; // Baudratengenerator starten PCON = PCON | 0x40; // SMOD1 (SFR PCON) auf "1" setzen stRecRS232.ucLen = 0; ES = 1; // Freigabe der ser. Schnittstelle return(0); } unsigned char uc_SendRS232(unsigned char * ucPtr, unsigned char ucLen) { if (ucLen == 0 || ucLen > 16) // Laengenueberpruefung return -1; stSendRS232.ucLen = ucLen; memcpy(stSendRS232.ucBuf, ucPtr, ucLen); SBUF = stSendRS232.ucBuf[0]; ucSendOffset = 1; return 0; } void v_IntSer(void) interrupt 4 using 1 { if (RI) // wurde Zeichen empfangen ? { if (stRecRS232.ucLen < 16) // Ueberpruefung auf Ueberlauf { stRecRS232.ucBuf[stRecRS232.ucLen] = SBUF; stRecRS232.ucLen++; } RI = 0; } if (TI) { if (ucSendOffset < stSendRS232.ucLen) {

Page 123: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 123

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

SBUF = stSendRS232.ucBuf[ucSendOffset]; ucSendOffset++; } else stSendRS232.ucLen =0; // alle Daten sind gesendet TI = 0; } }

Listing 67 Inhalt von RS232Lib.c

Um die RS232-Library verwenden zu können, muss das H-File mit inkludiert werden (siehe Listing 68, ). Der zu sendende Text ist in diesem Beispiel im code-Bereich abge-legt (siehe ). Die Konfiguration der Portpins für die serielle Schnittstelle wird mit Hilfe der Funktion „v_PortConfig()“ durchgeführt (siehe ). Die serielle Schnittstelle wird mit 9600 Baud und 8 Bit konfiguriert (siehe ). Die Freigabe der ISR sowie des Em-pfängers erfolgt im Hauptprogramm (siehe ). Der Sendevorgang wird mit dem Aufruf der Funktion „uc_SendRS232()“ gestartet (siehe ). Der sizeof()-Operator ermittelt die Größe des zu sendenden Bereichs. Er kann auf Arrays, Datentypen und Zeichenketten angewendet werden.

#include <REG932.H> #include <PortConfig.H> #include <RS232Lib.H> unsigned char code ucInfo[]={"Test der RS232"}; void main(void) { // Konfiguration der Portpins (UART) v_PortConfig(Port1, Pin0 | Pin1, BiDir); // Initialisierung der seriellen Schnittstelle uc_Init_Serial(_9600, _8BIT); // Interrupt Konfiguration EA = 1; // allg. Interruptfreigabe // Freigabe des Empfangsteils (UART) REN = 1; uc_SendRS232(&ucInfo, sizeof(ucInfo)); while(stSendRS232.ucLen != 0); // Warten bis alle Zeichen ausge- // sendet sind. while(1); }

Listing 68 Inhalt von Test_RS232.c

Um zu überprüfen, ob ein oder mehrere Zeichen empfangen wurden, muss der Wert aus „stRecRS232.ucLen“ überprüft werden (siehe Listing 69, ). Sind Zeichen vorhanden, können die Daten aus der Struktur ausgelesen werden.

Page 124: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

124 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

if (stRecRS232.ucLen) // Daten sind empfangen worden { }

Listing 69 Auswertung des Empfangsbuffers

Automatische Reloadberechnung Die im enum-Feld abgelegten Werte sind für die interne RC-Frequenz von 7,3728 MHz ausgelegt. Wird z. B. ein externer Quarz mit 12 MHz verwendet, müssen die Reloadwerte im enum-Feld neu angepasst werden. Die Anpassung auf die jeweilige Frequenz kann mit Hilfe einer #define-Anweisung und einer Berechnung erfolgen (siehe Listing 70, ).

#define XTAL 7372800L // Frequenzangabe enum enUARTBaudrate { _600=(XTAL/600) -16, _1200=(XTAL/1200) -16, _2400=(XTAL/2400) -16, _4800=(XTAL/4800) -16, _9600=(XTAL/9600) -16, _19200=(XTAL/19200)-16, _38400=(XTAL/38400) -16, _57600=(XTAL/57600)-16, _115200=(XTAL/11520)-16};

Listing 70 Berechnung der Reloadwerte mit Hilfe einer #define-Anweisung

Wird eine andere Frequenz verwendet, muss nur die Definition von XTAL angepasst werden. Die CPU-Frequenz kann aus den Projekt Settings ausgelesen werden. Die unter Options for Target, Reiter Target im Eingabefeld XTAL eingetragene Frequenz (siehe Abbildung 63) kann auch vom C-Compiler genutzt werden. Dieser Wert kann mit Hilfe der Makro Konstanten %%CPU_XTAL ausgelesen werden (siehe Listing 71, ).

!! Der Aufbau dieser Makro-Konstanten kann im Kapitel 5, Abschnitt Konstanten, [1] nachgelesen werden. !!

Abbildung 63 Options for Target, Reiter Target

#define %%CPU_XTAL // Berechnung Reloadwert fuer Baudratengenerator bei 7.3728 MHz enum enUARTBaudrate { _600=(CPU_XTAL/600)-16, _1200=(CPU_XTAL/1200) -16, _2400=(CPU_XTAL/2400) -16,_4800=(CPU_XTAL/4800) -16, _9600=(CPU_XTAL/9600) -16,_19200=(CPU_XTAL/19200)-16, _38400=(CPU_XTAL/38400) -16,_57600=(CPU_XTAL/57600)-16, _115200=(CPU_XTAL/115200)-16};

Listing 71 Berechnung der Reloadwerte mit Hilfe der Makro-Konstanten

Die Makro-Konstanten haben den Vorteil, dass die Library-Funktionen nicht verändert werden müssen und somit die Funktionen in mehreren Projekten verwendet werden können.

Page 125: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 125

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Die Taktfrequenz CCLK für die Versorgung des UARTs kann mit Hilfe des SFRs DIVM beeinflusst werden. Dies ist z. B. der Fall, wenn der Chip Strom sparen soll. In diesem Fall muss der Reloadwert in Abhängigkeit von DIVM ermittelt werden. Die For-mel für die Berechnung des Reloadwertes lautet wie folgt:

Abbildung 64 Berechnung der Baudrate mit dem Baudratengenerator

Da jetzt die Baudrate und nicht mehr der Reloadwert an die Funktion zur Initialisierung des UARTs übergeben wird, kann der Übergabeparameter „ucBaudRate“ auf den Daten-typ „unsigned char“ reduziert werden (siehe Listing 72, ). Die Werte im Aufzählungs-typ „enUARTBaudrate“ sind so angelegt, das sich die Baudraten auf ein Vielfaches von 600 beziehen (siehe ). Mit dieser Vorgehensweise lässt sich die Berechnung des Reloadwertes sehr stark vereinfachen (siehe Listing 72, ). Der cast auf unsigned long wird benötigt, da Zwischenergebnisse größer als 16 Bit sein können.

!! Die Funktionsweise des cast-Operators wird im Kapitel 14, „Typkonvertierung“ [1] ausführlich behandelt. !!

Projektname Verzeichnis Verwendete Sourcemodule RS232DynLibrary Test_RS232DynLib Test_RS232DynLib.c

..\Library RS232DynLib.c, PortConfig.c Tabelle 69 Projekt RS232DynLibrary

unsigned char uc_Init_Serial(unsigned char ucBaudRate, unsigned char ucUARTMode) { unsigned int uiReload; PCON = PCON & 0xBF; // SMOD0 (SFR PCON) auf "0" setzen BRGCON = 0x02; // Baudratengenerator stoppen SCON = ucUARTMode; // Betriebsart (8/9-bit), Flags loeschen uiReload = CPU_XTAL/((unsigned long)(ucBaudRate *600) * (DIVM + 1 )) -16; BRGR1 = uiReload /256; // Baudrate setzen BRGR0 = (unsigned char)uiReload; BRGCON = 0x03; // Baudratengenerator starten PCON = PCON | 0x40; // SMOD1 (SFR PCON) auf "1" setzen stRecRS232.ucLen = 0; ES = 1; // Freigabe der ser. Schnittstelle return(0); }

Listing 72 Auszug aus RS232DynLib.c

Da die Abweichung der Baudrate bei der RS232-Verbindung zwischen Sender und Emp-fänger maximal ± 5 % Abweichung haben darf (siehe EIA-232-D), sollte bei der Berech-nung des Reloadwertes überprüft werden, ob die erzeugte Baudrate noch innerhalb die-ser Toleranz liegt. Die Überprüfung kann dadurch erfolgen, indem die Baudrate anhand

Page 126: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

126 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

des Reloadwertes ermittelt wird. Unter dem folgenden Link finden sie noch weitere In-formationen zur RS232-Schnittstelle: http://www.camiresearch.com/Data_Com_Basics/RS232_standard.html

Arbeiten mit der Funktion printf() Die Funktion „printf()“ ist ein Bestandteil der C-Library. Mit dieser Funktion können Variable und Konstanten formatiert und der dadurch entstandene Text ausgegeben werden. Die Ausgabe erfolgt per default über die serielle Schnittstelle. Damit Anpassun-gen mit der Ausgabe vorgenommen werden können, ruft „printf()“ ihrerseits die Funk-tion „putchar()“ auf. Auch diese Funktion ist in der C-Library vorhanden. Die Funktion arbeitet mit der XON/XOFF- Flusssteuerung. Die Funktionsweise dieser Flusssteue-rung ist in Kapitel 3, Abschnitt „XON/XOFF-Protokoll“ [2] ausführlich beschrieben.

#define XON 0x11 #define XOFF 0x13 /* * putchar (full version): expands '\n' into CR LF and handles * XON/XOFF (Ctrl+S/Ctrl+Q) protocol */ char putchar (char c) { if (c == '\n') { if (RI) { if (SBUF == XOFF) { do { RI = 0; while (!RI); } while (SBUF != XON); RI = 0; } } while (!TI); TI = 0; SBUF = 0x0d; /* output CR */ } if (RI) { if (SBUF == XOFF) { do { RI = 0; while (!RI); } while (SBUF != XON); RI = 0; } } while (!TI); TI = 0; return (SBUF = c);

Page 127: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 127

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

}

Listing 73 Auszug aus Putchar.c

In Abbildung 65 ist der Ablauf beim Compilieren und Linken dargestellt. Der C-Compiler erzeugt ein OBJ-File. Dieses enthält einen Aufruf zur Funktion „_printf()“. Der Unterstrich vor dem Funktionsnamen gibt an, dass der Funktion Parameter in Registern übergeben werden (siehe Kapitel 8.8 „Aufbau von Funktionsnamen“ [1]). Der Linker findet diesen Funktionsaufruf und sucht nach einem Einsprung mit diesem Label im OBJ-File. Wenn er dieses Label nicht finden kann, sucht er in der Library nach diesem. Wenn er das Label gefunden hat, in diesem Fall „_printf“, nimmt der Compiler den entsprechenden Programmteil und fügt ihn zum Programm hinzu. Da „_printf“ seinerseits noch „putchar“ aufruft, wird auch dieser Programmteil aus der Library geholt und zum Projekt hinzugefügt.

Abbildung 65 Funktionsweise Compiler, Linker, Library

Soll die Funktion „putchar()“ an die eigenen Wünsche angepasst werden (z. B. ohne XON-/OFF-Steuerung), muss die Funktion mit in das C-Modul aufgenommen werden. Der Linker verwendet dann diese Funktion für den Aufruf aus „_printf“. Erstellen sie ein Projekt, das die Ausgabe über die RS232-Schnittstelle mit Hilfe der Funktion „printf()“ vornimmt. Die Funktion „putchar()“ soll die Zeichen ohne Ände-rung und ohne XON-/XOFF-Steuerung aussenden (siehe Listing 74, ). In Tabelle 70 ist die Projektstruktur enthalten.

Projektname Verzeichnis Verwendete Sourcemodule RS232Printf Test_RS232Printf Test_RS232Printf.c

..\Library RS232Lib.c, PortConfig.c Tabelle 70 Projekt RS232Printf

#include <REG932.H> #include <rs232lib.h> #include <PortConfig.H> #include <stdio.h> void main(void) { // Konfiguration der Portpins (UART) v_PortConfig(Port1, Pin0 | Pin1, BiDir); // Initialisierung der seriellen Schnittstelle

Page 128: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

128 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

uc_Init_Serial(_9600, _8BIT); TI = 1; // Freigabe des Senderegisters printf("Test der RS232 mit printf()"); while(1); } char putchar (char c) { while (!TI); // Warten bis letztes Zeichen gesendet TI = 0; SBUF = c; // Zeichen wird ausgesendet return(0); }

Listing 74 Inhalt von Test_ RS232Printf.c

Die Ausgabe der Zeichen erfolgt ohne die ISR. In der Funktion „putchar()“ wird solange gewartet, bis TI wieder von der Hardware gesetzt wird (siehe ). Das Programm be-findet sich solange in der Funktion „printf()“, bis das letzte Zeichen ausgesendet wurde. Bei diesem Beispiel werden 27 Zeichen zu 10 Bit (Startbit + Daten + Stoppbit) gesendet. Bei der Übertragungsrate von 9600 Baud (104 µs/Bit) ergibt sich eine Übertragungszeit von 28.08 ms. Wird eine Baudrate von 300 Baud verwendet, so liegt die Übertragungs-zeit bei 898.56 ms. Um hier eine Unabhängigkeit zwischen der Ausgabe mit Hilfe der Funktion „printf()“ und der Übertragungsgeschwindigkeit der seriellen Schnittstelle zu erreichen, müssen die erzeugten Daten von „printf()“ in einem Ringbuffer zwischenge-speichert werden. Die ISR der seriellen Schnittstelle liest dann die Daten aus dem Ringbuffer aus und versendet sie. Die genaue Funktionsweise dieses Verfahrens ist in Kapitel 3, Abschnitt „Zeitunkritische Ausgaben unter Verwendung des seriellen Inter-rupts“ [2] ausführlich beschrieben.

Arbeiten mit der Funktion scanf() Auch die Funktion „scanf()“ ist ein Bestandteil der C-Library. Im Gegensatz zur Funk-tion „printf()“, die Daten formatiert und mit Hilfe der Funktion „putchar()“ ausgibt, liest „scanf()“ Daten mit Hilfe der Funktion „getkey()“ ein und weist sie der Variablen zu. Die Formatierung der Daten bei „scanf()“ ist identisch mit der Formatierung bei „printf()“. In Listing 75 (siehe ) wird ein Byte eingelesen und der Variablen „cA“ zu-gewiesen. Beim Aufruf der Funktion „scanf()“ wird jetzt solange die Funktion „_getkey()“ (siehe Listing 76, ) aufgerufen, bis alle benötigten Daten empfangen wur-den. In „_getkey()“ wird jetzt solange das RI-Flag gepollt (siehe ), bis dieses den Wert „1” annimmt. Der Wert wird aus dem Empfangsbuffer SBUF ausgelesen und der Varia-blen „c“ zugewiesen (siehe ). Danach wird das RI-Flag wieder auf „0“ gesetzt.

Projektname Verzeichnis Verwendete Sourcemodule RS232Scanf Test_RS232Scanf Test_RS232Scanf.c

..\Library RS232Lib.c, PortConfig.c Tabelle 71 Projekt RS232Scanf

Page 129: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 129

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

#include <REG932.H> #include <rs232lib.h> #include <PortConfig.H> #include <stdio.h> void main(void) { char cA; // Konfiguration der Portpins (UART) v_PortConfig(Port1, Pin0 | Pin1, BiDir); // Initialisierung der seriellen Schnittstelle uc_Init_Serial(_9600, _8BIT); REN=1; // Freigabe des Empfangs scanf("%c",&cA); while(1); }

Listing 75 Inhalt von Test_ RS232Printf.c

char _getkey () { char c; while (!RI); c = SBUF; RI = 0; return (c); }

Listing 76 Inhalt von \c51\lib\Getkey.c

2.17 Arbeiten mit dem RTC Allgemeines Da der RTC (Real-Time-Clock) in der LPC900-Familie nur als 16-bit Down-Counter aufgebaut ist, müssen entsprechende Routinen für das Umsetzen in Stunden-/Tagesberechnung selbst durchgeführt werden. Da die Genauigkeit des internen RC-Oscillators bei ± 2,5 % liegt, kann schon nach 5 Stunden eine Abweichung von ± 8 min entstehen (siehe dazu auch Kapitel 10.13 [3]). Aus diesem Grund empfielt es sich, den RTC über einen externen Quarz (z. B. 32,769 kHz) zu betreiben.

Anpassungen für die Verwendung des externen Quarzes Damit der Simulator mit dem RC-Oscillator und der RTC mit dem externen Quarz arbeitet, muss die START900.a51 im Projekt verwendet werden. Dieses Assemblermodul enthält das Konfigurationsbyte UCFG1, mit dessen Einstellung die Auswahl für den ver-wendeten Quarz vorgenommen wird. Die Bits FOC0-2 müssen auf „3“ (Interner RC Oscillator) gesetzt werden (siehe Abbildung 66).

Page 130: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

130 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Abbildung 66 Auszug aus der START900.a51

!! Eine ausführliche Beschreibung zur START900.a51 finden sie in Kapitel 8.11 „Startup-Code“ [3], die Beschreibung zum UCFG1 in Kapitel 10 „Extern Taktbe-schaltung“ [3]. !!

Die Frequenz für den externen Uhren-Quarz wird unter Options for Target im Reiter Target eingegeben (siehe Abbildung 67). Die Auswahl externen Quarzes für den RTC erfolgt über das SFR RTCCON (siehe Kapitel 10.13 „Real Time Clcok „ [3]).

Abbildung 67 Options for Target, Reiter Target

Arbeiten mit den Baugruppen MCB900/ EPM900 Bei Verwendung der MCB900 Baugruppe wird der externe Quarz in der Position Q1 eingelötet. Die Kondensatoren (22 pF) können entweder auf die Positionen C5 und C6 (SMD) oder auf die Positionen P3.1 und P3.0 (verdrahtet) gelötet werden. Wird die EPM900 Baugruppe verwendet, muss nur der Quarz auf der Position Q1 einge-lötet werden. Die beiden Kondensatoren sind schon bestückt (Position C8, C9). Zudem müssen die beiden Jumper auf die Position „ext. XTAL“ gesteckt werden.

Aufbau einer Software-Uhr Bei Verwendung der Quarzfrequenz von 32,769 kHz werden 256 Zählimpulse pro Se-kunde am Down-Counter des RTC erzeugt (32768 Hz/128). Somit wird bei jedem Zähl-schritt eine 1/256 Sekunde gezählt. Um z. B. eine Auflösung von 10 ms mit dem Down-Counter des RTCs zu erreichen, muss ein externer Quarz von 128 kHz oder einem Vielfachen davon verwendet werden.

Page 131: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 131

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Die Uhr soll im ersten Schritt Stunden, Minuten und Sekunden enthalten. Die Verwal-tung dieser Informationen erfolgt in der Struktur stWatch (siehe Listing 77, ). Die Va-riablen werden im Datentyp „unsigned char“ abgespeichert (siehe ).

struct stWATCH { unsigned char ucSec; unsigned char ucMin; unsigned char ucHour; };

Listing 77 Aufbau der Struktur stUHR

Erstellen sie ein Programm, bei dem der RTC jede Sekunde einen Interrupt auslöst. Die Zeit soll in der Struktur aktualisiert werden. Die Initialisierung des RTCs soll über die Funktion „v_InitRTC()“ erfolgen. Die externe Frequenz für den RTC wird in der Defi-nition „RTC_FREQ“ angegeben (siehe Listing 78, ). In der Definition „RTC_RELOAD“ wird der Reloadwert für die SFR RTCL und RTCH berechnet. Der Reloadwert wird vor dem Teilen um „1“ verringert, da erst beim Wechsel von 0x0000 nach 0xFFFF der Unterlauf erkannt und somit die ISR ausgelöst wird. Die Struktur wird global im C-Modul angelegt (siehe Listing 79, ). Der RTC wird in der Funktion „v_InitRTC()“ initialisiert (siehe ). Der Reloadwert wird mit Hilfe der Definition berechnet (siehe ).

!! Vergessen sie nicht, den WDT auszuschalten, da dieser die gleiche ISR verwendet. !! Nach der Initalisierung läuft das Programm in der while(1) Schleife (siehe ). Löst der RTC die ISR-Routine aus, wird zuerst das Flag gelöscht (siehe ). Danach wird über-prüft, ob schon 59 Sekunden verstrichen sind (siehe ). Ist das nicht der Fall, wird die Variable „stWatch.ucSec“ um Eins erhöht. Andernfalls wird die Variable auf „0“ gesetzt, und es findet eine Überprüfung statt, ob schon 59 Minuten verstrichen sind (siehe ). Ist dies nicht der Fall, wird die Variable „stWatch.ucMin“ um Eins erhöht. Die gleiche Überprüfung findet dann nochmals für die Stunden statt (siehe ).

Projektname Verzeichnis Verwendete Sourcemodule Watch Test_Watch Test_Watch.c

START900.a51 Tabelle 72 Projekt Watch

// Definitionen #define RTC_FREQ 32768 // Angabe in Hz #define RTC_RELOAD ((RTC_FREQ-1)/128) struct stWATCH { unsigned char ucSec; unsigned char ucMin; unsigned char ucHour; };

Listing 78 Inhalt von Test_Watch.h

Page 132: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

132 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

#include <REG932.H> #include <Test_Watch.H> struct stWATCH stWatch; void v_InitRTC(void) { WDCON = 0x00; // WDT ausschalten !! WFEED1= 0xa5; WFEED2= 0x5a; // Berechnung des eigentlichen RTC Taktes RTCL = (unsigned char) (RTC_RELOAD); RTCH = (unsigned char) ((RTC_RELOAD) >> 8); // RTCS1 = 1 (low. Freq. Quarz) + Interrupt freigeben RTCCON = 0x42; RTCCON = RTCCON | 1; // RTC starten EWDRT = 1; } void main(void) { v_InitRTC(); EA = 1; // Allgemeine Interruptsperre aufheben while(1); } void v_RTC_ISR(void) interrupt 10 using 1 { RTCCON = 0x43; // ISR-Flag loeschen if (stWatch.ucSec < 59) // Ueberpruefung auf Ueberlauf (sec) stWatch.ucSec++; else { stWatch.ucSec = 0; if (stWatch.ucMin < 59) // Ueberpruefung auf Ueberlauf (min) stWatch.ucMin++; else { stWatch.ucMin= 0; if (stWatch.ucHour < 23) // Ueberpruefung auf Ueberlauf stWatch.ucHour++; // (hour) else stWatch.ucHour = 0; } } }

Listing 79 Inhalt von Test_Watch.c

Page 133: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 133

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Mit diesem Verfahren wird die Verwaltung der Uhr in die ISR verlagert. Soll jetzt noch eine Verwaltung der Tage, Monate und Jahre erfolgen, wird immer mehr Programmzeit in der ISR benötigt. Es empfiehlt sich deswegen, die Auswertung der Zeit außerhalb der ISR durchzuführen und die Zeit in Sekunden mit Hilfe einer Variablen vom Datentyp unsigned long zu spei-chern. Die Variable dieses Datentyps kann 4294967295 Sekunden aufnehmen, bis ein Überlauf stattfindet. Dies entspricht einer Zeit von rund 136 Jahren. Dieses Verfahren wird auch beim PC und bei einigen anderen RTC (z. B. von Dallas) eingesetzt. In der ISR des RTC wird nur die noch Variable inkrementiert. Erstellen sie ein Programm bei dem Zeit mit der Variablen „ulRTCTime“ verwaltet wird. In der ISR wird die Variable um Eins erhöht.

Projektname Verzeichnis Verwendete Sourcemodule RTCSec Test_RTCSec Test_RTCSec.c

START900.a51 Tabelle 73 Projekt RTCSec

#include <REG932.H> #include <TestWatchSec.h> unsigned long ulRTCTime; void v_InitRTC(void) { WDCON = 0x00; // WDT ausschalten !! WFEED1= 0xa5; WFEED2= 0x5a; // Berechnung des eigentlichen RTC Taktes // Berechnung des eigentlichen RTC Taktes RTCL = (unsigned char) (RTC_RELOAD); RTCH = (unsigned char) ((RTC_RELOAD) >> 8); // RTCS1 = 1 (low. Freq. Quarz) + Interrupt freigeben RTCCON = 0x42; RTCCON = RTCCON | 1; // RTC starten EWDRT = 1; } void main(void) { v_InitRTC(); EA = 1; // Allgemeine Interruptsperre aufheben while(1); } void v_RTC_ISR(void) interrupt 10 using 1 { RTCCON = 0x43; // ISR-Flag loeschen ulRTCTime++; }

Listing 80 Inhalt von Test_RTCSec.c

Page 134: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

134 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Die Umrechnung der Variablen „ulRTCTime“ auf die jeweilige Zeit muss per Software erfolgen. Fügen sie nun die Funktion „v_GetTime()“ hinzu, die die Zeitumrechnung durchführt (siehe Listing 81, ). Die Funktion zerlegt „ulRTCTime“ in Sekunden (siehe 2), Minuten (siehe 3) und Stunden (siehe 4) und weist das Ergebnis dem jeweiligen Element der Struktur zu. Als Übergabeparameter wird ein Pointer auf die Struktur stWATCH verwendet. Das Ergebnis der Berechnung wird in dieser Struktur abgespei-chert.

!! Die Funktionsweise der Struktur sowie die Adressierung mit Hilfe eines Pointers können sie in Kapitel 13, „Strukturen“ [1] nachlesen. !!

2 3 5 4

void v_GetTime(struct stWATCH *pWatch) { unsigned long ulMin, ulHour; unsigned int uiDays; ulMin = ulRTCTime / 60; pWatch->ucSec = ulRTCTime - (60 * ulMin); // Berechnung sec ulHour = ulMin / 60; pWatch->ucMin = ulMin - (60 * ulHour); // Berechnung min uiDays = ulHour / 24; pWatch->ucHour = ulHour - (24 * uiDays); // Berechnung hours }

Listing 81 Funktion v_GetTime()

Die Berechung der Tage, Monate und Jahre hängt von den Schaltjahren ab. Um hier eine Vereinfachung bezüglich der Softwareauswertung zu erreichen, wurde eine Formel ent-wickelt, die nur ein bestimmtes Zeitfenster abdeckt. Es beginnt beim Referenzdatum 01.01.1970 (Unix-Timestamp) und endet am 19.01.2038 (ausgetestet).

!! Dieser Bereich ist vollkommend ausreichend, da die Hardware meist nur für 10 Jahre ausgelegt wird. !!

Um Tag, Monat, Jahr und den Wochentag auswerten und abspeichern zu können, muss die Struktor stWATCH erweitert werden (siehe Listing 82, ).

// Definitionen struct stWATCH { unsigned char ucSec; unsigned char ucMin; unsigned char ucHour; unsigned char ucWeekday; unsigned char ucDay; unsigned char ucMonth; unsigned int uiYear; };

Listing 82 Inhalt von Test_RTCSec.h

Um den Wochentag zu errechnen, muss zur Anzahl der ermittelten Tage der Wert „4“ hinzugezählt werden (der 01.01.1970 war ein Donnerstag). Der Gesamtwert wird dann Modulo 7 geteilt. Das Ergebnis kann die Werte „0“ bis „6“ enthalten, wobei „0“ den Sonntag repräsentiert.

Page 135: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 135

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

2 3 4 5

6 7 8

void v_GetTime(void) { ... uiDays = ulHour / 24; pWatch->ucHour = ulHour - (24 * uiDays); // Berechnung hours pWatch->ucWeekday = (uiDays + 4) % 7; // Berechnung weekday uiDays = uiDays + 365 + 366; // ab 01.01.1968 ucSchaltPeri = uiDays / 1461; // ((4 * 365) + 1) uiDaysLYear = uiDays % ((4 * 365) + 1); if ((uiDaysLYear >= (31 + 29))) ucSchaltPeri++; pWatch->uiYear = ((uiDays - ucSchaltPeri) / 365); uiDays = uiDays - (pWatch->uiYear * 365) - ucSchaltPeri; if ((uiDays <= 365) && (uiDays >= 60)) uiDays++; pWatch->uiYear += 68; }

Listing 83 Auszug aus Funktion v_GetTime()

Für die Berechnung der Schaltjahre werden die Tage ab dem 01.01.1968 gezählt. Die in „v_GetTime()“ (siehe siehe Listing 81, 5) ermittelten Tage müssen um 731 (365 + 366) erhöht werden (siehe Listing 83, 2). Danach wird „uiDays“ durch 1461 geteilt, um die Anzahl der Schaltjahre zu ermitteln (siehe 3). Als nächstes müssen die Tage ermittelt werden, die seit dem letzten Schaltjahr vergangen sind (siehe 4). Liegt das Datum über dem 29.02. eines Schaltjahres, muss zudem die Anzahl der Schaltjahre um eins erhöht werden (siehe 5). Das aktuelle Jahr kann jetzt aus der Anzahl der ermittelten Tage minus der Anzahl Schaltjahrtage durch 365 errechnet werden (siehe 6). Die Anzahl der Tage seit Beginn des Jahres wird in 7 ermittelt. Da die Formel vom 01.01.1968 ausgeht, muss noch der Wert „68“ addiert werden (siehe 8). Um den aktuellen Monat und den Tag zu ermitteln, wird eine Schleife durchlaufen. In einem Array sind die Anzahl der abgelaufenen Tage pro Monat abgespeichert (siehe Listing 84, ). Im Januar sind 0 Tage, im Februar schon 31 Tage aus dem Januar enthal-ten. unsigned int DaysToMonth[13] = { 0,31,59,90,120,151,181,212,243,273,304,334,365};

Listing 84 Array DaysToMonth

Die while-Schleife (siehe Listing 85, ) wird jetzt solange durchlaufen, bis die Anzahl der Tage kleiner ist als der Monat Tage hat. Bei jedem Schleifendurchlauf wird der Monat (stWatch.ucMonth) um Eins dekrementiert (siehe 2). Der Monat wird als Index im Array „DaysToMonth“ verwendet (siehe 3). Zudem wird überprüft, ob ein Schaltjahr vorhanden ist und der Monat über Februar liegt (siehe 4). Ist dies der Fall, wird die Anzahl der Tage um Eins erhöht (siehe 5).

Page 136: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

136 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Ist die Bedingung der while-Schleife nicht mehr gegeben (false), so ist der Monat gefunden. Es kann jetzt noch der aktuelle Tag innerhalb des Monats ermittelt werden (siehe 6).

2 3 4 5

6

void v_GetTime(struct stWATCH *pWatch) { ... pWatch->ucMonth = 13; uiDay2Month = 366; while (uiDays < uiDay2Month) { pWatch->ucMonth--; uiDay2Month = DaysToMonth[pWatch->ucMonth]; if ((pWatch->ucMonth >= 2) && ((pWatch->uiYear % 4) == 0)) uiDay2Month++; } pWatch->ucDay = uiDays - uiDay2Month + 1; }

Listing 85 Auszug aus Funktion v_GetTime()

Für die Umwandlung eines Datums und einer Uhrzeit in einen long-Wert wird die Funk-tion „ul_SetTime()“ verwendet (siehe Listing 86, ). Die Funktion verwendet die Anga-ben in der Struktur stWatch (siehe 2) und errechnet daraus einen long-Wert. Dieser wird an die aufrufende Funktion zurückgegeben (siehe 3) .

2 2 2 2 2 3

unsigned long ul_SetTime(struct stWATCH *pWatch) { unsigned long iday; unsigned long val; iday = 365 * (pWatch->uiYear - 70) + DaysToMonth[pWatch->ucMonth] + (pWatch->ucDay - 1); iday = iday + (pWatch->uiYear - 69) / 4; if ((pWatch->ucMonth > 1) && ((pWatch->uiYear % 4) == 0)) iday++; val = pWatch->ucSec + 60 * pWatch->ucMin + 3600 * (pWatch->ucHour + 24 * iday); return val; }

Listing 86 Funktion ul_SetTime()

Erstellen sie das Projekt aus Tabelle 74, bei dem die Funktionen für den RTC und die ISR in einem eigenen Sourcemodul liegen. Auf die Variable ulRTCTime soll nur noch innerhalb des C-Moduls RTCLIB.c zugegriffen werden dürfen. Die Variable wird in die-sem Fall mit dem Gültigkeitsbereich „static“ versehen (siehe Listing 87, ). Die Funk-tionsweise von static können sie dem Kapitel 8.3 „Variablen [3] nachlesen. Das Auslesen bzw. das Setzen der Zeit kann nur noch über die Funktionen „v_GetTime()“ (siehe 2) und „v_SetTime()“ (siehe 3) erfolgen.

!! Wird die Funktion „v_GetTime()“ auch von der ISR des RTCs aufgerufen, muss die #pragma-Anweisung „NOAREGS“ verwendet werden (siehe 4). Diese Anwei-

Page 137: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 137

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

sung ist nötig, da die ISR mit der Registerbank 1 arbeitet, das Hauptprogramm mit der Registerbank 0. Eine ausführliche Beschreibung zu „NOAREGS“ finden sie in Kapitel 17.4, „Steuerparameter“, [1]. Mit den #pragma-Anweisungen „SAVE“ (siehe 5) und „RESTORE“ (siehe 6), werden die alten Einstellungen gespeichert und danach wieder hergestellt. !!

Projektname Verzeichnis Verwendete Sourcemodule RTCLib Test_RTCLib Test_RTCLib.c

START900.a51 ..\Library RTCLib.c

Tabelle 74 Projekt RTCLib

5 4 2

#include <REG932.H> #include <RTCLib.h> // Definitionen unsigned int DaysToMonth[13] = { 0,31,59,90,120,151,181,212,243,273,304,334,365}; static unsigned long ulRTCTime; void v_InitRTC(void) { WDCON = 0x00; // WDT ausschalten !! WFEED1= 0xa5; WFEED2= 0x5a; // Berechnung des eigentlichen RTC Taktes RTCL = (unsigned char) (RTC_RELOAD); RTCH = (unsigned char) ((RTC_RELOAD) >> 8); // RTCS1 = 1 (low. Freq. Quarz) + Interrupt freigeben RTCCON = 0x42; RTCCON = RTCCON | 1; // RTC starten EWDRT = 1; } #pragma SAVE #pragma NOAREGS void v_GetTime(struct stWATCH *pWatch) { unsigned long ulMin, ulHour; unsigned int uiDays, uiDay2Month, uiDaysLYear; unsigned char ucSchaltPeri; ulMin = ulRTCTime / 60; pWatch->ucSec = ulRTCTime - (60 * ulMin); // Berechnung sec ulHour = ulMin / 60; pWatch->ucMin = ulMin - (60 * ulHour); // Berechnung min uiDays = ulHour / 24;

Page 138: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

138 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

6 3

pWatch->ucHour = ulHour - (24 * uiDays); // Berechnung hours pWatch->ucWeekday = (uiDays + 4) % 7; // Berechnung weekday uiDays = uiDays + 365 + 366; // ab 01.01.1968 ucSchaltPeri = uiDays / ((4 * 365) + 1); uiDaysLYear = uiDays % ((4 * 365) + 1); if ((uiDaysLYear >= (31 + 29))) ucSchaltPeri++; pWatch->uiYear = ((uiDays - ucSchaltPeri) / 365); uiDays = uiDays - (pWatch->uiYear * 365) - ucSchaltPeri; if ((uiDays <= 365) && (uiDays >= 60)) uiDays++; pWatch->uiYear += 68; pWatch->ucMonth = 13; uiDay2Month = 366; while (uiDays < uiDay2Month) { pWatch->ucMonth--; uiDay2Month = DaysToMonth[pWatch->ucMonth]; if ((pWatch->ucMonth >= 2) && ((pWatch->uiYear % 4) == 0)) uiDay2Month++; } pWatch->ucDay = uiDays - uiDay2Month + 1; } #pragma RESTORE void v_SetTime(struct stWATCH *pWatch) { unsigned long iday; iday = 365 * (pWatch->uiYear - 70) + DaysToMonth pWatch->ucMonth] + (pWatch->ucDay - 1); iday = iday + (pWatch->uiYear - 69) / 4; if ((pWatch->ucMonth > 1) && ((pWatch->uiYear % 4) == 0)) iday++; ulRTCTime = pWatch->ucSec + 60 * pWatch->ucMin + 3600 * (pWatch->ucHour + 24 * iday); } void v_RTC_ISR(void) interrupt 10 using 1 { RTCCON = 0x43; // ISR-Flag loeschen ulRTCTime++; }

Listing 87 Inhalt von RTCLib.c

Die Definition der RTC-Frequenz, der Struktur, sowie der RTC-Funktionen sind im H-File RTCLib.h enthalten (siehe Listing 88).

// Definitionen #define RTC_FREQ 32768 // Angabe in Hz

Page 139: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 139

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

#define RTC_RELOAD ((RTC_FREQ-1)/128) struct stWATCH { unsigned char ucSec; unsigned char ucMin; unsigned char ucHour; unsigned char ucWeekday; unsigned char ucDay; unsigned char ucMonth; unsigned int uiYear; }; enum enRTCMONTH {JAN=0, FEB, MAR, APR, MAI, JUN, JUL, AUG, SEP, OCT, NOV, DEC}; // Deklarationen extern void v_GetTime(struct stWATCH *pWatch); extern void v_InitRTC(void); extern void v_SetTime(struct stWATCH *pWatch);

Listing 88 Inhalt von RTCLib.h

Um die RTC-Funktionen bekannt zu machen, wird das H-File „RTCLib.h“ am Anfang in das Sourcemodul mit eingebunden (siehe Listing 89, ). Vor der Initialisierung des RTCs wird zuerst die Zeit in der Struktur „stWatch“ vorbelegt, in diesem Beispiel auf den 01.10.2002, 14:00:00 (siehe 2) und dann mit Hilfe der Funktion „v_SetTime()“ gesetzt (siehe 3). Danach wird der RTC initialisiert (siehe 4) und die allgemeine Interruptsperre aufgehoben (siehe 5).

2 2 2 2 2 2 3 4 5

#include <REG932.H> #include <RTCLib.h> void main(void) { struct stWATCH stWatch; // Zeit auf 14:00:00 01.10.2004 setzen stWatch.ucSec = 0; stWatch.ucMin = 0; stWatch.ucHour = 14; stWatch.ucDay = 1; stWatch.ucMonth = OCT; // JAN == 0!! stWatch.uiYear = 104; // 2004 - 1970 v_SetTime(&stWatch); // Zeit umrechnen v_InitRTC(); // RTC initialisieren EA = 1; // Allgemeine Interruptsperre aufheben while(1); }

Listing 89 Inhalt von TestRTCLib.c

Page 140: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

140 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Erweitern sie das Projekt so, dass die Uhrzeit auf dem LCD ausgegeben wird. Für die Ausgabe auf der LCD muss noch das Sourcemodul „LCDLib_4bitPort.c“ zum Projekt hinzugefügt werden. Damit nicht ständig das LCD neu beschrieben wird, findet eine Überprüfung der Sekunden statt. In der Variablen ucOldSec (siehe Listing 90, ) wird zuerst ein Wert außerhalb des gültigen Sekundenbereichs, in diesem Beispiel 0xFF, ein-getragen. Wird jetzt das erste Mal die Zeit über die Funktion „v_GetTime()“ geholt (sie-he 2), ist die Überprüfung zwischen den aktuellen Sekunden und dem abgespeichertem Wert „wahr“. Somit wird der Programmteil innerhalb der if-Abfrage abgearbeitet. Als erstes werden die aktuellen Sekunden in der Variablen ucOldSec abgespeichert (siehe 4). Danach erfolgt die Ausgabe auf der LCD mit Hilfe der Funktion „printf()“ (siehe 5).

!! Der cast auf (int) (siehe 5) wird bei Variablen vom Datentyp char in Zusammen-hang mit printf() benötigt. Andernfalls arbeitet printf() nicht korrekt. !!

Projektname Verzeichnis Verwendete Sourcemodule RTCLib Test_RTCLib Test_RTCLib.c

START900.a51 ..\Library RTCLib.c, LCDLib_4bitPort.c

Tabelle 75 Projekt RTCLib erweitert um LCD-Ausgabe

#include <REG932.H> #include <RTCLib.h> #include <lcd_def.h> #include <stdio.h> void main(void) { unsigned char ucOldSec = 0xFF; struct stWATCH stWatch; // Zeit auf 14:00:00 01.10.2004 setzen stWatch.ucSec = 0; stWatch.ucMin = 0; stWatch.ucHour = 14; stWatch.ucDay = 1; stWatch.ucMonth = OCT; stWatch.uiYear = 104; // 2004 - 1970 v_SetTime(&stWatch); // Zeit umrechnen IP0 = 0x40; v_InitRTC(); // RTC initialisieren EA = 1; // Allgemeine Interruptsperre aufheben // Initialisierung des Port 2 (LCD) auf Bidirektional P2M1 = 0; P2M2 = 0; // Initialisierung des HD44780 Controllers uc_LCDIni(_2LINE | _7DOTS);

Page 141: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 141

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

2 3 4 5

while(1) { v_GetTime(&stWatch); if (stWatch.ucSec != ucOldSec) { ucOldSec = stWatch.ucSec; // Loeschen des HD44780 Speichers. uc_Clrscr(); printf("%.2d:%.2d:%.2d", (int)stWatch.ucHour, (int)stWatch.ucMin, (int)stWatch.ucSec); } } while(1); }

Listing 90 Inhalt von TestRTCLib.c erweitert um LCD-Ausgabe

Auswertung eines Alarms bzw. Schaltzeit Meist wird der RTC nicht nur zur Anzeige der aktuellen Uhrzeit verwendet, er wertet vielmehr gespeicherte Zeiten aus und gibt bei einer Übereinstimmung mit der aktuellen Uhrzeit ein Schaltsignal aus. Dieses kann nun einen Alarm auslösen oder z. B. ein Relais schalten. Dieses Schaltsignal kann z. B. zu einem bestimmten Tag zu einer bestimmten Uhrzeit kommen, täglich um 8 Uhr und um 22 Uhr, jeden Sonntag um 12 Uhr usw. Erstellen sie das Projekt aus Tabelle 76, das es , eine Alarmzeit zu speichern und bei einer Übereinstimmung mit der aktuellen Uhrzeit ein Schaltsignal ausgibt. Die Verwaltung der Alarm-Zeit und die Speicherung des Ereignisses wird mit Hilfe der Struktur „stRTC_ALARM“ durchgeführt (siehe Listing 91). Die Alarmzeit wird im Element „ulTime“ gespeichert (siehe Listing 91, ). Die Information, ob es sich um ein einmaliges Ereignis oder um ein wiederkehrendes Ereignis handelt, wird im Element „ucDayAndActiv“ gespeichert (siehe 2). Für die wiederkehrenden Ereignisse und die Einstellung, ob beim Alarm der Portpin gesetzt oder gelöscht werden soll, ist der Auf-zählungstyp „enALARMSET“ vorhanden (siehe 3).

2 3

// Definitionen ... struct stRTC_ALARM { unsigned long ulTime; unsigned char ucDayAndActiv; }; enum enALARMSET { SIGNAL_OFF=0x00, SIGNAL_ON=0x01, MONDAY=0x02, TUESDAY=0x04, WEDNESDAY=0x08, THURSDAY=0x10,FRIDAY=0x20, SATURDAY=0x40, SUNDAY=0x80};

Listing 91 Erweiterung in RTCLib.h

Im Sourcemodul RTCLIB.c wird die Struktur „stAlarm“ definiert (siehe Listing 92, ). Mit der Funktion „b_ SetAlarmTime()“ (siehe 2) wird die Struktur „stWATCH“ in ei-nen 32-bit Wert gewandelt und dem Element „ulTime“ zugewiesen (siehe 3). Der

Page 142: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

142 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Übergabeparameter „ucDayInfo“ wird direkt dem Element „ucDayAndActiv“ zugewie-sen (siehe 4).

2 3 4

... struct stRTC_ALARM stAlarm; ... bit b_SetAlarmTime(struct stWATCH *pWatch, unsigned char ucDayInfo) { unsigned long iday; iday = 365 * (pWatch->uiYear - 70) + DaysToMonth[pWatch->ucMonth] + (pWatch->ucDay - 1); iday = iday + (pWatch->uiYear - 69) / 4; if ((pWatch->ucMonth > 1) && ((pWatch->uiYear % 4) == 0)) iday++; iday = pWatch->ucSec + 60 * pWatch->ucMin + 3600 * (pWatch->ucHour + 24 * iday); stAlarm.ulTime = iday; stAlarm.ucDayAndActiv = ucDayInfo; return 1; }

Listing 92 Funktion b_ SetAlarmTime()

Die Auswertung der Alarmzeit erfolgt in der ISR des RTC. Ist in der Struktur „stAlarm“ eine Zeit eingetragen (siehe Listing 93, ), wird überprüft, ob es sich um einen täglichen Alarm handelt. Die Überprüfung findet in der switch-case Anweisung statt (siehe 2). Ist dies der Fall, wird die Variable „btDayFound“ auf „1“ gesetzt (siehe 3). Ist „btDayFound“ gesetzt, wird nun noch überprüft, ob die aktuelle Zeit mit dem der Alarmzeit übereinstimmt (siehe 4). Stimmt die Alarmzeit mit der aktuellen Zeit überein, wird die globale Variable „btAlarm“ gesetzt bzw. gelöscht (siehe 5). Handelt es sich um einen einmaligen Alarm, wird nur der Alarmwert „stAlarm.ulTime“ mit dem aktuellen Wert „ulRTCTime” verglichen (siehe ). Sind die beiden Werte gleich, liegt ein Alarm vor. Die globale Variable „btAlarm“ wird gesetzt bzw. gelöscht (siehe ).

2 3

void v_RTC_ISR(void) interrupt 10 using 1 { RTCCON = 0x43; // ISR-Flag loeschen ulRTCTime++; if (stAlarm.ulTime != 0) // Alarmzeit eingetragen { if (stAlarm.ucDayAndActiv & 0xFE) // taeglicher ALARM { struct stWATCH stActTime; bit btDayFound = 0; v_GetTime(&stActTime); switch(stActTime.ucWeekday) { case 0: if (stAlarm.ucDayAndActiv & SUNDAY) btDayFound = 1; break; case 1: if (stAlarm.ucDayAndActiv & MONDAY)

Page 143: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 143

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

3 3 3 3 3 3 4 5

btDayFound = 1; break; case 2: if (stAlarm.ucDayAndActiv & TUESDAY) btDayFound = 1; break; case 3: if (stAlarm.ucDayAndActiv & WEDNESDAY) btDayFound = 1; break; case 4: if (stAlarm.ucDayAndActiv & THURSDAY) btDayFound = 1; break; case 5: if (stAlarm.ucDayAndActiv & FRIDAY) btDayFound = 1; break; case 6: if (stAlarm.ucDayAndActiv & SATURDAY) btDayFound = 1; break; } if (btDayFound == 1) { struct stWATCH stAlarmTime; v_GetTime(&stAlarmTime); if (stActTime.ucSec == stAlarmTime.ucSec && stActTime.ucMin == stAlarmTime.ucMin && stActTime.ucHour == stAlarmTime.ucHour) btAlarm = stAlarm.ucDayAndActiv & 0x01; } } else if (stAlarm.ulTime == ulRTCTime) // einmaliger Alarm btAlarm = stAlarm.ucDayAndActiv & 0x01; } }

Listing 93 ISR v_RTC_ISR()

Für das Setzen der Alarmzeit sowie der aktuellen Zeit wird die Struktur stWatch benötigt (siehe Listing 94, ). Zuerst wird die Alarmzeit gesetzt (siehe 2), danach die aktuelle Zeit (siehe 3). Erst dann wird der RTC gestartet. In der ersten while(1)-Schleife (siehe 4) wird nun solange gewartet, bis „btAlarm“ auf „1“ gesetzt wird.

2

#include <REG932.H> #include <RTCLib.h> void main(void) { struct stWATCH stWatch; // Alarmzeit setzen 14:01:12 01.10.2004 setzen stWatch.ucSec = 12; stWatch.ucMin = 0; stWatch.ucHour = 14; stWatch.ucDay = 1; stWatch.ucMonth = OCT; stWatch.uiYear = 104; // 2004 - 1970 b_SetAlarmTime(&stWatch, THURSDAY | SIGNAL_ON); // Zeit auf 14:00:00 01.10.2004 setzen stWatch.ucSec = 0;

Page 144: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

144 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

3 4

stWatch.ucMin = 0; stWatch.ucHour = 14; stWatch.ucDay = 1; stWatch.ucMonth = OCT; stWatch.uiYear = 104; // 2004 - 1970 v_SetTime(&stWatch); // aktuelle Zeit setzen IP0 = 0x40; v_InitRTC(); // RTC initalisieren EA = 1; // Allgemeine Interruptsperre aufheben while(1) { if (btAlarm == SIGNAL_ON) while(1); } }

Listing 94 Inhalt von Test_RTCAlarm.c

Erstellen sie jetzt das Projekt aus Tabelle 76. Projektname Verzeichnis Verwendete Sourcemodule RTCAlarm Test_RTCAlarm Test_RTCAlarm.c

START900.a51 ..\Library RTCLib.c

Tabelle 76 Projekt RTCAlarm

Auswerten von mehreren Alarm-/Schaltzeiten Sollen mehrere Alarmzeiten gespeichert werden, z. B. erste Schaltzeit Montag 6:00, SIGNAL_ON, zweiter Alarm Montag 22:00, SIGNAL_OFF, usw. muss ein Array von Strukturelementen verwendet werden, die diese Alarm-Schaltzeiten aufnimmt (siehe Listing 95, ). In diesem Beispiel können 20 Einträge durchgeführt werden. Zudem wird die Variable „ucAlarmInfo“ (siehe 2) benötigt, die das Array verwaltet.

2

#include <REG932.H> #include <RTCMultiLib.h> // Definitionen ... struct stRTC_ALARM idata stAlarm[20]; unsigned char ucAlarmInfo =0; ...

Listing 95 Auszug aus RTCMultiLib.c

In der Funktion b_SetAlarmTime() ist jetzt eine Überprüfung vorhanden, ob noch ein Alarmeintrag zulässig ist (siehe Listing 96, ). Wenn kein weiterer Eintrag mehr aufge-nommen werden kann, liefert die Funktion den Wert „0“ zurück. Die Berechnung der möglichen Einträge wird mit Hilfe des sizeof()-Operators durchgeführt. Eine Beschrei-bung zur Funktionsweise dieses Operators finden sie in Kapitel 11.9 [1]. Nach der Um-

Page 145: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 145

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

rechnung wird der Wert in das Array geschrieben (siehe 2) und die Variable „ucAlarmInfo“ um eins erhöht (siehe 3).

2 2 3

bit b_SetAlarmTime(struct stWATCH *pWatch, unsigned char ucDayInfo) { unsigned long iday; if (ucAlarmInfo > (sizeof(stAlarm)/sizeof(struct stRTC_ALARM))) return 0; iday = 365 * (pWatch->uiYear - 70) + DaysToMonth[pWatch->ucMonth] + (pWatch->ucDay - 1); iday = iday + (pWatch->uiYear - 69) / 4; if ((pWatch->ucMonth > 1) && ((pWatch->uiYear % 4) == 0)) iday++; iday = pWatch->ucSec + 60 * pWatch->ucMin + 3600 * (pWatch->ucHour + 24 * iday); stAlarm[ucAlarmInfo].ulTime = iday; stAlarm[ucAlarmInfo].ucDayAndActiv = ucDayInfo; ucAlarmInfo++; return 1; }

Listing 96 Funktion b_SetAlarmTime()

In der ISR des RTCs wird nun zusätzlich mit Hilfe der Variablen „ucOff” überprüft, ob einer der Einträge im Array zuschlägt (siehe Listing 97, ). Diese Schleife wird solange durchlaufen, bis alle Einträge im Array überprüft wurden.

void v_RTC_ISR(void) interrupt 10 using 1 { unsigned char ucOff; struct stWATCH stActTime; RTCCON = 0x43; // ISR-Flag loeschen ulRTCTime++; v_GetTime(&stActTime, REALTIME); for (ucOff = 0; ucOff < ucAlarmInfo; ucOff++) { if (stAlarm[ucOff].ulTime != 0) // Alarmzeit eingetragen { if (stAlarm[ucOff].ucDayAndActiv & 0xFE) { // taeglicher ALARM bit btDayFound = 0; switch(stActTime.ucWeekday) { case 0: if (stAlarm[ucOff].ucDayAndActiv & SUNDAY) btDayFound = 1; break; case 1: if (stAlarm[ucOff].ucDayAndActiv & MONDAY) btDayFound = 1; break; case 2: if (stAlarm[ucOff].ucDayAndActiv & TUESDAY) btDayFound = 1; break; case 3: if (stAlarm[ucOff].ucDayAndActiv & WEDNESDAY)

Page 146: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

146 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

btDayFound = 1; break; case 4: if (stAlarm[ucOff].ucDayAndActiv & THURSDAY) btDayFound = 1; break; case 5: if (stAlarm[ucOff].ucDayAndActiv & FRIDAY) btDayFound = 1; break; case 6: if (stAlarm[ucOff].ucDayAndActiv & SATURDAY) btDayFound = 1; break; } if (btDayFound == 1) { struct stWATCH stAlarmTime; v_GetTime(&stAlarmTime, ucOff); if (stActTime.ucSec == stAlarmTime.ucSec && stActTime.ucMin == stAlarmTime.ucMin && stActTime.ucHour == stAlarmTime.ucHour) { btAlarm = stAlarm[ucOff].ucDayAndActiv & 0x01; break; } } } } else if (stAlarm[ucOff].ulTime == ulRTCTime) { // einmaliger Alarm btAlarm = stAlarm[ucOff].ucDayAndActiv & 0x01; break; } } }

Listing 97 ISR des RTCs

Erstellen sie das Projekt aus Tabelle 77 und geben sie die folgenden Zeiten an. Erste Alarmzeit: 14:01:12 01.10.2004 Zweite Alarmzeit: 14:01:15 01.10.2004 Realtime: 14:00:00 01.10.2004 An Port 2, Pin 0 soll die LED (btLEDAlarm) eingeschaltet werden, wenn das Alarmbit „btAlarm“ gesetzt ist. Die Definition der LED erfolgt über die sbit Deklaration (siehe Listing 98, ). In der while(1)-Schleife wird nun kontinuierlich „btAlarm“ überprüft (siehe 2). Diese Variable wird in der ISR des RTC gesetzt, wenn der erste Alarm zuge-schlagen hat und gelöscht, wenn der zweite Alarm eintrat.

Projektname Verzeichnis Verwendete Sourcemodule RTCMultiAlarm Test_RTCMultiAlarm Test_RTCMultiAlarm.c

START900.a51 ..\Library RTCMultiLib.c, PortConfig.c

Tabelle 77 Projekt RTCMultiAlarm

#include <REG932.H> #include <RTCMultiLib.h>

Page 147: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 147

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

2

#include <PortConfig.h> sbit btLEDAlarm = P2^0; void main(void) { struct stWATCH stWatch; // erste Alarmzeit setzen 14:01:12 01.10.2004 setzen stWatch.ucSec = 12; stWatch.ucMin = 0; stWatch.ucHour = 14; stWatch.ucDay = 1; stWatch.ucMonth = OCT; stWatch.uiYear = 104; // 2004 - 1970 b_SetAlarmTime(&stWatch, FRIDAY | SIGNAL_ON); // zweite Alarmzeit setzen 14:01:15 01.10.2004 setzen stWatch.ucSec = 15; stWatch.ucMin = 0; stWatch.ucHour = 14; stWatch.ucDay = 1; stWatch.ucMonth = OCT; stWatch.uiYear = 104; // 2004 - 1970 b_SetAlarmTime(&stWatch, FRIDAY | SIGNAL_OFF); // Zeit auf 14:00:00 01.10.2004 setzen stWatch.ucSec = 0; stWatch.ucMin = 0; stWatch.ucHour = 14; stWatch.ucDay = 1; stWatch.ucMonth = OCT; stWatch.uiYear = 104; // 2004 - 1970 v_SetTime(&stWatch); // Zeit umrechnen v_PortConfig(Port2, Pin0, BiDir); IP0 = 0x40; v_InitRTC(); // RTC initalisieren EA = 1; // Allgemeine Interruptsperre aufheben while(1) // Überprüfung des ALARM-Signals { if (btAlarm == 1) btLEDAlarm =1; else btLEDAlarm =0; } }

Listing 98 Inhalt von Test_RTCMultiAlarm.c

Page 148: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

148 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

2.18 Externer Zugriff mit /WR,/RD und /CS Im Kapitel 2.12 (Seite 101) wurde eine Möglichkeit aufgezeigt, wie eine externe RAM-Erweiterung an die LPC900-Familie möglich ist. In diesem Kapitel werden Vorschläge aufgezeigt, wie externe Peripheriebausteine die mit einen externen 8-bit Datenbus ausge-stattet sind, an die LPC900-Familie angeschlossen werden. Die Steuersignale /WR, /RD und /CS werden von der Software, in Abhängigkeit ob ein schreibender bzw. lesender Zugriff erfolgen soll, gesetzt. In Listing 99 ist die Funktion „uc_ReadVal()“ enthalten. Damit ein Wert über den Port 2 eingelesen werden kann, muss dieser zuerst in die Be-triebsart „Quasi-Bidirekional“

2 2 3

unsigned char uc_ReadVal(void) { unsigned char ucReadVal; // Quasi-Bidir. P2M1 = 0x00; P2M2 = 0x00; P2 = 0xFF; _RD =0; _CS1=0; ucReadVal = P2; _CS1=1; _RD =1; return ucReadVal; }

Listing 99 Funktion uc_ReadVal()

2 2 3

void v_WriteVal(unsigned char ucVal) { // Push-Pull P2M1 = 0x00; P2M2 = 0xFF; _WR =0; _CS1=0; P2 = ucVal; _CS1=1; _WR =1; }

Listing 100 Funktion uc_ReadVal()

Projektname Verzeichnis Verwendete Sourcemodule RTCMultiAlarm Test_RTCMultiAlarm Test_ExtRW_Signals.c

..\Library PortConfig.c Tabelle 78 Projekt RTCMultiAlarm

Page 149: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 149

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

2.19 Leiterplatte Abbildung 68 und Abbildung 69 enthalten die Bestückungs-/ Lötseite des LPC-Experi-mentierboard-light V1.3.

Page 150: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

150 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Abbildung 68 Bestückungsseite LPC-Experimentierboard-light V1.3

Page 151: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 151

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Abbildung 69 Lötseite LPC-Experimentierboard-light V1.3

Page 152: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

152 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

2.20 Stückliste In der nachfolgenden Tabelle finden sie das gesamte Material für die Bestückung des Experimentierboards-light V1.3.

Bezeichnung Gehäuse Anzahl Bestückungsplatz 100 n RM 2.5mm 6 C1, C8, C9, C14, C18, C20

100 µF/16 V RM 2.5mm 1 C2 1 µF/35 V RM 2.5mm 6 C3, C4, C5, C6, C7, C10

22 pF RM 2.5mm 1 C11 2,7 nF RM 2.5mm 1 C12 33 nF RM 2.5mm 1 C22

MAX232N DIP16 1 D1 PCF8574 DIP16 1 D2 74HC541 DIP20 1 D4 SAA1064 DIP24 1 D6

2mm Buchse 2.6x.25 77 - MC7805CT TO220S 1 N1

LM258D DIP8 1 N2 DS1621 DIP8 1 N4 Poti 25k PT15 Lv 3 PT1, PT2, PT3 270 R Axial 10x2.6 1 R1 430 R Axial 10x2.6 16 R2, R4, R6, R8, R10, R12, R14, R16, R36,

R37, R38, R39, R40, R41, R42, R43 10 k Axial 10x2.6 19 R3, R5, R7, R9, R11, R13, R15, R17, R18,

R19, R20, R21, R22, R23, R24, R25, R44, R45, R55

2k2 Axial 10x2.6 5 R33, R34, R26, R28, R32 4k7 Axial 10x2.6 3 R27, R29, R35 5k1 Axial 10x2.6 2 R30, R31 100k Axial 10x2.6 1 R56

8x330 R SIP9 1 R46 8x10 k SIP9 1 RW5 8x100 k SIP9 3 RW1, RW2, RW3

Schiebeschalter 11.5x6 8 S1 - 8 Kurzhubtaster 5x5 8 S9 – S16 EPS Increment - 1 S17

BC557B TO92 3 T1, T2, T3 BC547B TO92 2 T4, T5

Tabelle 79 Stückliste Experimentierboard-light V1.3

Page 153: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 153

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Bezeichnung Gehäuse Anzahl Bestückungsplatz 1N5822 DO-201 1 V1

TLLR440 LED RM 5mm 1 V2 1N4001 DO-41 2 V3, V4

LED-Zeile Rot ZAQS 0807

RM 2.5 1 V5

LED 7-Seg. SA36-11HWA

14x7.5x8.5 4 VL1 – 4

IC-Sockel DIP28 2 X1, X9 IC-Sockel DIP24 1 D6 IC-Sockel DIP20 1 D4 IC-Sockel DIP16 2 D1, D2 IC-Sockel DIP8 2 N2, N4

MiniDin 8pol 90° Ausf. P

1 X4

DSUB 9pol 90° 1 X8 Jumper 2pol. RM 2.5 8 J3, J4, J5, J6, J9, J11, J28 Jumper 3pol. RM 2.5 1 J28 Jumper 4pol. RM 2.5 10 J1, J2, J12, J20/21, J19/22, J18/23, J17/24,

J16/25, J15/26, J14/27 Jumper 6pol. RM2.5 1 J8/10/13

Steckverb. 8pol. RM2.5 1 X5 Steckverb. 14pol. RM2.5 1 X7 Steckverb. 14pol. RM2.5 1 X14 Steckverb. 16pol. RM2.5 4 X10, X11, X12, X13 Stiftleiste 14pol. RM2.5 1 X7

LCD 2x16 - 1 X7 Schaltbuchse

1.9mm - 1 X3

Kühlblech - 1 N1 Buchsenleiste

9pol. RM2.5 3 RW1, RW2, RW3

Tabelle 80 Stückliste Experimentierboard-light V1.3

2.21 Artikelübersicht Bezeichnung Bestellnr. Preis Lieferant Flexible Steckbrücken 528099-33 4,49 € Conrad Steckplatine TYP II 526819-WU 6,94 € Conrad Tabelle 81 Verbindungselemente für einfache Verdrahtung

Page 154: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

154 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

3. Beschreibung der Library-Funktionen In diesem Kapitel sind alle hier vorgestellten Library-Funktionen beschrieben

3.1 Libraryfunktionen zu DS1621_Lib.c void v_DS1621StartCov(void) v_DS1621StartCov: Die Funktion sendet das Kommando „Start Convert“ an den

DS1621. !! Die I²C-Adresse für den DS1621 ist direkt angegeben. !!

Rückgabewert: – Verwendete Funktionen: v_SetNextI2Cval(), v_StartI2CandWait() Verwendete globale Variablen: Slave Verwendete Definitionen: – C-Sourcemodul: DS1621_Lib.c

void v_DS1621SetCMD(unsigned char ucCmd) v_DS1621SetCMD: Die Funktion setzt den Übergabewert “ucCmd” als Kommando

ein und startet den Sendevorgang für den DS1621 auf dem I²C-Bus. !! Die I²C-Adresse für den DS1621 ist direkt angegeben. !!

Rückgabewert: – Verwendete Funktionen: v_SetNextI2Cval(), v_StartI2CandWait() Verwendete globale Variablen: Slave Verwendete Definitionen: – C-Sourcemodul: DS1621_Lib.c

void v_DS1621ReadTemp(void) v_DS1621ReadTemp: Die Funktion startet einen Lesevorgang mit der Adresse des

DS1621 auf dem I²C-Bus und liest danach zwei Bytes aus. !! Die I²C-Adresse für den DS1621 ist direkt angegeben. !!

Rückgabewert: – Verwendete Funktionen: v_SetNextI2Cval(), v_StartI2CandWait() Verwendete globale Variablen: Slave Verwendete Definitionen: – C-Sourcemodul: DS1621_Lib.c

Page 155: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 155

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

3.2 Libraryfunktionen zu Encoder_Lib.c void v_InitEncoder(void) v_InitEncoder: Die Funktion initalisiert den Keyboard-Interrupt auf den Portpins P0.5

bis P0.7 und gibt den Keyboard-Interrupt frei. Außerdem wird der aktuelle Zustand des Encoders ausgelesen und intern in der Variablen „ucActEncVal“ abgespeichert.

Rückgabewert: – Verwendete Funktionen: Verwendete globale Variablen: cValue Verwendete Definitionen: – C-Sourcemodul: Encoder_Lib.c

void v_KeyboardInt(void) interrupt 7 v_KeyboardInt: Die ISR wertet die Portpins P0.5 und P0.7 aus und inkrementiert bzw.

dekrementiert die Variable cValue. Es wird außerdem das neue Keyboard-Pattern gesetzt, die Variable „ucActEncVal“ auf den aktuelle Zustand gesetzt und das Interrupt-Flag zurückgesetzt. !! Die Auswertung des Tasters im Encoder wird nicht durchgeführt. !!

Rückgabewert: – Verwendete Funktionen: Verwendete globale Variablen: cValue Verwendete Definitionen: – C-Sourcemodul: Encoder_Lib.c

3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c unsigned char uc_Data2I2C(unsigned char ucI2CDev, unsigned int uiI2CAddr, unsigned char *pucSrc)uc_Data2I2C: Die Funktion schreibt Daten in den I²C-Bus Baustein. Mit der Variablen

„ucI2CDev“ wird die I²C-Bus Adresse und mit „uiI2CAddr“ die Zieladresse im Baustein angegeben. Der Pointer „pucSrc“ zeigt auf die Startadresse im Source.

Rückgabewert:(I2C_OK, NACK_WRADR, NACK_WRDATA, UNDEFINED) Verwendete Funktionen: v_SetNextI2Cval(),v_StartI2CandWait() Verwendete globale Variablen: Slave Verwendete Definitionen: – C-Sourcemodul: I2C_EEPROM_Lib.c

Page 156: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

156 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

unsigned char uc_I2C2Data(unsigned char ucI2CDev, unsigned int uiI2CAddr, unsigned char *pucDes) uc_I2C2Data: Die Funktion liest Daten aus einem I²C-Baustein. Mit dem Übergabepa-

rameter „ucI2Dev“ wird die I²C-Bus Adresse, mit „uiI2CAddr“ die Startadresse des auszulesenden Bereichs angegeben. Der Pointer „pucDes“ zeigt auf die Startadresse im Zielbereich.

Rückgabewert: (I2C_OK, NACK_WRADR, NACK_WRDATA, UNDEFINED) Verwendete Funktionen: v_SetNextI2Cval(),v_StartI2CandWait() Verwendete globale Variablen: Slave Verwendete Definitionen: – C-Sourcemodul: I2C_EEPROM_Lib.c

unsigned char uc_Data2I2C_EEPROM(unsigned char ucI2CDev, unsigned int uiI2CAddr, unsigned char *pucSrc)uc_Data2I2C_EEPROM: Die Funktion schreibt Daten in ein EEPROM-Device. Da-

bei wird der Page-Mechanismus des EEPROM-Devices berücksichtigt. Die Größe der EEPROM-Page wird in der Definition „PAGESIZE“ angegeben. Mit dem Über-gabeparameter „ucI2CDev“ wird die I²C-Bus Adresse und mit „uiI2CAddr“ die Ziel-adresse im Baustein angegeben. Der Pointer „pucSrc“ zeigt auf die Startadresse im Source.

Rückgabewert: (I2C_OK, NACK_WRADR, NACK_WRDATA, UNDEFINED) Verwendete Funktionen: v_SetNextI2Cval(),v_StartI2CandWait() Verwendete globale Variablen: Slave Verwendete Definitionen: PAGESIZE C-Sourcemodul: I2C_EEPROM_Lib.c

3.4 Libraryfunktionen zu I2C_Lib.c void v_InitI2C(void) v_InitI2C: Mit dieser Funktion wird der I²C-Part initalisiert. Als Quarz wird der RC-

Oscillator angenommen. Die Datenübertragung wird auf 100 kHz eingestellt. Wird eine andere CPU-Frequenz verwendet, müssen die SFRs I2SCLL und SCLH ange-passt werden. Außerdem wird der Interrupt freigegeben.

Rückgabewert: – Verwendete Funktionen: – Verwendete globale Variablen: Slave, ucI2CError Verwendete Definitionen: (I2C_OK, NACK_WRADR, NACK_WRDATA, UNDEFINED) C-Sourcemodul: I2C_Lib.c

Page 157: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 157

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

void v_SetNextI2CVal(unsigned char ucVal) v_SetNextI2CVal: Mit Hilfe dieser Funktion werden Daten in die Struktur „Slave“ ge-

schrieben. Es wird der Inhalt von „ucVal“ in das Element „Slave.Val[]“ geschrieben. Der Offset auf das Array wird automatisch nach dem Schreiben um Eins erhöht. Es können maximal 64 Bytes in das Array geschrieben werden. Es findet keineÜberprüfung statt, ob ein Überlauf des Arrays stattfindet. !!

Rückgabewert: – Verwendete Funktionen: – Verwendete globale Variablen: Slave Verwendete Definitionen: (I2C_OK, NACK_WRADR, NACK_WRDATA, UNDEFINED) C-Sourcemodul: I2C_Lib.c

void v_StartI2CandWait(void) v_StartI2CandWait: Die Funktion startet den Sendevorgang beim I²C-Bus. Die Funk-

tion wartet solange, bis alle Daten übertragen bzw. empfangen wurden, bzw. bis ein Fehler auf dem I²C-Bus aufgetreten ist. Das Ergebnis der Übertragung ist in der glo-balen Variablen „ucI2CError“ abgelegt. Das Ergebnis kann eine der unten aufgeführ-ten Definitionen sein.

Rückgabewert: – Verwendete Funktionen: – Verwendete globale Variablen: btI2cFinished, ucI2CError Verwendete Definitionen: (I2C_OK, NACK_WRADR, NACK_WRDATA, UNDEFINED) C-Sourcemodul: I2C_Lib.c

void v_StartI2CTrans(void) v_StartI2CTrans: Die Funktion Funktion startet den Sendevorgang beim I²C-Bus und setzt die globale Variable „ucI2CError“ auf den Wert „I2C_OK“. Rückgabewert: – Verwendete Funktionen: – Verwendete globale Variablen: Slave, ucI2CError Verwendete Definitionen: (I2C_OK, NACK_WRADR, NACK_WRDATA, UNDEFINED) C-Sourcemodul: I2C_Lib.c

Page 158: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

158 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

void v_WaitI2CFinish(void) v_WaitI2CFinish: Die Funktion wartet, bis der Sende-/Empfangsvorgang auf dem

I²C-Bus beendet ist. Rückgabewert: – Verwendete Funktionen: – Verwendete globale Variablen: Slave, ucI2CError Verwendete Definitionen: (I2C_OK, NACK_WRADR, NACK_WRDATA, UNDEFINED) C-Sourcemodul: I2C_Lib.c

void void v_I2CInterrupt(void) interrupt 6 v_I2CInterrupt: Die ISR wertet das SFR I2STAT aus und sendet bzw. empfängt Da-

ten. Die Daten werden aus der Struktur „Slave“ gelesen bzw. in das Element „Slave.Val[]“ geschrieben. Wird ein Fehler auf dem I²C-Bus erkannt, z. B. fehlendes ACK, wird die Variable „ucI2CError“ mit einer der unten aufgeführten Definitionen gesetzt. Nach dem letztem gesendeten bzw. empfangenen Byte wird die Stopbe-dingung gesetzt. !! Beim Empfangen der Daten wird nicht überprüft, ob über das Array Slave.Val[] hinaus geschrieben wird. !!

Rückgabewert: – Verwendete Funktionen: – Verwendete globale Variablen: Slave, ucI2CError Verwendete Definitionen: (NACK_WRADR, NACK_WRDATA, UNDEFINED) C-Sourcemodul: I2C_Lib.c

3.5 Libraryfunktionen zu PCF8574_Lib.c void v_PCF8574WriteVal(unsigned char ucVal) v_PCF8574WriteVal: Mit dieser Funktion wird der Übergabeparameter “ucVal” an die

Portpins des PCF8574 ausgegeben. Rückgabewert: – Verwendete Funktionen: v_SetNextI2Cval(),v_StartI2CandWait() Verwendete globale Variablen: Slave Verwendete Definitionen: – C-Sourcemodul: PCF8574_Lib.c

Page 159: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 159

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

void v_PCF8574ReadVal(void) v_PCF8574ReadVal: Mit dieser Funktion wird der aktuelle Zustand an den Portpins

des PCF8574 eingelesen. Der eingelesene Wert ist in „Slave.Val[0]“ abgespeichert. Rückgabewert: – Verwendete Funktionen: v_StartI2CandWait() Verwendete globale Variablen: Slave Verwendete Definitionen: – C-Sourcemodul: PCF8574_Lib.c

3.6 Libraryfunktionen zu PortConfig.c void v_PortConfig(unsigned char ucPortAddr, unsigned char ucPin, unsigned char Config) v_PortConfig: Mit dieser Funktion kann die Betriebsart eines oder mehrerer Pins

innerhalb eines Ports gesetzt werden. Die Definitionen der Pins, Ports und der Be-triebsart können den enum-Aufzählungstypen entnommen werden.

Rückgabewert: – Verwendete Funktionen: – Verwendete globale Variablen: – Verwendete Definitionen: ePinADDR (Pin0, Pin1, Pin2, Pin3, Pin4, Pin5, Pin6, Pin7, AllPins) ePort (Port0, Port1, Port2, Port3) eConfig (BiDir, PushPull, InpOnly, OpenDrain) C-Sourcemodul: PortConfig.c

Page 160: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

160 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

3.7 Libraryfunktionen zu RS232DynLib.c unsigned char uc_Init_Serial(unsigned char ucBaudRate, unsigned char ucUARTMode)uc_Init_Serial: Mit dieser Funktion wird die serielle Schnittstelle initialisiert. Als Taktge-

ber wird der Baudratengenerator verwendet. Zur Berechnung der Baudrate wird die Definition „CPU_XTAL“ und die Einstellung vom SFR DIVM verwendet.

Mit der Variablen „ucBaudrate“ wird die Baudrate und mit ucUARTMode“ die Übertragungsbreite festgelegt. Die Definitionen aus den enum-Aufzählungstypen geben die Baudraten bzw. die Anzahl der Bits an. Zudem wird der Interrupt der seriellen Schnittstelle freigegeben.

Rückgabewert: 0x00 Verwendete Funktionen: – Verwendete globale Variablen: stRecRS232 Verwendete Definitionen: enUARTBaudrate (_600= 1, _1200= 2, _2400= 4, _4800= 8, _9600=16, _19200=32, _38400=64, _57600=96, _115200=192) enUARTConfig (_8BIT= 0x40, _9BIT= 0xC0) C-Sourcemodul: RS232DynLib.c

unsigned char uc_SendRS232(unsigned char * ucPtr, unsigned char ucLen) uc_SendRS232: Mit dieser Funktion wird ein Sendevorgang der seriellen Schnittstelle

gestartet. Der Pointer „ucPtr“ zeigt auf die Startadresse des zu sendenden Bereichs, bzw. des Wertes. In „ucLen“ ist die Anzahl der zu sendenden Bytes angegeben. Ist die Länge größer als das Array in der Struktur „stRecRS232.ucBuf[]“, wird der Sende-vorgang nicht durchgeführt. In diesem Fall ist der Rückgabewert 0xFF, ansonsten 0x00. Der weitere Sendevorgang wird von der ISR der seriellen Schnittstelle übernommen.

Rückgabewert: 0x00, 0xFF Verwendete Funktionen: memcpy() Verwendete globale Variablen: stRecRS232, ucSendOffset Verwendete Definitionen: – C-Sourcemodul: RS232DynLib.c

Page 161: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 161

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

void v_IntSer(void) interrupt 4 using 1 v_IntSer: In der seriellen ISR werden die Flags RI und TI abgefragt. Ist RI gesetzt und

der Empfangsbuffer noch frei, wird der empfangene Wert in das Strukturelement „stRecRS23.ucBuf[]“ geschrieben. !! Das RI-Flag wird auf jeden Fall gelöscht, auch wenn der Inhalt des SFR SBUF nicht gespeichert werden konnte. !!

Ist das TI-Flag gesetzt, wird überprüft, ob noch Daten zum Versenden vorhanden sind. Ist dies der Fall, wird der nächste Wert aus dem Array „stSendRS232.ucBuf[] gelesen und versendet. Andernfalls wird die Variable „stSendRS232.ucLen“ auf den Wert „0“ gesetzt.

Rückgabewert: – Verwendete Funktionen: – Verwendete globale Variablen: stRecRS232, ucSendOffset Verwendete Definitionen: – C-Sourcemodul: RS232DynLib.c

3.8 Libraryfunktionen zu RTCLib.c void v_GetTime(struct stWATCH *pWatch) v_GetTime: Die Funktion ermittelt aus der 32-bit Variablen „ulRTCTime“ die aktuelle

Zeit und weist diese der Struktur „stWatch“ zu. Rückgabewert: – Verwendete Funktionen: – Verwendete globale Variablen: ulRTCTime Verwendete Definitionen: – C-Sourcemodul: RTCLib.c

void v_InitRTC(void) v_InitRTC: Diese Funktion aktiviert den RTC und gibt den Interrupt frei. Der Reload-

wert für den RTC wird aus der define-Anweisung „RTC_RELOAD“ ermittelt. !! Der WDT wird in dieser Funktion ausgeschaltet. !!

Rückgabewert: – Verwendete Funktionen: – Verwendete globale Variablen: - Verwendete Definitionen: RTC_RELOAD C-Sourcemodul: RTCLib.c

Page 162: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

162 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

void v_SetTime(struct stWATCH *pWatch) void v_SetTime: Diese Funktion wandelt die Werte aus der Struktur pWatch in einen

32-bit Wert und weist dieses Ergebnis der Variablen „ulRTCTime“ zu. !! Es findet keine Überprüfung statt, ob die angebenen Werte in der Struktur zulässig sind. !!

!! Es sind nur Zeitangaben zwischen dem 01.01.1979 und dem 19.01.2038 zulässig. !! Rückgabewert: – Verwendete Funktionen: – Verwendete globale Variablen: stWatch, ulRTCTime Verwendete Definitionen: – C-Sourcemodul: RTCLib.c

bit b_SetAlarmTime(struct stWATCH *pWatch, unsigned char ucDayInfo) void v_SetTime: Diese Funktion wandelt die Werte aus der Struktur pWatch in einen

32-bit Wert und weist dieses Ergebnis der Variablen „stAlarm.ulTime“ zu. !! Es findet keine Überprüfung statt, ob die angebenen Werte in der Struktur zulässig sind. !!

!! Es sind nur Zeitangaben zwischen dem 01.01.1979 und dem 19.01.2038 zulässig. !! Rückgabewert: – Verwendete Funktionen: – Verwendete globale Variablen: stAlarm Verwendete Definitionen: – C-Sourcemodul: RTCLib.c

void v_RTC_ISR(void) interrupt 10 using 1 void v_RTC_ISR: Die ISR inkrementiert die Variable „ulRTCTime“ und setzt das Flag

RTCF im SFR RTCCON zurück. Rückgabewert: – Verwendete Funktionen: v_GetTime() Verwendete globale Variablen: ulRTCTime, stAlarm Verwendete Definitionen: – C-Sourcemodul: RTCLib.c

Page 163: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 163

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

3.9 Libraryfunktionen zu SAA1064_Lib.c v_InitSAA1064(unsigned char ucMode) v_InitSAA1064: Die Funktion initialisiert das I²C-Device SAA1064 auf der Adresse

„0x70“. Die Betriebsart wird im Übergabeparameter „ucMode“ angegeben. Die Funktion wartet solange, bis die Übertragung auf dem I²C-Bus beendet ist.

Rückgabewert: – Verwendete Funktionen: v_SetNextI2Cval(),v_StartI2CandWait() Verwendete globale Variablen: Slave Verwendete Definitionen: – C-Sourcemodul: SAA1064_Lib.c

void v_ConvVal(unsigned char ucValue) v_ConvVal : Die Funktion konvertiert einen Wert von 0 bis 9 und A bis F in ein

darstellbares Zeichen auf dem Experimentierboard. Dieses Zeichen wird in das Array Slave.Val[]“ mit Hilfe der Funktion „v_SetNextI2Cval()“ gespeichert.

Rückgabewert: – Verwendete Funktionen: v_SetNextI2Cval() Verwendete globale Variablen: Slave Verwendete Definitionen: – C-Sourcemodul: SAA1064_Lib.c

3.10 Libraryfunktionen zu TimerLibrary.c void v_InitTimer0(unsigned char ucMode) void v_InitTimer0: Mit dieser Funktion kann der Timer 0 initialisiert werden. Es

werden dabei nur die im SFR TMOD, AUXR1 und TMOD relevanten Bits verändert. Die anderen Bits in den SFRs bleiben erhalten. Über den Parameter „ucMode“ kann der Timer mit Hilfe der enum-Aufzählungstypen in die jeweilige Betriebsart gesetzt werden.

Rückgabewert: – Verwendete Funktionen: – Verwendete globale Variablen: – Verwendete Definitionen: enTimerMode (MODE0 =0, MODE1, MODE2, MODE3, MODE6 = 0x12) enTimerFunc (TIMER = 0, COUNTER = 4, GATE_OFF = 0, GATE_ON = 8, PWM_OFF = 0, PWM_ON = 0x20) C-Sourcemodul: TimerLibrary.c

Page 164: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

164 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

void v_InitTimer1(unsigned char ucMode) void v_InitTimer1: Mit dieser Funktion kann der Timer 1 initialisiert werden. Es

werden dabei nur die im SFR TMOD, AUXR1 und TMOD relevanten Bits verändert. Die anderen Bits in den SFRs bleiben erhalten. Über den Parameter „ucMode“ kann der Timer mit Hilfe der enum-Aufzählungstypen in die jeweilige Betriebsart gesetzt werden.

Rückgabewert: – Verwendete Funktionen: – Verwendete globale Variablen: – Verwendete Definitionen: enTimerMode (MODE0 =0, MODE1, MODE2, MODE3, MODE6 = 0x12) enTimerFunc (TIMER = 0, COUNTER = 4, GATE_OFF = 0, GATE_ON = 8, PWM_OFF = 0, PWM_ON = 0x20) C-Sourcemodul: TimerLibrary.c

Page 165: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 165

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

4. Index A51-Assembler 8 Adresse 8 ANSI-C 8 Anweisung 8 Argument 8 AT24C256 108 Aufzählungstyp

enum eMenu 85 enConfig 55, 58

BiDir 55, 58 InpOnly 55, 58 OpenDrain 55, 58 PushPull 55, 58

enDS1621Config 74 READ_TEMP 74

enI2CERROR 109 I2C_OK 109 NACK_WRADR 109 NACK_WRDATA 109 UNDEFINED 109

enMenu AUSGABE 85 EINSTELLUNGEN 85 HAUPTMENU 85 RESET 85 TEST 85

enPinADDR 55, 58 AllPins 55, 58 Pin0 55, 58 Pin1 55, 58 Pin2 55, 58 Pin3 55, 58 Pin4 55, 58 Pin5 55, 58 Pin6 55, 58 Pin7 55, 58

enPort 55, 58 Port0 55, 58

Port1 55, 58 Port2 55, 58 Port3 55, 58

enSAACONFIG 74, 76 DYNAMIC_MODE 74, 76

enSAASEG 47, 62, 71, 74, 76 _A 76 _B 76 _C 76 _D 76 _E 76 _F 76 ACHT 47, 62, 71, 74, 76 BLANK 71, 74, 76 DREI 47, 62, 71, 74, 76 EINS 47, 62, 71, 74, 76 FUENF 47, 62, 71, 74, 76 MINUS 71, 74, 76 NEUN 47, 62, 71, 74, 76 NULL 47, 62, 71, 74, 76 PUNKT 47, 62, 71, 74, 76 SECHS 47, 62, 71, 74, 76 SIEBEN 47, 62, 71, 74, 76 VIER 47, 62, 71, 74, 76 ZWEI 47, 62, 71, 74, 76

enTimerFunc 92 COUNTER 92 GATE_OFF 92 GATE_ON 92 PWM_OFF 92 PWM_ON 92 TIMER 92

enTimerMode 92 MODE0 92 MODE1 92 MODE2 92 MODE3 92 MODE6 92

enUARTBaudrate 121, 124 _115200 121, 124 _1200 121, 124

Page 166: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

166 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

_19200 121, 124 _2400 121, 124 _38400 121, 124 _4800 121, 124 _57600 121, 124 _600 121, 124 _9600 121, 124

enUARTConfig 121 _8BIT 121 _9BIT 121

Ausdruck 8 C51-Input

REG-File 10 C51-Output

I-File 9 LST-File 9 OBJ-File 10 SRC-File 10

C-Library 127 _getkey() 128 printf() 127 putchar() 127 scanf() 128

Compiler 9 Cross-Compiler 9 DCF77-Signal 93 Definitionen 9 Deklarationen 9 dScope-Simulator 10 EPM900

Enable P2 LED driver 16 Fehlermöglichkeiten 17 Use UCFG1 from START900.a51: 25

Funktion 9 (void) 151 _getkey() 129 c_ClearCnt(void) 102 main() 9 putchar (char) 127 putchar(char) 126

scanf(...) 129 uc_Clrscr() 34 uc_ConvVal(unsigned char) 71 uc_Data2I2C(unsigned char, unsigned

int, unsigned char *) 64, 148 uc_Data2I2C_EEPROM(unsigned char,

unsigned int, unsigned char *) 114, 149

uc_I2C2Data(unsigned char, unsigned int, unsigned char *) 64, 149

uc_Init_Serial(unsigned char, unsigned char) 125, 153

uc_Init_Serial(unsigned int, unsigned char) 121

uc_LCDIni() 34 uc_ReadVal(void) 102 uc_SendRS232(unsigned char *,

unsigned char) 121 uc_SendRS232(unsigned char *,

unsigned char) 153 v_ConvVal(unsigned char) 74, 76, 156 v_DS1621ReadTemp(void) 73, 147 v_DS1621SetCMD(unsigned char) 73,

147 v_DS1621StartConv(void) 73 v_DS1621StartCov(void) 147 v_ExtInt1(void) 79 v_getTime(void) 154 v_I2CInterrupt(void) 40, 44, 47, 50, 60,

110, 151 v_InitEncoder(void) 148 v_InitEncoder(void) 66, 68, 80 v_InitI2C(void) 149 v_InitI2C(void) 44, 47, 50, 60, 63, 110 v_InitRS232(void) 25 v_InitRTC(void) 154 v_InitSAA1064(unsigned char) 74, 155 v_InitTimer0(unsigned char) 92, 156 v_InitTimer0(void) 88, 89, 90 v_InitTimer0_1ms(void) 66, 68 v_InitTimer1(unsigned char) 92, 156 v_InitTimer1(void) 98

Page 167: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 167

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

v_InitTimer10msec(void) 96 v_IntSer(void) 22, 25, 154 v_KeyboardInt(void) 31, 38, 66, 68, 80,

148 v_PCF8574ReadVal(void) 77, 152 v_PCF8574WriteVal(unsigned char) 77,

151 v_PortConfig(unsigned char, unsigned

char, unsigned char) 55, 57, 152 v_RTC_ISR(void) 155 v_SetNextI2Cval(unsigned char) 44, 47,

50, 60, 110 v_SetNextI2CVal(unsigned char) 150 v_SetTime(void) 155 v_SM_Printf() 34 v_StartFilter(void) 98 v_StartI2CandWait(void) 64, 110, 150 v_StartI2CTrans(void) 44, 47, 50, 60,

110, 150 v_Timer0Int(void) 36, 66, 68, 88, 89, 90,

95, 96, 105 v_Timer1Int(void) 98 v_WaitI2Cfinish(void) 44, 47, 50, 60,

110 v_WriteVal(unsigned char) 102

Hardwarearchitektur Harvard 9 VNM (von Neumann) 9 von Neumann 9

H-File Siehe C51-Input I²C

EEPROM 108 PAGESIZE 113

I-File Siehe C51-Output IMT901 104

Impulsgeber 107 Linker 9 LNK-File 9 LPC900

Comperator 27 I²C-Bus 40

ISR 1 66, 68, 88, 89, 90, 95, 96, 105 ISR 2 79, 118, 119 ISR 3 98 ISR 4 22, 25 ISR 6 40, 44, 47, 50, 60, 110 ISR 7 31, 38, 66, 68, 80 Low-Cost A/D: 27 Reset 24 SFR

AD1DAT2 29 ADCON1 29 ADINS 29 ADMODB 29 AUXR1 37, 38, 92 BRGCON 22, 25, 121, 125 BRGR0 22, 25, 121, 125 BRGR1 22, 25, 121, 125 CMP1 28 DIVM 125 EA 22, 25, 31, 38, 40, 44, 47, 50, 66,

68, 71, 75, 79, 80, 82, 84, 85, 88, 89, 90, 95, 96, 98, 105, 112, 115, 118, 119, 123

EA1 36 EI2C 40, 47, 50, 60, 63, 110 EII2C 44 EKB1 38 EKBI 31, 66, 68, 80 ES 22, 25, 123 ET0 36, 66, 68, 88, 89, 90, 95, 96, 105 ET1 98 EX1 79, 118, 119 I2CON 40, 44, 47, 50, 60, 63, 64, 110 I2DAT 40, 44, 47, 50, 60, 110 I2SCLH 40, 44, 47, 50, 60, 63, 110 I2SCLL 40, 44, 47, 50, 60, 63, 110 I2STAT 44, 47, 50, 60, 110 IP1 79 ISR 1 36 IT1 79, 118, 119 KBCON 31, 38, 66, 68, 80

Page 168: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

168 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

KBMASK 31, 38, 66, 68, 80 KBPATN 31, 38, 66, 68, 80 P0 16, 18, 28, 31, 38, 66, 68, 80, 93,

102 P0M1 28, 37, 38, 55, 102 P0M2 37, 38, 55, 102 P1 22, 66, 68 P1M1 22, 25, 36, 40, 44, 47, 50, 55, 60 P1M2 22, 25, 36, 40, 44, 47, 50, 55, 60 P2 16, 18, 25, 28, 29, 31, 59, 78, 79,

80, 89, 90, 95, 102, 105, 117, 118 P2M1 16, 18, 28, 29, 31, 34, 55, 102 P2M2 16, 18, 31, 34, 55, 102 P3M1 55 P3M2 55 PCON 121, 125 REN 123, 129 RI 121, 126, 129 RSTSRC 25 SBUF 22, 25, 126, 127, 129 SCON 22, 25, 121, 125 TAMOD 37, 38, 92 TF0 36, 66, 68, 88, 89, 90, 95, 96, 105 TF1 98 TH0 36, 66, 68, 88, 89, 90, 95, 96, 105 TH1 37, 38, 93, 98, 118 TI 22, 25, 121, 126, 127 TL0 36, 66, 68, 88, 89, 90, 95, 96, 105 TL1 37, 38, 98, 118 TMOD 36, 37, 38, 66, 68, 88, 89, 90,

92, 95, 96, 98 TR0 36, 66, 68, 88, 89, 90, 96, 105 TR1 37, 38, 93, 98, 118, 119

UART 23 UCFG1 24

LPC-Experimentierboard 74HC540 17 7805 12 7-Segment LED 76 BC547B 47

C1 13 C10 35 C11 35 C12 47 C14 17 C18 66 C2 12, 13 C20 47 C22 28 C3-C7 20 C8 43 C9 50 D1 20 D2 43 D6 47 DS1621 40, 50, 71, 73 EPM900 14 Freilaufdiode 53 HD44780 32 J11 43 J14-20 34 J28 13, 14 J29 14 J5 40 J6 40 J7 30 J8 30 J9 30 Lautsprecher 54 LCD 32, 81

44780 81 DD-RAM 81

Leiterplatte 142 LM258 35 MAX232 19 MCB900 14 N1 13 N2 35 N4 50 N6 54

Page 169: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Arbeiten mit dem LPC-Experimentierboard 169

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

OP 34 Impedanzwandler 35 Integrierer 34

PCF8574 40, 42, 77 PT1 32, 34 PT2 28 PT3 28 R1 13 R2,R4,R6,R8,R10,R12,R14,R16,R36-43

15 R26 54 R27 54 R28 54 R29 54 R3,R5,R7,R9,R11,R13,R15,R17-25 15 R30 40 R31 40 R32 54 R33 35 R34 35 R44 30 R45 30 R46 18 R55 30 R56 28 Relais 53 S17 30 S1-S8 15 S9-S16 15 SA36-11HWA 47 SAA1064 40, 46, 47, 73, 76 Schalter (S1-S8) 15 Spannungsversorgung 12 Steckplatine 108 Stückliste 145 T1 54 T2 54 T4 47 T5 47 Taster (S9-S16) 15

V1 13 V2 13 V3 54 V4 54 V5 18 VL1-VL4 47 X1 13 X2 65, 66, 102 X6 33 X7 33 X8 20 X9 13 XDA 35 XIN2 35 XOUT2 35

LST-File Siehe C51-Output M51-File 10 Makro 9

#define 98 %%CPU_XTAL 124 FILTER 98 GRENZ_O 105 GRENZ_U 105 PAGESIZE 114 PCLK 105 RELOAD_TIME_O 105 RELOAD_TIME_U 105 SRAMSIZE 102 XOFF (0x13) 126 XON (0x11) 126 XTAL 124

OBJ-File 10 Siehe C51-Output Operation 10 P89LPC935 35 Projekt

CallRCOsci 66, 68 DCF77_59sec 96 DCF77_DetectSpike 98 DCF77_Tick 95

Page 170: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

170 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

I2C_EEPROM 112 I2C_LIB 60, 63 I2C_Test 40, 53 LCD_Port: 34 Mess_ReedRelais 118, 119 PortConfig 55 RS232DynLibrary 125 RS232Library 121 RS232Printf 127 RS232Scanf 128, 131, 133, 137, 140, 142 TemperaturMes 71 Test_2DimLCDMenu 85 Test_ConfigLib 54, 59 Test_DS1621 50 Test_Encoder 31 Test_EncoderLib 79 Test_I2C_EEPROM_LIB 114 Test_IOExp_Int 79 Test_IOExp_Lib 77 Test_LCDCursor 82 Test_LCDMenu 84 Test_OP_Inc 38 Test_OP_tiT 37 Test_OPImp 36 Test_PCF8574 44 Test_ReedRelais 117 Test_SAA1064 47 Test_TempModular 73 Test_TimerLib 93 Test_TimRec 88 Test_TrimFreq 89, 90 TestAD_PT2 29 TestBalkenLED 18 TestComp1_Vref 28 TestExp_Taster 16 TestExtRAM 102 TestIMT901 104 TestIMT901Enc 107 TestReset: 25 TestRS232 22

PWM-Signale 34 RAM 10 Reed-Relais 115

Ansprechzeit 117 Prellzeit 117

ROM 10 Schlüsselwort 10 ser. Schnittstelle 23 SFR 10 Sourcemodul 9, 10 SRC-File Siehe Steuerparameter SRC START900.a51 24 Steuerparameter

#pragma 10 struct

stI2C 43, 44, 47, 50, 62, 109 stRecRS232 121 stSendRS232 121

Syntaxaufbau Buch 8 Terminal Programm 23 XRAM 10

Page 171: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

Page 172: Weitere Informationen zu den LPC900-Beschreibungen ... V0.22.pdf · LCD-Ansteuerung (Port 2 ... 3.3 Libraryfunktionen zu I2C_EEPROM_Lib.c _____ 155 3.4 ... 8051-Derivats angesprochen

172 Kapitel 2

Weitere Informationen zu den LPC900-Beschreibungen erhalten sie unter www.c51.de

5. Literaturverzeichnis [1] Michael Baldischweiler Der Keil C51-Compiler Teil 1 ELECTRONIC MEDIA Verlag ISBN 3-9804331-6-1 [2] Michael Baldischweiler Praxis mit dem C51-Compiler Teil 2 ELECTRONIC MEDIA Verlag ISBN 3-9804331-7-x [3] Michael Baldischweiler Keil C51/Philips LPC900 Hardware-Software-Toolchain ELECTRONIC MEDIA Verlag ISBN 3-9804331-9-6 Rolf Klaus Der Mikrocontroller 8051, 8052 und 80C517 Vdf Hochschule AG an der ETH Zürich ISBN 7-281-2478-8 Michael J.Pont Patterns for Time-Triggered Embedded Systems ACM PRESS BOOKS ISBN 0-201-33138-1 Kernighan/Ritchie Programmieren in C Hanser Verlag ISBN 3-446-15497-3