86
1 Inhaltsverzeichnis – Leseprobe 1.1 Die AVR-Produktfamilie von ATMEL ........................................................................ 5 1.2 Die Entwicklungsumgebung .................................................................................... 6 1.3 Das Programmiergerät ............................................................................................ 7 1.4 Das Entwicklerboard ................................................................................................ 9 1.5 Signalpegel (Logik-Pegel) ....................................................................................... 10 1.6 Das Taktsignal ........................................................................................................ 12 1.7 Pinbelegung des ATMega88 .................................................................................. 16 1.8 Compiler und Linker .............................................................................................. 16 1.9 Vorarbeiten für das erste Projekt .......................................................................... 18 1.11.1 Aufbau der Hardware ............................................................................................ 18 1.11.2 Stromversorgung des Mikrocontrollers................................................................. 19 1.11.3 Aufbau der Grundschaltung .................................................................................. 21 1.12 Einführung in Atmel Studio 6 – Das erste Projekt ................................................. 22 1.13 Debuggen in Atmel Studio 6 .................................................................................. 25 1.14 Das erste Programm .............................................................................................. 28 1.15 Das hexadezimale Zahlensystem ........................................................................... 30 1.16 Registerinhalte verändern ..................................................................................... 31 2.1 Mit Variablen arbeiten .......................................................................................... 32 2.2 Aufruf von Funktionen........................................................................................... 33 3 Der Watchdog ........................................................................................................ 35 4 Programmbeispiel Lauflicht ................................................................................... 37 5 Einlesen von Tastenzuständen .............................................................................. 38 5.1 Einlesen eines „aktive-low Tasters“....................................................................... 39 5.2 Entprellen eines Tasters ........................................................................................ 40 5.3 Schalten von Lasten mit Transistoren ................................................................... 41 6 Die State Machine ................................................................................................. 42

Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

  • Upload
    lengoc

  • View
    222

  • Download
    3

Embed Size (px)

Citation preview

Page 1: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

1

Inhaltsverzeichnis – Leseprobe

1.1 Die AVR-Produktfamilie von ATMEL ........................................................................ 5

1.2 Die Entwicklungsumgebung .................................................................................... 6

1.3 Das Programmiergerät ............................................................................................ 7

1.4 Das Entwicklerboard ................................................................................................ 9

1.5 Signalpegel (Logik-Pegel) ....................................................................................... 10

1.6 Das Taktsignal ........................................................................................................ 12

1.7 Pinbelegung des ATMega88 .................................................................................. 16

1.8 Compiler und Linker .............................................................................................. 16

1.9 Vorarbeiten für das erste Projekt .......................................................................... 18

1.11.1 Aufbau der Hardware ............................................................................................ 18

1.11.2 Stromversorgung des Mikrocontrollers ................................................................. 19

1.11.3 Aufbau der Grundschaltung .................................................................................. 21

1.12 Einführung in Atmel Studio 6 – Das erste Projekt ................................................. 22

1.13 Debuggen in Atmel Studio 6 .................................................................................. 25

1.14 Das erste Programm .............................................................................................. 28

1.15 Das hexadezimale Zahlensystem ........................................................................... 30

1.16 Registerinhalte verändern ..................................................................................... 31

2.1 Mit Variablen arbeiten .......................................................................................... 32

2.2 Aufruf von Funktionen ........................................................................................... 33

3 Der Watchdog ........................................................................................................ 35

4 Programmbeispiel Lauflicht ................................................................................... 37

5 Einlesen von Tastenzuständen .............................................................................. 38

5.1 Einlesen eines „aktive-low Tasters“....................................................................... 39

5.2 Entprellen eines Tasters ........................................................................................ 40

5.3 Schalten von Lasten mit Transistoren ................................................................... 41

6 Die State Machine ................................................................................................. 42

Page 2: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

2

6.1 Programmbeispiel Ampelregelung mit einer State Machine ................................ 43

7 Interrupts ............................................................................................................... 44

7.1 Funktionsweise einer Interruptsteuerung ............................................................. 44

7.2 Ausführung eines Interrupts mit einem Programmbeispiel .................................. 45

7.3 Messen einer Spannung mit dem ADC .................................................................. 48

8 Der 8-Bit Timer/Counter ........................................................................................ 51

8.1 Der Prescaler ......................................................................................................... 52

8.2 Der 8bit Timer (Timer 0) ........................................................................................ 53

8.2.1 Der 8bit Timer im Normal Mode ........................................................................... 54

8.2.2 Registereinstellungen im Normal Mode ................................................................ 55

8.2.3 Eine LED im Sekundentakt blinken lassen ............................................................. 57

8.2.4 Ansteuerung eines Servos ..................................................................................... 58

8.2.5 Die Stromversorgung eines Servos ........................................................................ 59

8.2.6 Servoposition per Taster steuern .......................................................................... 60

8.2.7 Eine LED im Sekundentakt im CTC Mode blinken lassen ....................................... 61

8.3 OCR-Modus (Output Compare Mode) ................................................................... 62

8.4 PWM-Mode (Pulsweitenmodulation) ................................................................... 63

9 LED-Fading ............................................................................................................. 66

9.1 SPI - Kommunikation mit einem 16 Mbit Flash-Speicher ...................................... 67

10 Die UART / USART-Schnittstelle............................................................................. 69

10.1 Ein Zeichen vom PC an die USART-Schnittstelle senden ....................................... 70

11 Die I2C-Schnittstelle (TWI-Schnittstelle) ................................................................ 72

11.1 Prinzip der I²C - Datenübertragung ....................................................................... 72

11.2 Datenübertragung von einem Master zu einem Slave .......................................... 74

11.3 Datenübertragung von einem Slave zu einem Master .......................................... 74

11.4 Bitübertragung....................................................................................................... 75

11.5 Start- und Stopbedingung ..................................................................................... 76

11.6 Repeated Start ....................................................................................................... 76

11.7 I²C – Beispielprojekt Temperaturmessung mit dem LM75 .................................... 77

11.8 I²C – Beispielprojekt Lichtmessung mit dem ISL29020 .......................................... 78

Page 3: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

3

12 Ansteuerung einer 7-Segmentanzeige im Multiplexbetrieb ................................. 79

13 Ansteuerung eines LC-Displays .............................................................................. 81

14 LED Punktmatrix Display ansteuern ...................................................................... 85

Page 4: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

4

Heimo Gaicher

AVR-Mikrocontroller

Programmieren in C für Einsteiger

Vorwort

Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler, die die ersten Schritte in der Programmierung von Mikrocontrollern machen. Da Mikrocontroller sehr komplexe Systeme sind, wurde in diesem Buch großen Wert darauf gelegt, den Einstieg so einfach wie möglich zu gestalten. Theoretische Teile werden daher mit vielen praktischen Beispielen unterstützt.

Die Beispiele wurden im Programmcode genau dokumentiert und führen so zu einem besseren Verständnis. Das Buch ist kein Kompendium sondern eine für den Studierenden schrittweise Anleitung um Projekte besser zu verstehen und selbständig eigene Projekte entwickeln zu können.

Das Buch wurde aus meiner eigenen praktischen Erfahrung mit großer Sorgfalt geschrieben. Sollten sich dennoch Fehler eingeschlichen haben, freue ich mich über entsprechende Hinweise. Anmerkungen und Kritiken sind unter info@ne555,.at immer willkommen.

Heimo Gaicher, Jahrgang 1969, ist bereits seit jungen Jahren leidenschaftlicher Bastler, Elektroniker und Programmierer. Berufsbegleitend absolvierte er die Werkmeisterschule für industrielle Elektronik und anschließend die Höhere Technische Bundeslehr- und Versuchsanstalt der Fachrichtung Elektronik und Technische Informatik (BULME) in Graz. In seiner Industrielaufbahn befasst er sich mit der Hard- und Softwareentwicklung für innovative Produkte aus den Bereichen der LED-Lichttechnik, der Entwicklung von Prüfumgebungen sowie der Entwicklung von Steuergeräten für Allradsysteme.

Page 5: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

5

1.1 Die AVR-Produktfamilie von ATMEL

Für alle Projekte in diesem Buch werden die AVR-Mikrocontroller ATMega88 und Attiny44 von ATMEL verwenden. Die Controller sind preiswert, leistungsfähig und es gibt sie von klein bis groß für eine Vielzahl von Anwendungen. Vor allem ist aber auch die Entwicklungsumgebung (Das ist die Software mit der der Programmcode geschrieben wird) kostenlos.

Die AVR-Serie gehört zu den 8-Bit-RISC-Prozessoren und verfügt über eine Harvard-Architektur. Der Vorteil dieser Architektur ist, dass Programm- und Datenspeicher über getrennte Busse angesteuert werden und somit auf Daten- und Programmspeicher gleichzeitig zugegriffen werden kann.

Hier ein Überblick über beliebte Modelle aus der Atmel Familie:

ATtiny Die ATtiny-Serie ist die kleinste und preiswerteste Serie mit wenigen Ein- und Ausgängen, einem kleinem Speicher, geringer Spannungsversorgung und sehr geringem Stromverbrauch. Diese Serie eignet sich gut für Kleinstanwendungen wo „geringer“ Rechenpower, kleinste Abmessungen und geringer Energieverbrauch (Batterieanwendungen) gefordert sind.

ATtiny4 ATtiny44 ATtiny2313

ATMega Diese Serie ist wohl die attraktivste für den Bastler und Hobbyelektroniker da sich diese Controller auch schon für etwas größere Projekte eignen.

ATMega88 ATMega32 ATMega128

ATXMega Das ist die neueste Serie von 8/16-Bit AVR-Controllern. Ausgestattet mit vielen Schnittstellen und I/O-Pins, großem Speicher, hoher Taktrate gibt es diese Mikrocontroller in 44 bis 100 poligen SMD Gehäuse. Dieser Typ eignet sich für größere und komplexe Anwendungen.

Page 6: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

6

ATXMega32 ATXMega128

Sonstige Für verschiedene Einsatzbereiche wie Automotive, Lightnig, Building Automation, Home Entertainment uvm. gibt es einige spezielle AVR-Controller wie z.B. AT90PWM316, AT90CAN128 und in der derzeit aktuellsten Variante ARM Cortex Controller.

AT90PWM316 im SOIC und QFN-Gehäuse

1.2 Die Entwicklungsumgebung

Für die Entwicklung einer Anwendung muss zuerst ein Programmcode in einem Editor geschrieben und in den Programmspeicher des Mikrocontrollers übertragen werden.

Hierfür gibt es Software, welche nicht nur einen Editor sondern auch einen Compiler, Linker, Debugger und Simulator enthält und dadurch das Leben eines Programmierers erheblich einfacher gestaltet.

Hier hat sich die Entwicklungsumgebung Atmel Studio etabliert, welche von ATMEL kostenlos zum Download angeboten wird.

Atmel-Studio ist eine kostenlose Entwicklungsumgebung (abgekürzt IDE, engl. integrated development environment) für AVR- und ARM-Controller bestehend aus einem Editor, Simulator, Debugger, Assembler und GNU C-Compiler sowie einer Projektverwaltung und einigen anderen Werkzeugen. Mit dieser Entwicklungsumgebung kann der Mikrocontroller in C bzw. C++ wie auch in Assembler programmiert werden.

Page 7: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

7

Die derzeit (Juni 2015) aktuellste Version ist Atmel Studio 6.2. Atmel Studio können Sie direkt unter http://www.atmel.com/atmelstudio herunter laden. Auch unter Linux können Sie Software für AVR-Controller entwickeln. Dafür gibt es spezielle Tools wie z.B. GNU BinUtils, AVRDUDE oder UISP. Weiterführende Informationen und Literatur finden Sie im Internet.

1.3 Das Programmiergerät

Ein Programmiergerät (Programmer) ist die Schnittstelle zwischen dem Mikrocontroller (Target) und dem PC und wird benötigt um den Programmcode in den Mikrocontroller einzuspielen. Neben VCC und GND für die Stromversorgung werden zur Kommunikation vier Leitungen (/RESET, SCK, MISO, MOSI) zwischen dem Programmiergerät und dem Mikrocontroller benötigt. Auf die Bedeutung dieser Anschlüsse wird im Verlauf dieses Buches noch genauer eingegangen.

Abb.1.1: Verbindung von PC, Programmiergerät und Mikrocontroller

Die Ansteuerung des Programmiergerätes muss vom Atmel-Studio unterstützt werden. Damit wir also unsere am PC geschriebene Software in den Speicher des Mikrokontrollers übertragen können, benötigen wir einen ISP-Programmer.

Reset AVR

DRAGON

Programmiergerät

Mikrocontroller

MISO

MOSI

CLK

Page 8: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

8

ISP (In-System-Programming) bedeutet, einen Mikrocontroller oder anderen programmierbaren Baustein im eingebauten Zustand zu programmieren. Dazu muss der Mikrocontroller entsprechend verschaltet sein. Das bedeutet, die benötigten Anschlüsse am Mikrocontroller (/RESET, SCK, MISO, MOSI) müssen zugänglich sein und dürfen nicht anderweitig benutzt werden, beziehungsweise nur im zulässigen Rahmen.

Wenn bei einem Mikrocontroller alternative SPI-Pins vorhanden sind, sind diese standardmäßig für die SPI-Datenübertragung eingestellt. In diesem Fall muss auch der ISP-Programmieranschluss mit den alternativen SPI-Pins MOSI_A, MISO_A, SCK_A und SS_A verbunden werden.

Es gibt eine ganze Reihe verschiedener Programmiergeräte wie zum Beispiel ATMEL AVR-ISP, ATMEL AVR DRAGON, USBisp, usbprog, mySmartUSB uvm. am Markt.

Abb.1.2: ISP-Programmer mySmart USB light

Bei der Auswahl des geeigneten Programmiergerätes sollten Sie darauf achten, dass das Programmiergerät die passende Schnittstelle zu ihrem PC (meist USB) aufweist und mit ihrer Entwicklungsumgebung kompatibel ist.

Abb.1.3: Programmer AVR-ISP von ATMEL Abb.1.4: Programmer JTAG ICE 2 von ATMEL

Weiters sollte das Programmiergerät eines Softwareentwicklers debugging unterstützen. Ein Debugger ist ein Werkzeug zum schrittweisen Auffinden von Programmfehlern (engl. bugs). Hier hat sich zum Beispiel Atmels original AVR Dragon etabliert.

Page 9: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

9

Abb.1.5: AVR-Dragon Programmer von ATMEL

Der AVR Dragon ist ein sehr leistungsfähiges und preiswertes Programmiergerät. Die großen Vorteile des Dragons sind, dass er alle Programmiermodi beherrscht, inklusive High-Voltage Parallel Programming ("verfuste" AVRs retten), dass er ein natives USB-Interface hat, von AVR-Studio unterstützt wird, und sogar JTAG und debugWIRE ICE / Debugging unterstützt (bei den AVRs die dies können).

Zu den größten bekannten Nachteilen gehören, dass der Dragon ohne Gehäuse, ohne USB-Kabel und ohne Programmierkabel geliefert wird. Daneben wird aufgrund der Stromversorgung ein USB-Hub mit Netzteil empfohlen.

1.4 Das Entwicklerboard

Am Markt gibt es eine Vielzahl verschiedener Entwicklerboards mit unterschiedlicher Peripherie. Bevor Sie sich aber ein fertig aufgebautes Board anschaffen, sollten Sie die ersten Projekte mit einem Steckbrett (Breadboard) aufbauen.

Diese Vorgehensweise ist besonders für den Anfang sehr zu empfehlen, da ein Entwicklerboard mit seiner fertig bestückten Peripherie für den Einsteiger oft zu komplex und daher sehr verwirrend sein kann.

Der Aufbau auf dem Breadboard ist rasch erledigt und Fehler können schnell korrigiert werden. Der Nachteil eines Breadboards ist, dass man bei größeren Schaltungsaufbauten schnell die Übersicht verlieren kann. Sollten Sie kein Breadboard zur Verfügung haben, können Sie die Projekte auch auf einer Lochrasterplatine aufbauen. Wenn möglich sollten Sie hier dem Mikrocontroller aber einen Sockel spendieren um ihn bei Bedarf einfach und rasch tauschen zu können.

Page 10: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

10

Abb.1.6: Schaltungsaufbau auf dem Breadboard mit angeschlossenen AVR Dragon

Eine weitere Möglichkeit ist es, sich ein Entwicklerboard selbst zu bauen. Dazu zeichnen Sie sich den Schaltplan und das Layout z.B. mit dem CAD-Programm EAGLE und lassen die Platine von einem Anbieter für Leiterplatten fertigen.

Wenn Sie etwas Erfahrung mit dem Ätzen von Platinen haben, können Sie die Leiterplatte natürlich auch selbst fertigen. Hier sollten Sie darauf achten, dass das Gehäuse des Mikrocontrollers nicht zu klein ist, damit Sie den Controller noch per Hand auflöten können.

Die folgende Abbildung zeigt ein selbst entworfenes Board mit einem AT90PWM316, 4 Taster, 8 LEDs, einer RGB-LED, einem 6-poligen Programmierstecker und einem 3,3V Linearregler für die Stromversorgung.

Alle Pins des Mikrocontrollers wurden hier auf Buchsenleisten ausgeführt. Damit können Sie ganz einfach und schnell eine Schaltung mit Drahtbrücken aufbauen. So ein Board können Sie natürlich auch auf einer Lochrasterplatine mit bedrahteten Bauteilen aufbauen.

1.5 Signalpegel (Logik-Pegel)

In der Digitaltechnik werden die zu verarbeitenden Daten durch Spannungspegel dargestellt. Zum Beispiel entspricht eine Spannung von 0V einem LOW-Pegel und eine Spannung von 5V einem HIGH-Pegel.

Page 11: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

11

Konkret stimmt diese Aussage aber nicht ganz. Was, wenn ein Spannungspegel von 4,5V auftritt? Gilt dieser Spannungswert noch als HIGH oder nicht?

Je nach verwendeter Technologie (TTL, CMOS, etc.) sind gewisse Spannungsbereiche für ein eindeutiges LOW- oder HIGH-Signal erlaubt. Für CMOS(5V) ist z.B. eine Eingangsspannung welche größer als 3,5V ist als ein eindeutiges HIGH-Signal zu werten. Eine Eingangsspannung unter 1,5V gilt als LOW-Signal.

Der Bereich zwischen 1,5V und 3,5 ist nicht definiert und wird als verbotener Bereich bezeichnet. Man unterscheidet zwischen Eingangs- und Ausgangspegel. Eingangspegel sind jene Spannungspegel, welche für den Eingang eines Bausteins gelten. Ausgangspegel sind Spannungspegel, welche ein Baustein an seinem Ausgang liefert.

Abb.1.18: Gängige Logik-Pegel TTL, 5V-CMOS und 3,3V-CMOS

Eingangspegel 5V-CMOS:

VIL <1,5V (V Input Low) VIH >3,5V (V Input High)

Eine Eingangsspannung unter 1,5V wird sicher als LOW, über 3,5V sicher als HIGH erkannt.

Ausgangspegel 5V-CMOS:

VOL <0,5V (V Output Low) VOH >4,44V (V Output High)

Der Ausgang liefert sicher ein LOW-Signal welches kleiner als 0,5V ist und ein HIGH-Signal, welches größer als 4,44V ist. Der Störabstand (Das ist die Differenz zwischen VOH und VIH bzw. zwischen VIL und VOL) bei 5V-CMOS beträgt rund 1V. Welche Ein- und Ausgangspegel

Page 12: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

12

für einen Mikrocontroller unter den gegebenen Bedingungen (Versorgungsspannung VCC ) gelten, sehen Sie im jeweiligen Datenblatt unter „electrical characteristics“.

Abb1.19: DC characteristics (VIL und VIH)des ATMega88 aus dem Datenblatt

1.6 Das Taktsignal

Wie im Kapitel 1.5 (Der Mikrocontroller) bereits angeführt, benötigt ein Mikroprozessor ein Taktsignal um eine Rechenoperation ausführen zu können. Dieses Taktsignal kann intern durch einen bereits im Mikrocontroller vorhandenen RC-Oszillator oder durch einen externen Quarz bzw. Keramikresonator erzeugt werden.

Ein Taktsignal besteht im Wesentlichen aus einem periodisch wiederkehrenden Signal welches abwechselnd zwischen High und Low hin- und her pendelt. Um dieses Taktsignal zu generieren wird ein Oszillator (Sinusoszillator) benötigt welcher ein möglichst konstant schwingendes Signal erzeugt. Um aus einem sinusförmigen Signal ein rechteckförmiges Taktsignal zu erhalten, kann beispielsweise ein Komparator oder Schmitt-Trigger zur Signalwandlung verwendet werden.

Abb.1.20: Aus einem Sinussignal wird ein rechteckförmiges Taktsignal erzeugt

AVR-Controller können mit verschiedenen Taktquellen versorgt werden. Diese Taktquellen werden über die Fusebits (CKSEL-Bits) eingestellt. Fusebits sind spezielle Register welche extern z.B. mittels Programmiergerät gesetzt oder gelöscht werden können. Mit diesen Fusebits werden sozusagen die Grundeinstellungen wie Taktquelle und Taktfrequenz eines Mikrocontrollers vorgenommen.

Mehr Informationen dazu finden Sie auch im Kapitel 1.16 (Fusebits). Grundsätzlich benötigen alle Oszillatoren und Quarze eine gewisse Anlaufzeit um eine stabile

Page 13: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

13

Schwingung und damit einen stabilen Takt zu erzeugen. Auch diese Einstellungen werden wie in der folgenden Abbildung gezeigt mit Hilfe der Fusebits vorgenommen.

Abb.1.21: Fusebit Einstellungen des internen RC-Oszillators

Die Einstellungen der jeweiligen Einschwingzeiten der unterschiedlichen Taktquellen sollten dem Datenblatt entnommen werden. Wie die entsprechende Einstellung der Fusebits und der Taktquelle vorgenommen wird, erfahren Sie im Kapitel 1.12 (Einführung in Atmel Studio 6 – das erste Projekt).

Interner RC-Oszillator

Der interne RC-Oszillator ist wie der Name schon sagt bereits im Chip integriert und ist standardmäßig als Taktquelle mit einem Takt von 1MHz (8MHz Grundtakt mit dem Fusebit CKDIV8 auf 1MHz herunter geteilt) im Auslieferungszustand des Mikrocontrollers vorkonfiguriert.

Der Vorteil des internen RC-Oszillators ist der rasche Einschwingvorgang von weniger als 10 Taktzyklen um ein stabiles Taktsignal zu erzeugen. Weiters benötigt der interne RC-Oszillator sehr wenig Strom und eignet sich daher besonders für batteriebetriebene Anwendungen.

Der Nachteil des internen RC-Oszillators ist jedoch die Temperaturabhängigkeit und damit verbunden eine relativ hohe Frequenzabweichung von bis zu ±10%. Diese Taktquelle eignet sich daher für alle Anwendungen bei denen keine hohe Genauigkeit der Taktfrequenz gefordert ist.

Für eine serielle Kommunikation oder zeitkritischen Anwendungen ist aus diesem Grund ein externer Quarzoszillator besser geeignet. Bei der Chipherstellung eines ATMega88 wird der interne RC-Oszillator bereits werkseitig bei einer Temperatur von typ. 25°C und einer Versorgungsspannung von 3V auf 8MHz kalibriert.

Page 14: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

14

Abb.1.22: Interne RC-Oszillatorfrequenz in Abhängigkeit von Temperatur und Versorgungsspannung

Schwingquarze

Schwingquarze bestehen aus einem speziellen Quarzkristall mit piezo-elektrischen Eigenschaften welche durch Zuführung einer Wechselspannung einen Schwingkreis mit hoher Güte darstellen. Schwingquarze werden extern an den beiden Anschlüssen XTAL1 und XTAL2 des Mikrocontrollers angeschlossen. Sie benötigen wie in der folgenden Abbildung gezeigt zusätzlich zwei Lastkondensatoren (22 bis 33pF) zum Anschwingen und sollten zusammen mit dem Quarz möglichst nahe an den Controllerpins positioniert werden.

Abb1.23: Externer Quarz mit Lastkondensatoren Abb.1.24: Quarze in verschiedenen Bauformen

Schwingquarze erreichen eine wesentlich höhere Genauigkeit als interne RC-Oszillatoren. Die Genauigkeit wird üblicherweise in ppm (parts per million) angegeben. Übliche Werte sind <100ppm. Bei einem Quarz mit 1MHz beträgt die maximale Toleranz somit ±100 Hertz. Schwingquarze haben auch eine geringere Temperaturabhängigkeit, benötigen aber eine längere Einschwingzeit von bis zu einigen Millisekunden bis sie stabil schwingen.

Quarze gibt es standardmäßig in unterschiedlichen Frequenzen von z.B. 4MHz, 8MHz, 16MHz oder 20MHz. Es gibt aber auch Quarze mit Frequenzen wie z.B. 7,3728MHz, 14,7456MHz oder 18,432MHz welche als Baudratenquarze bezeichnet werden und für

Page 15: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

15

serielle Datenübertragungen eingesetzt werden. Eine Sonderstellung nehmen die sogenannten Uhrenquarze ein. Sie haben eine Frequenz von 32,768kHz und gehören zu den EXTLOFXTAL (ext. Low frequency crystal) Oszillatoren.

Keramikresonatoren

Keramikresonatoren bestehen aus ferroelektrischem Material und können wie Quarze auf einer bestimmten Frequenz zum Schwingen angeregt werden. Keramikresonatoren benötigen auch eine wesentlich kürzere Einschwingzeit und sind billiger als Quarze. Sie sind robuster gegenüber Vibrationen können jedoch nicht die hohe Genauigkeit wie Quarze bieten.

Abb.1.25: Keramikresonatoren in verschiedener Ausführung

Externes Taktsignal

Eine eher selten angewandte Möglichkeit ist die Einspeisung eines externen Taktsignals. Prinzipiell kann hier jede beliebige Taktquelle gewählt werden. Das externe Taktsignal wird am PIN XTAL1 eingespeist.

Page 16: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

16

1.7 Pinbelegung des ATMega88

Wie Sie anhand der Pinbelegung erkennen, können Sie die meisten Pins mehrfach verwenden. Der Pin 23 (PC0) kann zum Beispiel als digitaler Eingang bzw. Ausgang oder als ADC0 (Analog Digitalwandler Kanal 0) oder als PCINT8 (Pin Change Interrupt 8) verwendet werden. Wie letztendlich ein Pin verwendet wird, wird durch die Einstellungen der entsprechenden Register bestimmt.

Abb.1.27: Pinbelegung des ATMega88 im DIP28-Gehäuse

1.8 Compiler und Linker

Wie eingangs bereits erwähnt, wird die Software für den Mikrocontroller mit Hilfe einer Entwicklungsumgebung (Integrated Development Environment) kurz IDE geschrieben. Ein Softwareprojekt besteht gewöhnlich aus mehreren Dateien, die für den Mikrocontroller „aufbereitet“ werden müssen. Die Programmiersprache C ist eine höhere Programmiersprache, die für den Menschen einigermaßen gut leserlich und verständlich ist. Ein Mikrocontroller versteht jedoch nur die Maschinensprache, also eine Abfolge von Nullen und Einsen.

Page 17: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

17

Die in C geschriebene Anweisung

if (a < 10) // wenn a kleiner 10 a++; // erhöhe a um 1

liest sich für den Mikrocontroller zum Beispiel so:

10110011 11011001 00110111 00001010 11011001 01100011

Das bedeutet, dass ein C Programm für den Mikrocontroller zuerst in seine Maschinensprache übersetzt werden muss. Diese Übersetzung übernimmt ein Programm welches als Compiler bezeichnet wird. Den Übersetzungsvorgang nennt man kompilieren.

Die folgende Abbildung veranschaulicht diesen Vorgang:

Source Code Datei Objekt Datei

Der Compiler übersetzt den C-Code der Source Code Datei in eine Maschinencode ähnlichen Sprache und erzeugt eine Objektdatei. Der für AVR-Projekte verwendete Compiler ist der avr-gcc Compiler und ist bereits in Atmel Studio 6 integriert. Ebenso integriert sind andere Hilfsprogramme wie z.B. Assembler, Präprozessor und Linker.

Durch die Verwendung von Atmel Studio 6 als Entwicklungsumgebung wird der gesamte Compilierungsprozess praktisch mit einem einzigen „Knopfdruck“ durchgeführt. Dennoch sollten Sie wissen, wie so ein Compilierungsvorgang im Einzelnen funktioniert.

Ein Softwareprojekt besteht aber nicht nur aus C-Dateien sondern auch aus Headerdateien und fertigen Bibliotheken, welche für die Programmausführung ebenfalls eingebunden werden müssen.

Page 18: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

18

1.9 Vorarbeiten für das erste Projekt

In diesem Abschnitt geht es darum, die Entwicklungsumgebung Atmel Studio 6 kennen zu lernen, einen Zugriff auf den Mikrocontroller zu bekommen, die Fusebits auszulesen und zu ändern, sowie ein kleines Programm zu schreiben welches z.B. eine LED blinken lassen soll. Dieses Projekt sollten Sie auf einem Experimentierboard oder einer Lochrasterplatine aufbauen. Sie benötigen Atmel Studio 6 als Entwicklungsumgebung und einen ISP-Programmer wie z.B. den AVR-Dragon.

1.11.1 Aufbau der Hardware

Für dieses Projekt werden folgende Bauteile benötigt:

1 Stk. Mikrocontroller ATMega88 1 Stk. Stiftleiste oder Wannenstecker (3polig / 2-reihig) für den ISP-Stecker 1 Stk. Widerstand im Bereich von 470Ω bis 1kΩ 1 Stk. Widerstand im Bereich von 10kΩ bis 22kΩ 1 Stk. Spannungsregler LM7805 3 Stk. Kondensatoren (2x 100nF, 1x 330nF) 1 Stk. Rote oder grüne LED

Für die Grundbeschaltung des Mikrocontrollers benötigen Sie zunächst die Spannungsversorgung und die Anschlüsse für den ISP-Programmieradapter.

Abb.1.29: ATMega88 Anschlussbelegung Vcc, GND, Reset, MISO, MOSI, SCK

Der Anschluss AVCC (Pin 20) stellt unter anderem die

Versorgung des ADC (Analog Digital Converter) und

der Portpins am Port C sicher. Grundsätzlich sollte

dieser Pin immer mit VCC verbunden werden.

.

Page 19: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

19

1.11.2 Stromversorgung des Mikrocontrollers

Ein Mikrocontroller ist sehr empfindlich vor Überspannung. Daher darf die maximal zulässige Versorgungsspannung des Controllers nicht überschritten werden. Die Versorgungsspannung liegt je nach Mikrocontroller zwischen 1,8 und 5V und ist dem jeweiligen Datenblatt zu entnehmen.

Sie können eine Mikrocontrollerschaltung auch beispielsweise direkt über eine 4,5V-Batterie, Li-ION-Batterie oder ein Netzgerät versorgen. Um die Versorgungsspannung auch bei Laständerungen konstant zu halten, wird aber gewöhnlich ein Linear- oder Schaltregler verwendet.

Am einfachsten ist es, einen Linearregler aufzubauen. Dieses Bauteil (z.B. LM7805) benötigt als Zusatzbeschaltung nur zwei Kondensatoren (0,33µF auf der Eingangsseite und 0,1µF auf der Ausgangsseite) und hält die Ausgangsspannung auf 5V konstant.

Die Eingangsspannung kann je nach Last 7V bis 36V betragen. Der maximale Ausgangsstrom beträgt 1,5A. Da die Mikrocontrollerschaltung selbst nur sehr wenig Strom verbraucht, ist auch die Verlustleistung des Linearreglers sehr gering.

Möchten Sie aber damit auch andere Verbraucher betreiben, achten Sie auf die Verlustleistung des Reglers und montieren Sie ihn auf einen entsprechenden Kühlkörper.

Die Verlustleistung des Linearreglers errechnet sich aus:

𝑃𝑣 = (𝑉𝑖𝑛 − 𝑉𝑜𝑢𝑡) ∗ 𝐼

Bei einer Eingangsspannung von z.B. 12V und einem Strom von 1A beträgt die Verlustleistung des 5V-Reglers bereits (12V-5V) * 1 = 700mW. Damit wird der Regler schon brennend heiß und verlangt unbedingt nach einem Kühlkörper.

Abb.1.31: Linearregler LM7805 im TO220-Gehäuse

Page 20: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

20

Abb.1.32: Linearregler LM7805 mit Zusatzbeschaltung der Kondensatoren

Viele externe Bausteine dürfen aber oft nur mit einer maximalen Spannung von 3,3V versorgt werden. Für eine solche Versorgung eignen sich ebenfalls Linearregler für 3V bzw. 3,3V. In der Praxis wird für diese Zwecke gerne der Linearregler LM317 eingesetzt. Dieser Linearregler hat den Vorteil, dass man die Ausgangsspannung durch eine entsprechende Kombination der beiden Regelwiderstände R1 und R2 selbst bestimmen kann. Der Widerstandswert für R1 sollte hier im Bereich zwischen 240Ω und 270Ω liegen.

Abb.1.33: Beschaltung des LM317 mit Eingangs- und Ausgangskondensator

Die Ausgangsspannung lässt sich mit der Formel 𝑉𝑜𝑢𝑡 = 1,25𝑉 (1 +𝑅2

𝑅1) berechnen.

Berechnung für eine Versorgungsspannung von 3,3V und R1 = 240Ω:

𝑅2 = 𝑅1 (𝑉𝑜𝑢𝑡

1,25− 1) 𝑅2 = 240 (

3,3

1,25− 1) R2 = 390Ω

Abb.1.34: Pinbelegung LM317 im

TO-220 Gehäuse

Page 21: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

21

1.11.3 Aufbau der Grundschaltung

Abb.1.38: Grundschaltung des ATMega88 mit ISP-Anschluss und 5V-Linearregler LM7805

Diese Grundschaltung ist die erste Schaltung die wir aufbauen. Sie wurde wie in der folgenden Abbildung auf einem Breadbord aufgebaut und mit einer 9V-Batterie versorgt. Der Linearregler LM7805 regelt die Versorgungsspannung auf konstante 5V.

Abb.1.39: Aufbau der Grundschaltung auf einem Breadboard

Page 22: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

22

Auf der linken Seite im Bild befindet sich der lineare Spannungsregler (LM7805) mit Ein- und Ausgangskondensatoren. Mittig ist eine 6-polige Stiftleiste für die ISP-Schnittstelle an dem das Programmiergerät angeschlossen wird.

Auf der rechten Seite befindet sich noch zusätzlich eine grüne LED mit einem Vorwiderstand welche an einem Portpin des Controllers angeschlossen ist.

Achten Sie darauf, dass der Pull-up Widerstand am Pin1 (/RESET) nicht zu klein gewählt wird. Dieser Pin wird vom Programmiergerät beim Programmiervorgang auf Masse gezogen. Ist der Widerstand zu klein, kann der Programmer diesen Pin nicht mehr sauber auf Masse ziehen und damit kann der Controller nicht programmiert werden. Übliche Werte für diesen Widerstand sind 10kΩ bis 22kΩ.

Der /RESET-Pin ist low-aktiv (ein Reset wird also bei einem Low-Signal ausgelöst) und wird daher mit einem / vor dem Pin-Namen gekennzeichnet. Ein low-aktiver Pin kann aber auch mit einem Querstrich über den Pin-Namen z.B. RESET gekennzeichnet sein.

Wenn die Hardware fertig verdrahtet und der Programmer angeschlossen ist können wir unser erstes Projekt starten.

1.12 Einführung in Atmel Studio 6 – Das erste Projekt

Nachdem Sie Atmel Studio 6.2 gestartet haben werden Sie mit einem Willkommensfenster begrüßt. Um ein neues Projekt zu erstellen, klicken Sie hier auf „New Project“.

Page 23: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

23

Es öffnet sich ein Fenster, in dem Sie bestimmte Projekteinstellungen vornehmen können. Für unser Beispiel wählen Sie unter „Installed Templates“ C/C++ sowie im mittleren Fenster GCC C Executable Project aus.

Geben Sie der Anwendung einen entsprechenden Namen (z.B. blinky_1) und speichern sie diese im gewünschten Ordner.

Bestätigen Sie nun mit OK! Es öffnet sich ein weiteres Fenster mit dem Namen „Device Selection“. Hier stellen Sie ein, welchen Controller Typ Sie für Ihr Projekt verwenden. Neben dem Typ erhalten Sie hier noch einige Basisinformationen wie z.B. die Speichergrößen von Boot, RAM und EEPROM.

Auf der rechten Seite erhalten Sie Informationen zum Betriebsspannungsbereich (Vcc) sowie die unterstützten Tools, mit denen Sie den Controller programmieren können. Ebenfalls finden Sie hier einen direkten Link zum Datenblatt des Controllers.

Für unser Projekt wählen wir in diesem Beispiel den verwendeten ATMega88PA als Controller aus.

Page 24: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

24

Nachdem Sie mit OK bestätigt haben wird das Projekt erstellt und startet mit dem Editor, welcher bereits einige Standard-Codezeilen enthält.

Klicken Sie nun auf den Reiter „Debug“ und anschließend auf „Disable debugWIRE and close“.

Page 25: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

25

Ist das geschehen, ändern Sie unter Tool das Interface auf ISP

und klicken anschließend auf das Icon „Device Programming“.

Jetzt haben Sie wieder Zugriff auf die Fusebits und können den Controller per ISP programmieren.

1.13 Debuggen in Atmel Studio 6

Sie haben bereits einige Funktionen der Entwicklungsumgebung kennen gelernt. Sie wissen, wie Sie ein Programm im ISP-und Debugwire-Mode in einen Mikrocontroller übertragen können und wie Sie zwischen diesen beiden Modi wechseln können.

Ein für den Programmierer wichtiges Werkzeug einer Entwicklungsumgebung ist das sogenannte Debugging. Ein Debugger ist ein Werkzeug zum Auffinden von Fehlern in einem Computer bzw. Mikrocontroller. Der Begriff „debugging“ (entwanzen) wurde 1947 von Grace Hopper eingeführt da am damaligen Mark II-Computer eine Motte eine Fehlfunktion an einem Relais verursacht hatte. Ein Bug (Käfer) ist somit in der Informatik ein Begriff für einen Programmfehler. Um Programmfehler finden zu können, bietet ein Debugger die Möglichkeit einzelne Programmanweisungen schrittweise auszuführen, Haltepunkte (Breakpoints) an beliebiger Stelle zu setzen oder den Inhalt von Variablen zu überwachen. Insbesondere wenn Programme größer und damit unübersichtlich werden, können Programmfehler mit einem Debugger sehr einfach und rasch gefunden werden.

Page 26: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

26

Beginnen wir damit, unser Programm „blinky_1“ mit dem Debugger schrittweise auszuführen. Starten Sie das Programm im Debugwire-Mode und kommentieren Sie zuvor die beiden Zeilen _delay_ms(500); mit zwei // aus. (Durch das Auskommentieren werden diese Programmzeilen vom Compiler nicht mehr übersetzt und sind für das Programm sozusagen unsichtbar.) Das Programm hält an der 1. Programmzeile in main().

Klicken Sie auf das icon „Step Over“ oder drücken Sie die Taste F10. Damit können Sie jede Programmzeile schrittweise ausführen lassen. Funktionen werden damit aber übersprungen. Was das bedeutet wird zu einem späteren Zeitpunkt behandelt. Nachdem die erste Programmzeile DDRD |= (1<<PD0); ausgeführt wurde bleibt der Programmzeiger in der folgenden Programmzeile stehen. Bisher wurde also nur die Anweisung DDRD |= (1<<PD0); ausgeführt.

Um zu überprüfen, ob diese Anweisung auch tatsächlich ordnungsgemäß ausgeführt wurde, lässt sich das im Fenster „IO View“ überprüfen. Das Fenster „IO View“ befindet sich auf der rechten Seite der Entwicklungsumgebung bzw. kann durch einen Klick auf das icon

„I/O View“ aktiviert werden.

Im „IO View“ markieren Sie anschließend PORTD und sehen unterhalb grafisch dargestellt, die derzeitigen Portpin Zustände.

Page 27: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

27

In der ersten Programmzeile wurde das Richtungsregister DDRD am Pin D0 auf 1 gesetzt. Nach Ausführung der nächsten Programmzeile PORTD = (1<<PD0); wurde PD0 auf 1 gesetzt.

Ändert ein Bit seinen Zustand, wird das Bit in roter Farbe dargestellt. Wie in diesem Beispiel ändert das Bit PD0 seinen Zustand von low auf high und die LED leuchtet. Im nächsten Schritt springt das Programm wieder zurück in die 1.Programmzeile der while-Schleife und die Anweisung PORTD &= ~(1<<PD0); wurde ausgeführt. Der Portpin PD0 wechselt seinen Zustand von high auf low und die LED erlischt.

PIND0 = low

PIND1 und PIND2 = high

DDRD0 = high

Registerwerte in Hex

PD0 wechselt von 0 auf 1

PD0 wechselt von 1 auf 0

Page 28: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

28

1.14 Das erste Programm

Gehen wir nun aber wieder einen kleinen Schritt zurück und starten das bereits bekannte Programm code001.c mit dem Debugger. Löschen Sie vorher noch die beiden Programmzeilen _delay_ms(500); und ergänzen Sie das Programm um zwei weitere Programmzeilen. /* code001.c ATMega88 @ 8MHz */ #include <avr/io.h> // Einbinden der Headerdatei avr/io.h #include <util/delay.h> // Einbinden der Headerdatei util/delay.h int main(void) // Startpunkt eines C-Programms DDRD |= (1<<PD0); // Richtungsregister PORTD PinD0 (Pin2)auf Ausgang setzen while(1) // Beginn der Endlosschleife da while(1) immer wahr ist PORTD = (1<<PD0); // Portpin PD0 setzen = HIGH PORTD &= ~(1<<PD0); // Portpin PD0 löschen = LOW PORTD = (1<<PD2)|(1<<PD7); // Portpin 2 und 7 am PORTD setzen PORTD &= ~(1<<PD2); // Portpin 2 am PORTD löschen

Öffnen Sie im I/O-Fenster auf der rechten Seite PORTD wie in der folgenden Abbildung:

Hier sehen Sie drei Register: Das Datenrichtungsregister DDRD (1=Ausgang, 0=Eingang) Das Eingangsregister PIND (1=ein High-Signal liegt an, 0=ein Low-Signal liegt an) Das Ausgangsregister PORTD (1=Ausgangspin auf High, 0=Ausgangspin auf Low)

Führen Sie nun die erste Programmzeile mit F10 aus. Jetzt wurde das Richtungsregister DDRD (Data Direction Register D) mit 0x01 beschrieben. Das unterste Bit (Bit 0) wurde gesetzt:

Page 29: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

29

Damit haben Sie dem Controller mitgeteilt, dass dieser Portpin (D0) ein Ausgangspin ist. In der nächsten Programmzeile wird das Bit 0 am Ausgangsport D gesetzt:

Mit PORTD &= ~(1<<PD0); wird das Bit 0 wieder gelöscht:

Mit PORTD = (1<<PD2)|(1<<PD7); werden Bit 2 und Bit 7 gesetzt:

Mit PORTD &= ~(1<<PD2); wird Bit 2 wieder gelöscht:

Mit dem IO View Fenster können Sie aber nicht nur die Inhalte der PORTS sondern auch die Inhalte und Einstellungen aller anderen Funktionen wie z.B. Timer, Interrupts, AD-Wandler usw. beobachten. Sie können auch direkt im IO View Bits setzen und löschen! Klicken Sie im IO View Fenster mit der Maus auf das Bit 0 am PORTD. Damit können Sie gezielt ihre angeschlossene LED ein- oder ausschalten. Der Inhalt der Bytes wird unter der Bezeichnung „Value“ auch als Hexadezimalwert dargestellt. Ein Beispiel:

Die Bits 7 und 2 sind gesetzt. Das Byte hat den binären Wert 10000100 oder hexadezimal 84. Das Voranstellen von 0x kennzeichnet einen hexadezimalen Wert. In der Informatik werden die Bitstellen beginnend mit Bit 0 immer von rechts nach links gezählt. Anstatt PORTD = (1<<PD2)|(1<<PD7);

könnte man genauso gut PORTD = 0x84; // 84Hex = 10000100 binär schreiben. Wenn man mit Hexadezimalzahlen umzugehen weiß, ist eine Umrechnung zwischen Binär- und Hexadezimalwerten sehr einfach. Aus diesem Grund wird diese Schreibweise von vielen Softwareentwicklern bevorzugt. Damit auch Sie den Umgang mit binären und hexadezimalen Zahlen beherrschen, sollten Sie das folgende Kapitel zu diesem Thema gut durcharbeiten und selbst einige Umrechnungen durchführen.

Page 30: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

30

1.15 Das hexadezimale Zahlensystem

Wie bereits im binären Zahlensystem kurz aufgezeigt, hat das hexadezimale Zahlensystem die Basis 16. Für die Zahlen 0 bis 9 werden die Ziffern 0 bis 9 verwendet. Für die restlichen sechs werden die ersten Buchstaben des Alphabets (A bis F) verwendet.

Beispiele:

Dezimalzahl Hexadezimalzahl Dezimalzahl Hexadezimalzahl 5 5 170 AA 9 9 255 FF 12 C 256 100 15 F 257 101 16 10 1024 400 17 11 2048 800 18 12 32768 8000 28 1C 65535 FFFF

Das hexadezimale Zahlensystem findet vor allem in der Programmierung von Mikrocontrollern seine Anwendung. Die Umrechnung funktioniert wie im binären Zahlensystem. Der Unterschied ist nur, dass die Basis nicht 2 sondern 16 ist.

Beispiel: Umrechnung von 18E7 nach Dezimal.

𝟏 ∗ 163 + 𝟖 ∗ 162 + 𝟏𝟒 ∗ 161 + 𝟕 ∗ 160

4096 + 2048 + 224 +7 = 6375

Die Umrechnung von einem Hexadezimalwert in einen Binärwert oder auch umgekehrt ist hingegen sehr einfach.

Hier ein Beispiel:

Das PORTD ist wie folgt gesetzt und hat den hexadezimalen Wert 0x84:

Gedanklich kann man dieses Byte in der Mitte teilen:

Page 31: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

31

1.16 Registerinhalte verändern

Hier sehen Sie einige Beispiele, wie Sie die Inhalte von Registern verändern können. Im ersten Beispiel werden alle Bits von Port D auf Ausgang gesetzt und die untersten 4 Port-Bits auf 1 gesetzt:

DDRD = 0xFF; // Richtungsregister PORTD auf 1111 1111 PORTD = 0x0F; // Die untersten 4 Bits von PORTD auf HIGH (0000 1111)

Hierbei ist zu beachten, das eine direkte Zuweisung mit einem = das gesamte Register überschreibt. Also alles was zuvor in diesem Register gestanden hat wird überschrieben.

Ein einzelnes Bit setzen

Um ein einzelnes Bit zu setzen, wird der ODER-Operator | verwendet. Im folgenden Beispiel soll der Portpin D7 auf 1 (HIGH) gesetzt werden. Dieses Bit ist das höchstwertige Bit und wird als MSB (Most Significant Bit) bezeichnet.

PORTD |= (1<<PD7); // Das oberste Bit von PORTD auf HIGH setzen

Durch die ODER-Verknüpfung wurde Bit 7 gesetzt ohne die anderen Registerwerte zu verändern.

Mehrere Bits gleichzeitig setzen

Um mehrere Bits gleichzeitig zu setzen, wird ebenfalls der ODER-Operator | verwendet. Im folgenden Beispiel sollen die Portpins D6, D5 und D4 auf 1 (HIGH) gesetzt werden ohne die bestehenden Registerinhalte zu ändern.

PORTD |= (1<<PD6)|(1<<PD5)|(1<<PD4);

Page 32: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

32

2.1 Mit Variablen arbeiten

Variablen speichern also Zahlen, Buchstaben oder Zeichenketten und stellen sie dem Programm zur Verfügung. Jede Variable ist von einem bestimmten Datentyp der angibt, welche Art von Information die Variable speichern soll.

Beispiel: Der Variablen mit dem Namen Sum wird der Inhalt von Variable a + Variable b zugewiesen.

In Sum wird hier der Wert 12 gespeichert. Die Variable Sum hat nun solange den Wert 12, solange ihr kein neuer Wert zugewiesen wird.

uint8_t a=2, b=5, sum; sum = a + b;

Im folgenden Beispiel ein Programm, welches den Wert von zwei Variablen vertauscht. Mit einer Hilfsvariablen (hilf) wird ein Wert zwischengespeichert. Benutzen Sie für dieses Programm den Simulator in Atmel Studio. Ändern Sie dazu einfach den Programmer im Reiter „Tool“ von z.B. AVR Dragon auf den Simulator.

/* code004.c Simulator */ #include <avr/io.h> uint8_t a=2, b=5, hilf; // Deklaration und Initialisierung globaler Variablen int main(void) hilf = a; // in hilf wird der Wert von a gespeichert a = b; // in a wird der Wert von b gespeichert b = hilf; // in b wird der Wert von hilf gespeichert

Page 33: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

33

2.2 Aufruf von Funktionen

Hier ein praktisches Beispiel, wie eine Funktion erstellt und aufgerufen wird. Wir schreiben zwei Funktionen welche eine Berechnung durchführen sollen. Die Funktion addiere() soll einen übergebenen Parameter zur Zahl 5 addieren und das Ergebnis zurückgeben. Die zweite Funktion multipliziere() soll dieses Ergebnis mit 2 multiplizieren und das Ergebnis direkt auf PORTD ausgeben.

#include <avr/io.h> uint8_t addiere(uint8_t zahl) // (2) zahl += 5; // (3) return zahl; // (4) void ausgabe(uint8_t summe) // (6) summe *= 2; // (7) PORTD = summe; // (8) int main(void) DDRD = 0xFF; // PORTD auf Ausgang PORTD = 0x00; // PORTD = Low uint8_t summe = addiere(2); // (1) ausgabe(summe); // (5)

(1) Die Funktion addiere() wird aus dem Hauptprogramm aufgerufen und als Parameter die Zahl 2 übergeben. Das Ergebnis der Funktion wird als Rückgabewert in summe gespeichert. Da summe zuvor noch nicht deklariert wurde, wird die Deklaration der Variablen gleich in einer Zeile mit dem Funktionsaufruf durchgeführt.

(2) Die Funktion addiere() erhält aus dem Funktionsaufruf den Parameter „zahl“ (zahl = 2) vom Typ int.

(3) Die Variable zahl (der Übergabeparameter) vom Typ int ist nur in dieser Funktion

sichtbar. Die Zeile „zahl += 5;“ ist die Kurzschreibweise für „zahl = zahl + 5;“. Die Variable zahl hat nun den Wert 7.

(4) Mit dem Schlüsselwort return wird zahl (also der Wert 7) an die aufrufende

Funktion zurückgegeben und in summe gespeichert. Der Datentyp des Rückgabeparameters steht vor der Funktion addiere() und ist in diesem Fall vom Typ int.

Page 34: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

34

(5) Die Funktion ausgabe() wird aufgerufen und als Parameter wird der Wert der in

summe gespeichert ist übergeben. Die Funktion ausgabe() liefert keinen Rückgabeparameter.

(6) Die Funktion ausgabe() gibt keinen Wert an die aufrufende Stelle zurück und ist

daher void. Der übernommene Parameter „summe“ wird innerhalb der Funktion mit dem Wert 2 multipliziert und anschließend am PORTD ausgegeben.

(7) Kurzschreibweise „summe *= 2;“ entspricht „summe = summe * 2;“

(8) Ausgabe von summe (Wert = 7) am PORTD

In der folgenden Abbildung sehen Sie diesen Ablauf grafisch dargestellt:

1. Der Übergabeparameter (Wert 2) wird an zahl vom Datentyp int übergeben 2. Mit return wird der aktuelle Wert von zahl an die aufrufende Funktion zurück

gegeben und in summe gespeichert 3. Der Wert von summe wird als Übergabeparameter an summe übergeben

12

3

In diesem Beispiel wurden die beiden Funktionen vom Compiler sofort erkannt, da sie vor der Hauptfunktion main() stehen und damit bereits vor dem Funktionsaufruf deklariert wurden!

Page 35: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

35

3 Der Watchdog

Der Watchdog (Wachhund) ist ein Timer, der in bestimmten Zeitabständen den Mikrocontroller „überwacht“. Insbesondere bei etwas größeren Programmen besteht immer die Gefahr, ja sogar die sehr hohe Wahrscheinlichkeit, dass unser Programm nicht 100% korrekt und fehlerfrei ist.

Sollte sich das Programm „aufhängen“, sorgt der Watchdog dafür dass der Mikrocontroller einen Reset auslöst und neu startet. Der Watchdog kann aber auch je nach Registereinstellung einen Interrupt auslösen bzw. zuerst einen Interrupt und dann einen Systemreset. Diese Variante wird verwendet, wenn vor einem Reset der Controller in einen sicheren Zustand versetzt werden soll.

Betrachten wir das folgende Programm. Die while-Schleife wird in diesem Fall niemals

beendet, da die Variable counter mit uint8_t deklariert wurde. Und eine Variable die als

unsigned deklariert wird kann niemals kleiner als Null werden! Das Programm wird hier

ewig in der Schleife hängen und PORTD wird niemals den Zustand 0xFF einnehmen. Wenn

Sie das Programm kompilieren findet auch Atmel Studio keinen Fehler da es sich hier um

keine Verletzung der Syntax handelt.

#include <avr/io.h> uint8_t counter; int main(void) DDRD = 0xFF; PORTD = 0x00; counter = 100; while (counter >= 0) // mach irgend etwas counter --; PORTD = 0xFF;

Aus dieser Situation kann uns nur mehr der Watchdog befreien.

Page 36: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

36

Wie funktioniert nun der Watchdog?

Der Watchdog besteht aus einem Timer der von 0 beginnend hochzählt. Je nach eingestelltem Vorteiler erreicht der Timer nach einer bestimmten Zeit seinen Überlauf und löst dabei den Reset des Mikrocontrollers aus.

Nachdem der Watchdog aktiviert wurde, muss dieser im Programm in bestimmten zeitlichen Abständen immer wieder zurückgesetzt werden. So, dass die Zeit bis zum Timerüberlauf niemals erreicht wird – zumindest dann nicht, wenn das Programm ordnungsgemäß läuft. Bleibt das Programm irgendwo hängen, wird die nächste Anweisung zum Rücksetzen des Watchdog nicht mehr im vorgeschriebenen Zeitfenster erreicht und der Watchdog löst den Reset aus.

Der Watchdog kann grundsätzlich einen Systemreset, einen Interrupt oder einen Interrupt und Systemreset auslösen. Die Watchdog Time-out Zeiten lassen sich beim ATMega88 je nach Vorteiler zwischen 16ms und 8s einstellen. Über die Fusebits (WDTON) kann der Watchdog permanent aktiviert werden. Weiters wird der Watchdog hardwareseitig von einem separaten 128kHz Oszillator getaktet.

time

time

time

Start

Programmteil

Reset Watchdog

Programmteil

Reset Watchdog

Programmteil

Reset Watchdog

Abb.7.1: Watchdog Ablaufdiagramm

Wie in diesem Flussdiagramm beispielhaft

dargestellt, benötigt jeder Programmteil eine

gewisse Zeit für seine Ausführung. In dieser Zeit

läuft parallel der Watchdogtimer und muss vor

dem Ablauf der time-out Zeit durch einen

Watchdog Reset zurückgesetzt werden. Bleibt das

Programm in einem Programmteil hängen,

kommt es nicht mehr rechtzeitig zu einem

Watchdog Reset. Der Watchdog Timer läuft in

diesem Fall über und es wird ein Systemreset

oder ein Watchdog Timer Interrupt ausgelöst.

Page 37: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

37

Die ersten Grundlagen zur Mikrocontrollerprogrammierung haben Sie nun gelernt. Sie haben sich grundlegende Kentnisse angeeignet um kleinere Projekte zu verstehen. Dieses Grundlagenwissen soll jetzt in praktischen Projekten angewandt und erweitert werden.

Um die folgenden Prokekte nachbauen und testen zu können, sollten Sie sich falls noch nicht vorhanden, einen kleinen Vorrat an Bauteilen besorgen. Dazu gehören Standardbauteile wie z.B. Widerstände aus der E6-Reihe, Transistoren (Standardtypen NPN und PNP wie BC547 oder BC557), MOS-FETS (Standardtypen N-Kanal und vielleicht ein oder zwei P-Kanal Typen), Dioden (Standardtypen wie 1N4007 oder 1N4148) LED-Sortiment (rote, grüne und gelbe 3mm LEDs), 7-Segment Anzeigen, Micro-Taster und ein paar Digitalbausteine wie Schieberegister oder Temperatursensoren. Sehen Sie sich zuerst kurz die Projekte in diesem Buch an. Dort finden Sie zu jedem Projekt die benötigten Bauteile.

4 Programmbeispiel Lauflicht

In diesem Projekt wollen wir ein Lauflicht mit 8 LEDs realisieren. An jedem Portpin von PORTD wird eine LED mit Vorwiderstand (470Ω – 1kΩ) angeschlossen:

Abb.8.1: Lauflicht mit dem ATMega88

Im ersten Versuch soll sich das Lauflicht von rechts nach links bewegen und am Anfang wieder beginnen. Eine Überlegung wäre z.B. der Einsatz des Schiebeoperators << um das erste gesetzte Bit am PORTD nach links zu schieben.

Wenn Sie das folgende Beispiel debuggen, werden Sie sehen, dass dies zwar einmal funktioniert, aber da bei der Schiebeoperation nach jedem Schiebevorgang das PORT mit 0 aufgefüllt wird, ist nach dem 7. Schiebevorgang das PORTB auf 0000 0000 gesetzt.

Page 38: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

38

#include <avr/io.h> int main(void) DDRD = 0xFF; PORTD = (1<<PD0); // Bit D0 setzen --> 0000 0001 while(1) PORTD = (PORTD << 1); // PORTD um 1 Stelle nach links verschieben

Um das Lauflicht wieder zu starten, müsste nach dem letzten Schiebevorgang das erste Bit neu gesetzt werden. Hierfür eignet sich z.B. eine for-Schleife.

5 Einlesen von Tastenzuständen

Eines der wichtigen Aufgaben eines Mikrocontrollers ist die Verarbeitung von Tastenzuständen. Beispielsweise die Verarbeitung einer Codeeingabe eines Tastenfeldes oder Steuerungstasten von einem Bedienboard usw.

Grundsätzlich unterscheidet man zwei Arten von Abfragen:

1. Abfrage auf Low- oder Highlevel 2. Abfrage auf eine Schaltflanke (Flanke von High auf Low bzw. von Low auf High)

Abb.9.1: Portpinabfrage in 10ms Schritten

Page 39: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

39

5.1 Einlesen eines „aktive-low Tasters“

Im folgenden Beispiel soll der Zustand eines Tasters im Pollingverfahren am Pin D2 abgefragt werden. Der Taster wird im Ruhezustand über einen 10kOhm Pull-Up Widerstand auf High gezogen. Man spricht hier von einem low-aktiven Taster, da er im gedrückten (aktiven) Zustand ein low-Signal liefert.

Programmieren Sie das folgende Beispiel und setzen je einen Breakpoint innerhalb der beiden if-Abfragen. Beobachten Sie im Fenster „IO View“, wie sich der Zustand von PIN D2 am Eingangsregister bei einem Tastendruck verändert.

Wird der Taster nicht betätigt, liegt am Portpin D2 ein High-Signal an da durch den geöffneten Taster kein Strom über den Widerstand gegen Masse fließen kann. Daher entsteht auch kein Spannungsabfall am Pull-Up Widerstand und die Versorgungs -spannung von +5V liegt direkt am Pin D2 an.

Wird der Taster geschlossen, wird der Pin D2 über den Taster direkt mit Masse verbunden. Die gesamte Versorgungsspannung von 5V fällt am Pull-Up Widerstand ab.

Page 40: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

40

5.2 Entprellen eines Tasters

Taster haben wie alle mechanischen Kontakte die unangenehme Eigenschaft dass sie prellen. Das bedeutet, dass bei einem Tastendruck der Kontakt nicht einmalig und sauber geschlossen wird sondern wie im folgenden Oszilloskop Bild ersichtlich, mehrmals ein- und ausgeschaltet wird. Dieser Taster prellt z.B. zwei Mal bevor der Kontakt nach rund 115µs geschlossen bleibt.

Abb.9.3: Tasterprellen – Messung mit dem Oszilloskop

Typische Prellzeiten von Tastern liegen im Bereich von wenigen Mikrosekunden bis einige Millisekunden.

Für viele Anwendungen ist das Tasterprellen auch kein Problem. Wenn Sie aber mit dem Mikrocontroller eine Schaltung entwickeln die z.B. Tastendrücke zählen oder einen Interrupt auslösen soll, müssen Sie den Taster vorher entprellen. Grundsätzlich unterscheidet man zwei Arten der Tasterentprellung. Die Tasterentprellung mittels Hardware und die softwareseitige Tasterentprellung.

Page 41: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

41

5.3 Schalten von Lasten mit Transistoren

In diesem Beispiel wird gezeigt, wie Sie mit einem bipolaren NPN-Transistor (BC547) eine Highpower LED ansteuern können. Wir wählen für den Betrieb der LED einen Strom von 50mA. Diesen Strom kann auch der Transistor BC547 bewältigen.

Für den Basisvorwiderstand wählen wir einen typischen Wert von 1kΩ. Dieser Wert hat sich in der Praxis bewährt und begrenzt den Basisstrom bzw. den Ausgangsstrom des Portpins. Der Spannungsabfall UCESAT des Transistors beträgt lt. Datenblatt rund 0,2V.

Die verwendete LED ist für maximal 350mA ausgelegt und erreicht bei 50mA eine Vorwärtsspannung von rund 3V. Bei einer Versorgungsspannung von 5V verbleibt demnach für den Emitterwiderstand (dieser begrenzt den Strom der LED) ein Spannungsabfall von 1,8V. Der Emitterwiderstand lässt sich nun berechnen:

𝑅 =𝑈𝑅2

𝐼=

1,8

0,05= 36Ω

Wir wählen hier aus der E6-Reihe einen 33Ω Widerstand. Da der Widerstand etwas kleiner gewählt wurde, wird dementsprechend der Strom etwas höher sein.

Abb.10.1: Schalten von Lasten mit einem NPN-Transistor

Achten Sie auch auf die Verlustleistung der Bauteile! Die Verlustleistung des Widerstandes R2 beträgt in diesem Beispiel:

𝑷𝑹𝟐 = 𝑈𝑅2 ∗ 𝐼 = 1,8𝑉 ∗ 0,05 = 𝟗𝟎𝒎𝑾

I=50mA

UF = 3V

UCESAT = 0,2V

UR2 = 1,8V

Page 42: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

42

Ein ¼-Watt Widerstand wird hier bereits warm!

Um größere Ströme zu schalten oder die Verlustleistung zu minimieren werden in der Praxis vorwiegend MOSFETs eingesetzt.

Ein MOSFET (engl. Metal Oxide Semiconductor Field-Effect Transistor) kann „nahezu verlustfrei“ angesteuert werden und produziert durch seinen sehr geringen Drain-Source Widerstand (RDS(ON)) eine geringe Verlustleistung. Durch diese Eigenschaften kann ein MOSFET große Ströme schalten.

Im nächsten Beispiel wird ein N-Kanal MOSFET (IRLR3105) verwendet um die LED zu betreiben. Der Widerstand am Gate von 1kΩ begrenzt den Gatestrom im Schaltmoment. Der MOSFET hat ein RDSON von 0,037Ω. Dem entsprechend fällt zwischen den Anschlüssen Drain und Source kaum eine Spannung ab.

6 Die State Machine

Eine State Machine (auch als endlicher Zustandsautomat bezeichnet) ist ein Verfahren zur Steuerung von „Maschinen“ welche ihre Aktionen abhängig von den jeweils vorherrschenden Zuständen oder Zustandsübergängen ausführen. Sie besteht also aus einer Schaltlogik und einem Zustandsspeicher.

Man unterscheidet bei einer State Machine vier Aktionstypen:

Eingangsaktion Eine Aktion wird beim Eintreten in einen Zustand ausgeführt

Ausgangsaktion Eine Aktion wird beim Verlassen eines Zustandes ausgeführt

Eingabeaktion Eine Aktion wird in Abhängigkeit vom aktuellen Zustand und einer Eingabe ausgeführt

Übergangsaktion Eine Aktion wird abhängig vom jeweiligen Zustandsübergang ausgeführt

Page 43: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

43

6.1 Programmbeispiel Ampelregelung mit einer State Machine

Zustände der Ampel

Betrachtet man die Kreuzung, dann haben die Ampeln 1 und 3 sowie 2 und 4 denselben Zustand zur selben Zeit. Das heißt, für eine Zustandstabelle benötigen wir auch nur den Zustand zweier Ampeln. Zuerst stellen wir uns eine Tabelle zusammen, welche alle möglichen Zustände der beiden nicht gegenüber liegenden Ampeln darstellt.

Zustand Ampel 1, 3 Ampel 2, 4 Nächster Zustand

1 Rot Grün 2

2 Rot Gelb 3

3 Rot Rot 4

4 Rot/Gelb Rot 5

5 Grün Rot 6

6 Gelb Rot 7

7 Rot Rot 8

8 Rot Rot/Gelb 1 Abb.11.1: Ampelregelung Zustandstabelle

Die verschiedenen Zustände einer State Machine werden in der Praxis üblicherweise wie in der folgenden Abbildung in einem Zustandsdiagramm dargestellt. Beginnend mit dem 1. Zustand (Ampel 1 und 3 = Rot, Ampel 2 und 4 = Grün) wird der nächste Zustand nach Ablauf einer definierten Zeit erreicht.

Page 44: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

44

A1,A3Red

A2,A4Green

wait

A1,A3Red

A2,A4Yellow

wait

A1,A3Red

A2,A4Red

wait

A1,A3Red,

Yellow

A2,A4Red

wait

A1,A3Red

A2,A4Red,

Yellow

wait

A1,A3Red

A2,A4Red

wait

A1,A3Yellow

A2,A4Red

wait

A1,A3Green

A2,A4Red

wait

1

2 3

4

5

67

8

Abb.11.2: Zustandsdiagramm einer Ampelregelung

Für unseren Versuchsaufbau benötigen wir je zwei rote, gelbe und grüne LEDs, welche wir an den freien Portpins des Controllers anschließen. Für Ampel 1 verwenden wir die Portpins PB0, PB1 und PB2 sowie PD0, PD1 und PD2 für Ampel 2.

7 Interrupts

Interrupts sind in der Mikrocontrollertechnik ein wichtiges Werkzeug um in Echtzeit auf externe und interne Ereignisse augenblicklich reagieren zu können. Wird zum Beispiel in einem Prozess ein Zustand erreicht auf welchen man sofort reagieren muss (Daten werden beispielsweise über die UART-Schnittstelle empfangen), wird dieses Ereignis durch eine Interrupt Routine entsprechend behandelt.

7.1 Funktionsweise einer Interruptsteuerung

Wird ein Interrupt ausgelöst, unterbricht dieses Ereignis den Mikrocontroller bei seiner aktuellen Ausführung der Befehle im Hauptprogramm. Das auslösende Ereignis wird Unterbrechungsanforderung (Interrupt Request, IRQ) genannt. Der Mikrocontroller führt den aktuellen Befehl noch fertig aus und unterbricht an dieser Stelle das Programm. Jetzt

Page 45: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

45

wird die Interrupt Service Routine (ISR) ausgeführt. Ist die ISR beendet, springt das Programm an die Unterbrechungsstelle zum Hauptprogramm zurück und führt den Programmablauf weiter fort.

Das folgende Flussdiagramm soll den Programmablauf veranschaulichen. Bei einem Interrupt wird das Hauptprogramm verlassen (der aktuelle Befehl wird noch beendet) und ein Sprung zur Interrupt Service Routine ISR wird ausgeführt. Jetzt wird der Programmteil in der ISR ausgeführt. Anschließend wird wieder zum Hauptprogramm zurück gesprungen und das Programm an der nächsten Programmzeile fortgeführt.

Abb.12.1: Flussdiagramm einer ISR

Im Gegensatz zum Polling-Verfahren wird bei einem Interrupt kein bestimmter Status permanent abgefragt. Tritt ein Interrupt-Ereignis auf (ein Endschalter wird betätigt oder ein Zeichen wird über die UART-Schnittstelle empfangen) wird die ISR sofort (einige µs später) ausgeführt. Das entlastet den Mikrocontroller enorm, da er nicht ständig damit beschäftigt ist irgendeinen Status abzufragen.

7.2 Ausführung eines Interrupts mit einem Programmbeispiel

Um Interrupts im Programm ausführen zu können, muss die Headerdatei interrupt.h eingebunden werden.

Page 46: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

46

Damit stehen dann u.a. die beiden Makros

sei(); // Interrupts aktivieren (Global Interrupt Enable Bit im Status Register setzen) cli(); // Interrupts sperren (Global Interrupt Enable Bit im Status Register löschen)

zur Verfügung. Entsprechend könnte man natürlich auch direkt im Statusregister SREG das Bit 7 (Global Interrupt Enable Bit) setzen oder löschen.

SREG 7 6 5 4 3 2 1 0

I T H S V N Z C

Um einen Interrupt im Programm verwenden zu können muss er zuerst im Hauptprogramm entsprechend initialisiert werden.

Im folgenden Beispiel wird ein externer Interrupt (INT0) über einen Taster am Portpin PD2 bei einer steigenden Flanke ausgelöst. Die Initialisierung der Register EICRA und EIMSK ist im Programmcode entsprechend dokumentiert.

Abb.12.4: INT0 mit einem Taster auslösen

// ATMega88 @ 8MHz #include <avr/io.h> #include <avr/interrupt.h> // Einbinden der Headerdatei für Interrupts int main(void) DDRD &= ~(1<<PD2); // PD2 = Eingang (INT0) DDRB |= (1<<PB1); // PB1 = Ausgang PORTB = 0x00; // PORTB auf low EICRA |= (1<<ISC01)|(1<<ISC00); // Int0 wird durch eine steigende Flanke ausgelöst EIMSK |= (1<<INT0); // Ext. Int0 aktivieren

Page 47: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

47

sei(); // Alle Interrupts aktivieren while(1) return 0; ISR (INT0_vect) // Hier beginnt die ISR für den ext. Int0 PORTB ^= (1 << PB1); // Toggle PB1

Wie Sie sehen, ist eine ISR nichts anderes als eine Funktion deren übergebener Parameter der jeweilige Interrupt-Vector ist. Der externe Impuls der einen Interrupt auslöst muss länger als eine Taktperiode sein. Der Grund dafür ist, dass der Interrupt-Pin eingelesen (gesampelt) werden muss.

Dadurch kommt es zu einer kleinen Verzögerung zwischen dem Auslösen eines Ereignisses und der Ausführung einer ISR. Diese Verzögerungszeit wird auch als Latenzzeit bezeichnet.

Am folgenden Oszilloskop Bild ist die Verzögerung zwischen dem Tastendruck (CH1 bei steigender Flanke) und dem Flankenwechsel am Portpin PB1 auf High (CH2) zu erkennen. Die verstrichene Zeit beträgt hier 2,5µs.

Abb.12.5: Mit dem Oszilloskop gemessesne Latenzzeit eines Interrupt

Bei externen Interrupts muss darauf geachtet werden, das das Signal welches den Interrupt auslöst nicht mehrfach zwischen einem High- und Low-Pegel hin und her

CH1

CH2

Page 48: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

48

wechselt. Wird ein Interrupt z.B. über einen Taster ausgelöst, muss ein unerwünschter mehrfacher Flankenwechsel durch Tasterprellen verhindert werden.

Dadurch können Interrupts die flankengetriggert sind mehrfach ausgelöst werden. Das folgende Oszilloskop Bild zeigt einen prellenden Taster und einen Interrupt der insgesamt drei Mal (1x pro steigender Flanke) ausgelöst wurde. An CH2 ist die LED wie im vorherigen Programmbeispiel angeschlossen, welche bei jedem Interrupt toggelt.

7.3 Messen einer Spannung mit dem ADC

Für dieses Projekt ist es anfangs notwendig einige Register für den ADC-Betrieb einzustellen. Diese Registereinstellungen werden in diesem Abschnitt schrittweise erklärt. Wirft man einen Blick auf das Datenblatt des ATMEGA88 stellt man fest, dass der Controller mehrere ADC-Pins zur Verfügung stellt. Es handelt sich hier um sechs oder acht (abhängig von der Gehäusebauform) ADC-Kanäle, welche im Multiplexbetrieb verwendet werden. D.h. ein A/D-Wandler für sechs bzw. acht verschiedene Eingänge.

Durch den Multiplexbetrieb können die ADC-Kanäle nur nacheinander angesteuert werden. Eine gleichzeitige A/D-Wandlung mehrerer Kanäle ist somit nicht möglich.

Für den ersten Versuch verwenden wir ein Potentiometer welches zwischen VCC und GND geschalten wird. Die Mittelanzapfung wird mit einem ADC-Pin, in diesem Fall mit dem ADC-Kanal 5 verbunden. Das Potentiometer dient als veränderbarer Spannungsteiler und sollte einen Wert von 10kΩ bis 100kΩ haben (Da der Eingangswiderstand des ADC sehr hoch ist, ist der Wert des Potentiometers unkritisch). Damit können wir die Spannung am ADC-Kanal zwischen 0 bis 5V stufenlos verändern.

Der gemessene Wert soll direkt am PORTD in binärer Form auf 8 LEDs ausgegeben werden.

Abb.13.4: Poti-Anschluss am ADC-Kanal 5

Page 49: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

49

Da wir den ADC verwenden, muss auch der Pin AVCC mit +5V versorgt werden! Weiters empfiehlt es sich einen Kondensator mit ca. 100nF an den Pin VREF und GND aus Gründen der Störungs- und Rauschunterdrückung anzuschließen. Für die Auswahl der Referenzspannung gibt es prinzipiell drei Möglichkeiten:

- interne Referenzspannung (ATMEGA88 = 1,1V) - AVCC - Externe Referenzspannung am Pin AREF

Da der gesamte Bereich zwischen 0 und 5V gemessen werden soll, benötigen wir AVCC als Referenzspannung. Die Referenzspannung sollte nach Möglichkeit exakt 5V betragen und keinen Spannungsschwankungen unterliegen. Je ungenauer die Referenzspannung ist, desto ungenauer wird auch das Ergebnis einer A/D-Wandlung. Die Referenzspannung wird im Register ADMUX eingestellt. Dafür verantwortlich sind die Bits 6 und 7.

ADMUX 7 6 5 4 3 2 1 0

REFS1 REFS0 ADLAR - MUX3 MUX2 MUX1 MUX0

Lt. Tabelle im Datenblatt muss für AVCC das Bit REFS0 gesetzt werden.

Dies geschieht mit ADMUX |= (1<<REFS0); // Uref = 5V

Im Register ADCSRA muss der ADC durch Setzen des Bits ADEN aktiviert und der Vorteiler auf den gewünschten Wert gesetzt werden.

ADCSRA 7 6 5 4 3 2 1 0

ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0

ADCSRA |= (1<<ADEN); // ADC aktivieren

Der Vorteiler bestimmt die Frequenz der Abtastrate einer A/D-Wandlung. Er teilt die CPU-Frequenz auf den entsprechenden Wert. Die Abtastrate hat einen Einfluss auf die Genauigkeit und die Rauscheigenschaft des A/D-Wandlers und sollte im Bereich 50kHz bis 200kHz liegen. Eine Wandlung dauert dann 13 ADC-Takte. Dies gilt allerdings nicht für die erste Wandlung des ADC. Da hier die Initialisierung durchgeführt wird, dauert diese

Page 50: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

50

Standardmäßig ist ADLAR=0 eingestellt. Hier werden die 10 Bits rechtsbündig ausgegeben. Die 8 niederwertigeren Bits werden im ADCL und die beiden höchstwertigen Bits im ADCH gespeichert.

Abb.13.5: Ausgabe rechtsbündig ADLAR=0

Abb.13.6: Ausgabe linksbündig ADLAR=1

Wie im folgenden Programmcode zu erkennen ist, wird nach der Initialisierung des ADC zuerst ein sogenannter „dummy readout“ durchgeführt. Dies wird empfohlen, da die erste Wandlung nach der Initialisierung undefiniert ist. Das Ergebnis der Wandlung wird in die Variable x gespeichert und verworfen.

In der while-Schleife wiederholt sich nun permanent die A/D-Wandlung. Das Ergebnis wird am PORT D auf 8 LEDs als Binärwert ausgegeben.

#include <avr/io.h> int main(void) unsigned int x, ergebnis; DDRD = 0xFF; // Richtungsregister Port D auf Ausgang //*** Init ADC *** ADCSRA |= (1<<ADEN); // ADC aktivieren ADCSRA |= (1<<ADPS0)|(1<<ADPS1); // Vorteiler auf 8 ADMUX |= (1<<REFS0); // Uref = 5V ADMUX |= (1<<MUX2)|(1<<MUX0); // ADC-Kanal 5 einstellen ADMUX |= (1<<ADLAR); // Ausgabe linksbündig DIDR0 |= (1<<ADC5D); // Dig. Input Kanal ADC5 deaktivieren (spart Strom) //*** Dummy Readout *** ADCSRA |= (1<<ADSC); // Start ADC-Wandlung while (ADCSRA &(1<<ADSC)); // Auf Abschluss der Konvertierung warten x = ADC; // Das Ergebnis der 1.Wandlung in x speichern while(1) ADCSRA |= (1<<ADSC); // Start ADC-Wandlung while (ADCSRA &(1<<ADSC)); // Auf Abschluss der Konvertierung warten ergebnis = ADCH; // Inhalt von ADCH in ergebnis speichern PORTD = ergebnis; // Wandlungsergebnis am Port D ausgeben

Page 51: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

51

8 Der 8-Bit Timer/Counter

Ein Timer/Counter ist ein Zähler, der unabhängig vom restlichen Programmablauf arbeitet und mit jedem Takt ein Zählregister TCNTx um eins hochzählt.

Wenn dieses Register überläuft (Timer Overflow) oder ein bestimmter eingestellter Wert (Capture Compare Value) erreicht wird, führt der Timer einen Interrupt aus und setzt ein Flag.

Wird als Takt eine externe Quelle benutzt, spricht man von einem Counter, der die steigenden oder fallenden Flanken am entsprechenden Portpin zählt. Anwendungsbeispiele sind:

Erzeugen exakter Zeitverzögerungen

Generieren von periodischen Interrupts (z.B. Uhr)

Zählen externer Signale (Counter)

Frequenzgenerator

Pulsweitenmodulation PWM für die Ansteuerung von Motoren oder LEDs

Über wie viele Timer der Mikrocontroller verfügt ist im jeweiligen Datenblatt beschrieben. Beispiele:

ATtiny 44 1x 8-bit Timer/Counter , 1x 16-bit Timer/Counter AT90PWM316 1x 8-bit Timer/Counter, 1x 16-bit Timer/Counter ATMega32 2x 8-bit Timer/Counter, 1x 16-bit Timer/Counter ATMega128 2x 8-bit Timer/Counter, 2x 16-bit Timer/Counter ATMega1281 2x 8-bit Timer/Counter, 4x 16-bit Timer/Counter

Ein Timer ist also ein Register im Mikrocontroller, welches in Abhängigkeit der Zeitbasis (Frequenz des Oszillators oder externer Takt) um eins hochgezählt wird. Dieses Zählwerk wird hardwareseitig unabhängig vom restlichen Programmfluss gesteuert und belastet so den Controller nicht bei seiner Arbeit.

In Abhängigkeit davon wird je nach eingestelltem Timermodus ein Zählregister hinauf oder auch hinunter gezählt.

Page 52: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

52

Hier ein Beispiel zur Funktionsweise eines 4-bit Timers:

Abb.16.1: Funktionsweise eines 4-Bit Timers/Counters

Wird der Timer gestartet, beginnt er bei 0000 zu zählen und erhöht den Zähler bei jedem Takt um 1. Wenn der Zähler den Endwert 1111 (0xFFhex oder 15dez) erreicht, beginnt er anschließend wieder mit dem Anfangswert 0000. Bei einem 4bit Timer kommt es nach 16 Takten (Timer-Periode) zu einem Timerüberlauf (Timer Overflow). Dieser Timer Overflow kann nun einen Timer Interrupt auslösen.

8.1 Der Prescaler

Der Prescaler (Vorteiler) hat die Aufgabe, den Takt mit dem der Mikrocontroller arbeitet auf einen für den Timer sinnvollen Wert herunter zu teilen. Die folgende Grafik zeigt einen 8:1 Prescaler der z.B. einen 8MHz-Takt auf einen 1MHz-Timertakt herunter teilt.

Abb.16.2: Der Prescalter teilt den Takt des Quarzoszillators

Wenn z.B. der Quarzoszillator des Mikrocontrollers mit 8MHz schwingt, würde der Zähler

des Timers alle 125ns (1

8000000) um 1 erhöht werden. Bei einem 8bit Timer welcher von 0

bis 255 zählen kann würde dies bedeuten, dass der Timer alle 32µs überläuft. Das sind 31250 Timer Overflows pro Sekunde.

Page 53: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

53

Um diese hohe Anzahl von Timer Overflows zu verringern gibt es den Prescaler. Je nach Controller kann der Prescaler auf fixe Werte (1, 8, 64, 256, 1024) eingestellt werden und verringert so die Taktgeschwindigkeit des Timers.

Wird ein Prescaler von 1024 bei einem Systemtakt von 8Mhz angewandt, wird der Zähler des Timers nur mehr alle 128µs um einen Zählschritt erhöht. Dadurch verringern sich auch die Timer Overflows entsprechend auf rund 30 pro Sekunde.

Hier eine Übersichtstabelle für einen Systemtakt von 8MHz:

Prescaler Timertakt in Sek. Timer Overflows/Sek. 1 0,000000125 31250 8 0,000001 3906,25 64 0,000008 488,28 256 0,000032 122,07 1024 0,000128 30,52

Der Prescaler wird im Register TCCR (Timer / Counter Control Register) durch das Setzen der entsprechenden Bits (CSn0, CSn1 und CSn2) eingestellt.

8.2 Der 8bit Timer (Timer 0)

Wie der Name schon verrät, ist das Zählregister bei diesem Timer 8bit breit. Der Zähler kann also maximal 256 (0…255) Timertakte zählen bevor der Timer überläuft. Der Timer0 beim ATMega88 ist z.B. ein 8bit Timer.

Um die theoretischen Kenntnisse gleich praktisch anzuwenden, programmieren wir den 8bit Timer um einen Timerinterrupt zu erzeugen mit dem wir eine LED im Sekundentakt blinken lassen. Der Mikrocontroller wird mit dem internen Oszillator bei einem Systemtakt von 8MHz betrieben.

Folgende Schritte sind grundsätzlich notwendig, um den Timer zu initialisieren und auf den Sekundentakt einzustellen.

1.) Timermodus auswählen 2.) Prescaler auf optimalen Wert einstellen 3.) Bit für Timer Interrupt setzen 4.) Timer mit dem entsprechenden Wert vorladen

Page 54: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

54

8.2.1 Der 8bit Timer im Normal Mode

Grundsätzlich ist zuerst der Betriebsmodus des Timers zu wählen. Hier unterscheidet man vier verschiedene Modi:

a.) Normal Mode b.) Clear Timer on Compare Match (CTC) Mode c.) Fast PWM Mode d.) Phase Correct PWM Mode

Für das Erzeugen unseres Sekundentaktes wählen wir den Normal Mode. Das ist der einfachste Modus in dem der Zähler des Zählregisters nur aufwärts zählt, bis der Timeroverflow bei 255 erreicht ist. Danach startet der Zähler wieder bei 0.

Zuerst wählen wir den Prescaler. Der Systemtakt beträgt 8MHz, das sind 8000000 Takte pro Sekunde.

Bei einem Prescaler von 1024 erhalten wir demnach 8000000

1024 = 7812,5 Timertakte pro

Sekunde. D.h. unser Timer würde 7812,5

256 = 30,52-mal pro Sekunde überlaufen.

Wenn nun bei jedem Überlauf ein Timerinterrupt ausgelöst wird, würde unsere LED mit einer Frequenz von 30,52 Hz blinken. Da wir keinen so hohen Prescaler zur Verfügung haben, müssen wir einen kleinen Trick anwenden, um unsere LED im Sekundentakt blinken zu lassen.

Zuerst wählen wir den Prescaler so, dass wir ein ganzzahliges Ergebnis für den Timertakt erhalten. Wie wäre es mit einem Prescaler von 64?

Bei einem Prescaler von 64 erhalten wir einen Timertakt von 125000 Takte pro Sekunde oder anders gesagt, 125 Takte pro Millisekunde. Unser Ziel ist es nun, den Timer für eine Millisekunde zu berechnen und jeden 1000 Timerinterrupt zu nutzen und so unseren gewünschten Sekundentakt zu realisieren.

Da der Timer bei 255 überläuft (nach 256 Schritten) subtrahieren wir einfach die Takte die wir für 1ms benötigen und erhalten daraus den Vorladewert des Timers.

Vorladewert = 256 – 125 = 131

Damit wird das Zählregister mit 131 vorgeladen und der Timer erreicht nach 125 Takten also genau nach 1ms seinen Überlauf.

Page 55: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

55

Abb.16.3: Funktionsweise eines Zählregisters

Jetzt muss nur noch jeder 1000 Interrupt abgefangen werden um einen Sekundentakt zu generieren.

8.2.2 Registereinstellungen im Normal Mode

Wie im Datenblatt ersichtlich, müssen die Register wie folgt eingestellt werden:

TCCR0A (Timer0/Counter0 Control Register A)

TCCR0A 7 6 5 4 3 2 1 0

COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00

Im TCCR0A Register wird der Timer Modus eingestellt. Da wir den Normal Mode verwenden, werden die Bits 4 bis 7 nicht gesetzt.

Dasselbe gilt für die Registerbits COM0B1 und COM0B0.

Auch die Registerbits WGM02, WGM01 und WGM00 werden im Mode 0 nicht gesetzt. Somit ist das Register gleich 0000 0000:

TCCR0A = 0x00

Page 56: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

56

TCCR0B (Timer0/Counter0 Control Register B)

In diesem Register wird unter anderem der Prescaler eingestellt. Wir benötigen einen Prescaler von 64 und setzen daher wie im Datenblatt beschrieben die beiden Bits CS01 und CS00.

TCCR0B 7 6 5 4 3 2 1 0

FOC0A FOC0B - - WGM02 CS02 CS01 CS00

Somit ist das Register gleich 0000 0011 TCCR0B = 0x03

Page 57: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

57

Im nächsten Schritt wird die Einstellung für den Timerinterrupt vorgenommen. Dies geschieht im Register TIMSK0.

TIMSK0 (Timer/Counter Interrupt Mask Register)

TIMSK0 7 6 5 4 3 2 1 0

- - - - - OCIE0B OCIE0A TOIE0

Hier teilen wir den Timer mit, dass bei einem Überlauf ein Interrupt ausgelöst werden soll. Das Bit0 TOIE0 (Timer0 Overflow Interrupt Enable) muss dazu gesetzt werden.

TIMSK0 = 0000 0001 = 0x01

Jetzt müssen wir nur noch den Timer mit dem berechneten Wert 131 vorladen, damit der Timer nicht bei 0 zu zählen beginnt. Hierbei beschreiben wir direkt das Zählregister TCNT0.

TCNT0 = 131dez oder 0x83hex

Damit haben wir alle Registerwerte gesetzt und können das folgende Beispiel programmieren!

8.2.3 Eine LED im Sekundentakt blinken lassen

Im folgenden Versuch soll eine rote LED am Portpin PB1 angeschlossen werden und im Sekundentakt blinken. Die zuvor bestimmten Registereinstellungen werden direkt übernommen. Da der Timerinterrupt nach jeder Millisekunde ausgelöst wird, wird mit einer if-else Anweisung jeder 1000. Interrupt abgefangen und damit ein Sekundentakt generiert.

Abb.16.4: Eine LED mit Vorwiderstand am Pin B1

Page 58: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

58

8.2.4 Ansteuerung eines Servos

Ein Servo ist eine Antriebseinheit die man üblicherweise aus dem Modellbau kennt. Ein Servo besteht aus einem Elektromotor inklusive Antriebsmechanik mit Steuerelektronik und wird vorwiegend im Modellbau (Flugzeuge, Helikopter, Boote, Autos usw.) und im Bereich der Robotik eingesetzt. Im folgenden Projekt soll ein Servo mit einem kleinen Programm getestet werden.

Abb.16.6: Modellbauservo von HITEC

Ein Modellbauservo wird über ein dreipoliges Kabel (VCC , GND und Signalleitung) welches an einem Empfänger angeschlossen ist über eine Pulsweitenmodulation (PWM) angesteuert. Der Drehwinkel des Servos wird über die Pulsbreite des PWM-Signals verändert. In der Regel handelt es sich um ein 50-Hz-Signal mit einer Periodenlänge von 20ms und einem HIGH-Pegel zwischen 1ms und 2ms.

1ms bedeutet linker und 2ms rechter Anschlag des Servoarms. Diese Werte sind Richtwerte und können je nach Servo auch über- und unterschritten werden.

Da Servos im Inneren einen mechanischen Anschlag haben, können sie keine 360°-Drehung ausführen. Der Stellbereich bewegt sich in der Regel zwischen 0° und 180°.

Nachfolgend drei Abbildungen, welche die Servopositionen mit den entsprechenden PWM-Signalen darstellen:

Abb.16.7: Pulsbreite 1ms, Servoposition 0°

Page 59: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

59

Abb.16.8: Pulsbreite 1,5ms, Servoposition 90° (Neutralstellung)

Abb.16.9: Pulsbreite 2ms, Servoposition18 0°

8.2.5 Die Stromversorgung eines Servos

Servos erzeugen häufig Störungen auf Seite der Versorgungsspannung. Diese Störungen können einen Mikrocontroller sogar zum Absturz bringen. Daher ist es empfehlenswert, sie von einer eigenen Stromquelle wie zum Beispiel einem Akku zu betreiben. Da eine getrennte Versorgungsspannung aber nicht immer möglich ist, sollten diese Störungen mithilfe von Kondensatoren gefiltert werden. In der Praxis hat sich hier eine Mischung aus kleinen Kondensatoren (100nF) und großen Kondensatoren (10-100µF) zwischen VCC und GND bewährt. Wird ein Servo mit einer eigenen Stromquelle (Akku) betrieben, kann die Versorgungsspannung zwischen 4V und 6V betragen. Je nach Servohersteller sind die Servosteckverbindungen unterschiedlich. Hier zum Beispiel ein Servostecker von Graupner:

Abb.16.10: Steckerbelegung Graupner

Die Signalleitung für das PWM-Signal wird beispielsweise mit einem Mikrocontrollerpin verbunden.

Page 60: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

60

8.2.6 Servoposition per Taster steuern

Um ein genaues PWM-Signal zu erhalten und den Mikrocontroller zu entlasten, wird in diesem Projekt ein Timer verwendet. Mittels zweier Taster an PC0 und PC1 wird die Pulsbreite des PWM-Signals zwischen 1ms und 2ms verändert und damit ein entsprechender Drehwinkel des Servos eingestellt.

Für eine genauere Auflösung des PWM-Signals wird der 16bit-Timer des ATMega88 verwendet. Die Taktfrequenz des Controllers beträgt 1Mhz. Um eine PWM-Frequenz von 50Hz (20ms) zu generieren müssen Prescaler und Top-Wert des Output Compare Registers OCR1A entsprechend eingestellt werden.

Die Periodendauer und damit die PWM-Frequenz werden ausschließlich durch den TOP-Wert des Zählers bestimmt. Der Top-Wert wird in diesem Beispiel über das Input Capture Register ICR1 gesetzt. Wird ein Compare Match erreicht, wird OC1A bis zum nächsten TOP-Wert gelöscht. Damit lässt sich durch die Änderung des OCR1A-Wertes die Pulsweite verändern.

Abb.16.13: Erzeugung einer PMW mit dem Timer

Die PWM-Frequenz lässt sich wie folgt berechnen:

𝑓𝑂𝐶𝑛𝑥𝑃𝑊𝑀 = 𝑓𝐶𝐿𝐾

𝑃𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟 ∗ (1+𝑇𝑂𝑃)=

1000000

1∗(1+19999) = 50 Hz

Um einen passenden Prescaler bzw. Top-Wert zu ermitteln, gibt es im Internet zahlreiche Programme, die einem die Berechnung eines Vorlade- oder Comparewertes erleichtern. Ein solches Programm wäre zum Beispiel der AVR Timer Calculator von avr-praxis.de.

Die Periodendauer bei 50Hz beträgt 20ms und entspricht 1+19999 Taktimpulsen. Für die Mittelstellung unseres Servos benötigen wir eine Pulsweite von 1,5ms (1500µs). Diese Zeit ist nach 1500 Takten erreicht und wird im Register OCR1A gespeichert.

Page 61: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

61

8.2.7 Eine LED im Sekundentakt im CTC Mode blinken lassen

Im folgenden Beispiel soll der 16 Bit Timer im CTC Modus betrieben werden und eine LED am PORT B3 im Sekundentakt blinken lassen. Der Timer soll bei Erreichen des compare match einen Interrupt (Compare Match Interrupt) auslösen.

Zuerst muss der Wert des Output Compare Registers ermittelt werden. Die Taktfrequenz des Controllers beträgt 8MHz.

Der 16 Bit Timer würde ohne Vorteiler demnach 8000000

65535= 102,072 mal pro Sekunde

durchlaufen werden. D.h. der Vorteiler muss größer als 102 gewählt werden, damit der Vergleichswert innerhalb der 16 Bit Auflösung des Timers liegt.

Wir wählen den Wert 256 für den Vorteiler. Damit ergibt sich ein output compare Wert

von 8000000

256= 31250.

Da der Timer bei 0 zu zählen beginnt, muss dass Ergebnis noch um -1 korrigiert werden. Der korrekte Vergleichswert für das Output Compare Register ist also 31250 -1 = 31249.

𝑂𝐶𝑅𝑥 = 𝑓𝐶𝑃𝑈

𝑃𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟∗ 𝑓𝑂𝐶− 1 𝑂𝐶𝑅𝑥 =

8000000

256∗ 1− 1 = 31249

#include <avr/io.h> #include <avr/interrupt.h> #define LED (1<<PB3) // LED auf Portpin B3 int main(void) DDRB |= (1<<PB3); // Port B3 = output TCCR1B |= (1 << CS12); // Vorteiler auf 256 und Timer start TCCR1B |= (1 << WGM12); // Mode 4, CTC on OCR1A OCR1A = 31249; // Compare match auf 31249 setzen TIMSK1 |= (1 << OCIE1A); // Interrupt bei compare match aktivieren sei(); // enable interrupts while(1) asm ("NOP"); // Nichts tun ISR (TIMER1_COMPA_vect) // Timer1 Compare Match Interrupt PORTB ^= LED; // LED im Sekundentakt toggeln lassen

Page 62: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

62

Da der Interrupt bei einem compare match ausgelöst wird, hat auch der Interrupt-Vektor einen anderen Namen. Hier zum Vergleich:

Compare Match Interrupt Timer1: ISR (TIMER1_COMPA_vect)

Timer Overflow Interrupt Timer1: ISR(TIMER1_OVF_vect)

8.3 OCR-Modus (Output Compare Mode)

Viele AVR Controller verfügen über “Output Compare Register“ (z.B. OCRx, OCRAx, OCRBx).

In der Compare-Betriebsart wird der Zählerstand mit dem Inhalt des Vergleichsregisters OCR1A oder OCR1B verglichen. Stimmen beide überein, wird das entsprechende Compare Flag (OCFnx) gesetzt und es kann ein Output Compare Interrupt ausgelöst werden. Das Compare Flag wird automatisch gelöscht, wenn der Interrupt ausgeführt wird. (Alternativ kann ein Flag auch per Software durch das Schreiben einer 1 im zuständigen Register gelöscht werden).

Die folgende Abbildung stellt den OCR-Mode wie zuvor beschrieben grafisch dar:

Abb.18.5: Timer/Counter Zählregister bei einem compare match

Im Output Compare Modus gibt es verschiedene Möglichkeiten ein Signal zu generieren. Einerseits kann ein Interrupt ausgelöst werden und andererseits kann man in diesem Modus einen oder mehrere Ausgangspins des Controllers direkt ansprechen um beispielsweise eine PWM zu erzeugen.

Wie im Blockdiagramm ersichtlich, steuert der Waveform Generator direkt den Ausgangspin OCnx des Controllers. Durch diese hardwareseitige Unterstützung wird der Mikrocontroller bei seiner Arbeit stark entlastet.

Page 63: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

63

8.4 PWM-Mode (Pulsweitenmodulation)

Die Pulsweitenmodulation kurz PWM ist ein Rechtecksignal mit fester Periodenlänge bei der die Ein- und Ausschaltzeit variiert.

Häufige Anwendungen sind beispielsweise das Dimmen einer LED oder die Drehzahlsteuerung eines Elektromotors.

Beispiel einer PWM mit 50% Ein- und 50% Auszeit (Dutycycle = 50%):

Abb.18.8: PWM-Signal mit einem 50% Dutycycle

Über die Periodendauer T wird hier die Leistung halbiert, da der ON-Teil 50% der gesamten Periode beträgt und der OFF-Teil der ebenfalls 50% beträgt Null ist.

Damit kann man nun ganz einfach die Leistung einer LED oder eines Elektromotors steuern. Der Dutycycle einer PWM ist also das Verhältnis der ON-Zeit zur Gesamtzeit einer Periode und wird wie folgt berechnet:

𝐷𝑢𝑡𝑦 𝐶𝑦𝑐𝑙𝑒 = 𝑇𝑜𝑛

𝑇𝑜𝑛 + 𝑇𝑜𝑓𝑓∗ 100

Beispiel:

Es soll eine LED mit einer 100Hz PWM angesteuert werden. Die Periodendauer dieser

Frequenz berechnen wir mit 𝑇 =1

𝑓=

1

100 = 0,01 Sekunden.

Eine gesamte Periode T setzt sich aus der EIN-Zeit Ton und der AUS-Zeit Toff zusammen.

T = Ton + Toff = 1

100 = 0,01 Sekunden oder 10ms.

Page 64: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

64

Die Leistung soll auf ¼ eingestellt werden. D.h. die EIN-Zeit ist ¼ der Gesamtzeit und somit 0,0025 Sekunden oder 2,5ms. Von 10ms ist das Signal also 2,5ms auf ON und die restlichen 7,5ms auf OFF.

Dadurch ergibt sich ein Dutycycle von 25% wie die folgende Darstellung zeigt:

Abb.18.9: PWM-Signal mit einem 25% Dutycycle

Um mit einem AVR-Mikrocontroller ein PWM Signal zu erzeugen, gibt es drei PWM Modi:

Fast PWM Phase Correct PWM Frequency and Phase Correct PWM

Fast PWM

Die Fast PWM ist wie der Name schon verrät eine schnelle PWM für hohe Frequenzen. Im Gegensatz zum CTC-Mode wird das Zählregister bei einem Compare Match nicht auf 0 zurückgesetzt sondern läuft weiter bis zum Top-Wert.

Der Zähler startet bei BOTTOM (bei 0) und zählt bis TOP (65535 beim 16bit Timer). Danach startet der Zähler wieder bei BOTTOM

Die Periodendauer und damit die PWM-Frequenz werden ausschließlich durch den TOP-Wert des Zählers bestimmt. Der TOP-Wert wiederum ist abhängig von der gewählten Auflösung. Wird ein Compare Match erreicht, wird OC1A bis zum nächsten TOP-Wert gelöscht. Damit lässt sich durch die Änderung des OCR1A-Wertes die Pulsweite verändern.

Page 65: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

65

Die folgende Darstellung soll den Fast-PWM Modus veranschaulichen:

Abb.18.10: PWM-Signal im Fast-PWM Modus

Je nach Wahl des Modus (5, 6, 7, 14 oder 15) wird die PWM-Auflösung für den TOP-Wert festgelegt. Der TOP-Wert kann einen festen Wert von 8-, 9- oder 10-bit oder auch einen variablen Wert bestimmt durch ICRn oder OCRnA haben. Der Compare Output Mode bestimmt ob der Ausgang bei einem Compare Match gesetzt, gelöscht (invertiert) oder getoggelt wird. Die folgende Tabelle aus dem Datenblatt des ATMega88 zeigt die verschiedenen Modi und deren Einstellmöglichkeiten:

Page 66: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

66

9 LED-Fading

Unter „Fading“ versteht man das langsame Hoch- und Abwärtsdimmen einer LED. Wie im vorherigen Beispiel zu erkennen war, ändert sich die Helligkeit der LED aber nicht linear. Grund dafür ist die nichtlineare, fast logarithmische Wahrnehmungskennlinie des menschlichen Auges.

Um eine lineare Dimmung der LED zu erhalten, muss man die PWM-Werte über eine logarithmische Funktion (ähnlich einer e-Funktion) berechnen und ausgeben. Dies kann durch eine mathematische Berechnung oder mittels einer PWM-Tabelle erfolgen.

LED-Fading mittels Wertetabelle:

Eine Wertetabelle wird häufig verwendet, da sie bei weitem weniger Ressourcen des Mikrocontrollers benötigt als eine mathematische Berechnung. Die Tabelle enthält je nach Auflösung n verschiedene Werte, die näherungsweise eine logarithmische Funktion wiedergeben.

Hier ein Beispiel eines Arrays mit einer 10bit PWM Tabelle:

const unsigned int pwm_table_10[64] = 0, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17, 19, 21, 23, 26, 29, 32, 36, 40, 44, 49, 55, 61, 68, 76, 85, 94, 105, 117, 131, 146, 162, 181, 202, 225, 250, 279, 311, 346, 386, 430, 479, 534, 595, 663, 739, 824, 918, 1023 ;

Überträgt man diese Werte in ein Diagramm, erhält man eine logarithmische Kurve:

Abb.19.1: Logarithmische Kurve mittels Wertetabelle

Page 67: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

67

9.1 SPI - Kommunikation mit einem 16 Mbit Flash-Speicher

Dieses Beispiel beschreibt im Detail die SPI-Kommunikation mit einem 16Mbit Flash-Speicher (SST25VF016BB)

In der Praxis wird diese Art von Flash-Speicher gerne für die Speicherung nicht flüchtiger Daten z.B als Datenlogger oder als externes EEPROM genutzt. Denn oft ist der interne EEPROM-Speicher eines Mikrocontrollers zu klein oder überhaupt nicht vorhanden.

Der Speicherchip, besser gesagt die einzelnen Speicherzellen können ca. 100.000-mal beschrieben werden und sind in der Lage, Daten über einen Zeitraum von über 100 Jahren speichern.

In diesem Beispielprojekt soll ein Speicherchip (16Mbit Flash Speicher) über das SPI-Interface des ATMega88 angesprochen werden.

Beachten Sie, dass dieser Speicherchip mit max. 3,6V versorgt werden darf.

In diesem Fall versorgen Sie Ihre gesamte Schaltung am besten über einen 3,3V Linearregler bzw. einem LM317. Auch mit zwei in Serie geschalteten 1,5V Batterien oder einer Lithium-Batterie könnte die Schaltung versorgt werden.

Abb.20.10: Empfohlene Beschaltung des SST25VF016B. (1) 100nF Kondensator

Die Pull-Up und Pull-Down Widerstände haben üblicherweise einen Wert von 10kOhm. Sie sind aber nicht zwingend erforderlich und können für Testzwecke auch weggelassen werden. Prinzipiell geht es „nur“ darum, saubere Daten- und Taktsignale für eine störungsfreie Kommunikation zu erhalten. Sind alle benötigten Anschlüsse mit dem Mikrocontroller verbunden, kann nun die Software nach eingehendem Studium des Datenblattes geschrieben werden. Da es gerade für einen Einsteiger oft sehr schwierig

Page 68: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

68

und mühsam ist ein so komplexes Datenblatt zu verstehen, soll das folgende Beispiel die Umsetzung schrittweise veranschaulichen.

Zuerst sollten Sie versuchen, eine Datenkommunikation zwischen dem Mikrocontroller und dem Speicherchip herzustellen. Idealerweise verfügen Sie über ein Oszilloskop und können prüfen, ob ein entsprechendes Signal am MOSI, MISO oder SCK vorhanden ist.

Hier ist es empfehlenswert zuerst das Statusregister des Flash-Speichers auszulesen. Dieser Vorgang ist im Datenblatt mit einem Zustandsdiagramm beschrieben. Wie im Zustandsdiagramm angegeben, muss das Kommando 0x05 gefolgt von einem Dummy Byte gesendet werden. Der Wert des Dummy Byte (üblicherweise wird für ein Dummy-Byte der Wert 0x00 verwendet) hat hier keine Relevanz. Durch das Senden eines Dummybytes werden 8 weitere Taktimpulse am SCK generiert, welche die zu lesenden Daten am SO an den MISO des Mikrocontrollers übertragen. Dort werden die Daten im SPI Data Register zwischengespeichert und abgerufen.

Statusregister auslesen

Zu Beginn der Datenkommunikation muss der Pin CE auf low gesetzt werden und verbleibt bis zum Ende des Datenflusses auf low.

Abb.20.11: Read-Statusregister Sequence

Mit dem Senden des Command Byte 0x05 werden vom Mikrocontroller automatisch acht Taktimpulse am SCK-Ausgang generiert. Der Wert des Command Byte wird am SI (MOSI) an den Flash-Speicher gesendet. Mit der Übertragung des Dummy Byte werden wiederum acht Taktimpulse generiert und gleichzeitig mit jeder fallenden Taktflanke, die Bits des

Command Byte Dummy Byte

Command Byte = 05h Dummy Byte

Page 69: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

69

10 Die UART / USART-Schnittstelle

UART steht für Universal Asynchronous Receiver Transmitter welcher bereits in der 60er Jahren entwickelt wurde. Über die UART-Schnittstelle kann der Mikrocontroller Daten seriell senden und empfangen und so sehr einfach mit einer RS-232-Schnittstelle eines PCs oder anderen Geräten verbunden werden. Die Daten werden seriell mit einem fixen Datenrahmen übertragen. Dieser Rahmen besteht aus einem Start-Bit, 5-9 Datenbits und einem Stop-Bit. Optional gibt es noch ein Parity-Bit für die Erkennung von Übertragungsfehlern.

Startbit D0 D1 D2 D3 D4 D5 D6 D7 (D8) (Parity) Stopbit(s) Abb.22.1: UART-Datenrahmen (LSB wird zuerst gesendet)

Die USART-Schnittstelle (Universal Synchronous/Asynchronous Receiver Transmitter) bietet zusätzlich auch eine synchrone Übertragung der Daten an. Beim asynchronen Betrieb wird für den Takt kein eigenes Taktsignal verwendet. Der Empfänger synchronisiert sich über die Länge des Rahmens (Frame) und die eingestellte Baudrate durch das Start- und Stop-Bit. Damit der Empfänger etwas Zeit hat sich auf den Takt der empfangenen Daten zu synchronisieren, kann das Stop-Bit entsprechend auf das 1,5- oder 2-fache der Übertragungszeit eines Bits verlängert werden. Da bei moderneren PCs meistens keine serielle Schnittstelle zur Verfügung steht, muss in diesem Fall das serielle Datensignal auf ein USB-Signal oder umgekehrt umgesetzt werden.

Abb.22.2: USB/UART Datenverbindung zwischen PC und Mikrocontroller mit einem USB/UART-Konverter

Für diese Umwandlung der seriellen Daten gibt es eigene USB/UART Converter (z.B. CP2102, FTDI232 usw.), Module und USB/RS232 Schnittstellenkabel.

Abb.22.3: USB/UART Converter mit CP2102, Mini-USB/UART Modul und FTDI Entwicklungsmodul USB/UART

Page 70: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

70

Selbstverständlich kann man sich einen USB/UART Converter auch selbst zusammen bauen. Dabei muss der verwendete Converterchip (z.B. CP2102 oder FTDI232RL) entsprechend beschalten werden. Schaltpläne hierzu finden Sie ausreichend im Internet.

Soll eine serielle Verbindung zu einer RS232-Schnittstelle hergestellt werden, benötigt man auch hier einen Chip für die Umsetzung der Signalpegel. Ein bekannter Vertreter ist hier der MAX232. Der MAX232 wandelt einen 5V Pegel eines Mikrocontrollers in den für die RS232-Schnittstelle notwendigen Pegel von +12V und -12V. Ein High-Pegel (+5V) des Mikrocontrollers entspricht einem -12V-Pegel bei RS232 und ein Low-Pegel (0V) dementsprechend +12V. Die internen DC-DC-Wandler des MAX232 sind für die Erzeugung der Spannungspegel verantwortlich. Der Chip muss nur mehr von außen mit vier Kondensatoren beschalten werden. Auch hierfür stehen genügend Schaltpläne im Internet zur Verfügung.

10.1 Ein Zeichen vom PC an die USART-Schnittstelle senden

In diesem Beispiel soll unser PC mit dem Mikrocontroller über die USB/USART-Schnittstelle über einen USB/UART-Converter kommunizieren und ein vom PC gesendetes Zeichen zurücksenden und am PORTB ausgeben. Dafür benötigen wir ein Terminalprogramm am PC welches Zeichen senden und empfangen kann. Ältere Betriebssysteme wie z.B. Windows XP haben das Programm Hyper-Terminal automatisch unter Windows (Programme --> Zubehör --> Kommunikation) installiert. Das Programm muss beim Start auf die jeweiligen Einstellungen (COM Port, Baud Rate, Stop Bits, etc.) eingestellt werden. Neuere PCs (ab Win7) haben kein Terminalprogramm mehr installiert. In diesem Fall verwenden Sie einfach ein Terminalprogramm eines anderen Anbieters wie z.B. TeraTerm Putty oder HTerm.

In diesem Versuch wird mit dem Programm HTerm ein Zeichen an den Mikrocontroller gesendet, anschließend zurück gesendet und im Fenster „Received Data“ angezeigt. Sollte das folgende Programmbeispiel bei Ihnen nicht funktionieren, schließen Sie einen externen Quarz an den Controller oder kalibrieren Sie den internen RC-Oszillator lt. Datenblatt im Register OSCCAL . Der interne RC-Oszillator ist oft recht ungenau. Prüfen Sie auch, ob die Schnittstellenleitungen Rx und Tx am Controller nicht vertauscht sind.

Page 71: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

71

Abb.22.4: Serielle Datenkommunikation zwischen PC und Mikrocontroller mit dem Programm HTerm

In diesem Fall befindet sich die serielle Schnittstelle mit dem USB/UART-Controller Modul am COM Port 4. Testen Sie zuerst das folgende Programmbeispiel uart_demo_01.c aus und versuchen Sie eine Kommunikation zwischen ihrem PC und dem Mikrocontroller herzustellen.

Wenn wir nun ein Zeichen senden (in unserem Fall das Zeichen a) wird der entsprechende ASCII-Code des Zeichens an den Mikrocontroller gesendet und dort am PORTB ausgegeben. Da das empfangene Zeichen sofort zurück gesendet wird, wird es im Terminalfenster „Received Data“ empfangen und angezeigt. Der ASCII-Code für das Zeichen a ist 61Hex und daher wird am PORTB 61Hex (= binär 0110 0001) angezeigt. Die den jeweiligen Zeichen zugehörigen Codes können Sie der ASCII-Tabelle im Anhang des Buches entnehmen.

Page 72: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

72

11 Die I2C-Schnittstelle (TWI-Schnittstelle)

Die I²C-Schnittstelle (Inter Integrated Circuit) ist ein genormter serieller Bus und wurde ursprünglich von Philips (jetzt NXP) entwickelt. Dieser synchrone Zweidraht-Bus auch TWI-Bus genannt (Two Wire Interface) ist mittlerweile zum Industriestandard avanciert. Ziel der Entwicklung war es, ein einfaches und kostengünstiges Bussystem zu schaffen über das mehrere ICs wie z.B. Temperatursensoren, Drucksensoren, Lichtsensoren, RTC, Multiplexer/Demultiplexer, ADC/DAC, EEPROM, RAM, Portexpander usw. miteinander kommunizieren können.

Aus diesem Anspruch heraus entstand ein bidirektionaler Bus mit nur zwei Leitungen in einer Master/Slave Anordnung. Über diese beiden Leitungen wird der Takt über SCL (serial clock line) und die Daten über SDA (serial data) übertragen. So kann z.B. ein einziger Mikrocontroller (Master) eine Vielzahl an ICs (Slaves) mit nur zwei Leitungen steuern.

Abb.23.1: Prinzipschaltbild eines I²C Netzwerkes

Wie in der obigen Abbildung dargestellt, werden alle Slaves über die beiden Leitungen SDA und SCL untereinander verbunden. Für eine entsprechende Signalsicherheit werden die beiden Leitungen SDA und SCL über Pullup-Widerstände auf Vcc (Ruhezustand) gezogen. Typischerweise werden Widerstandswerte zwischen 2,2kΩ und 10kΩ eingesetzt. Auf Grund unterschiedlicher Buskapazitäten sollten die Signale mit einem Oszilloskop auf ihre Tauglichkeit überprüft werden.

11.1 Prinzip der I²C - Datenübertragung

Die Datenübertragung erfolgt synchron und bitseriell. Dabei wird jedes zu übertragene Datenbit der SDA-Leitung mit dem Takt der SCL-Leitung synchronisiert. Da es sich um eine bidirektionale Datenübertragung handelt, kann prinzipiell jeder Busteilnehmer Daten versenden oder anfordern.

Page 73: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

73

Die Datentransferrate beträgt bei einer maximalen Buskapazität von 400pF im Standard Mode 100kBit/s und im Fast Mode 400kBit/s. Für höhere Taktraten gibt es zudem noch den Fast Mode Plus mit 1MBit/s, den High Speed Mode mit 3,4MBit/s und den Ultra Fast Mode mit 5MBit/s. Letzterer Mode gilt aber nur für unidirektionale Übertragung.

Damit die Daten auch an den jeweils richtigen Empfänger gelangen, kann jeder am Bus angeschlossene Teilnehmer über eine eindeutige Adresse identifiziert werden. Eine Kommunikation wird immer von einem Master initiiert welcher auch das notwendige Taktsignal generiert. Da beim I²C-Bus keine festen Taktzeiten festgelegt sind, können auch Busteilnehmer mit unterschiedlichen Geschwindigkeiten eingesetzt werden. Sollte für einen Slave die Taktrate zu hoch sein, hat er die Möglichkeit, die Taktleitung auf Masse zu ziehen und damit die Übertragungsgeschwindigkeit zu reduzieren. Diese Vorgehensweise wird als „clock streching“ bezeichnet. Um größere Übertragungswege (einige Meter) realisieren zu können, muss die Taktrate entsprechend reduziert werden.

Im folgenden Beispiel werden zwei Temperatursensoren (LM75) am Bus betrieben. Damit der Mikrocontroller (Master) die beiden Temperatursensoren (Slaves) unterscheiden kann, müssen sie unterschiedlich adressiert werden. Um einen Slave zu adressieren müssen die Adressleitungen mit einem High- oder Low-Pegel beschalten werden.

Abb.23.2: Adressierung von zwei Temperatursensoren

Wie in diesem Beispiel dargestellt liegen die Adresseingänge des ersten LM75 auf Masse (Adresse = 000) wogegen die Adresse A0 des zweiten LM75 auf High liegt (Adresse = 001). Damit wurden beide Slaves unterschiedlich adressiert und können so vom Master unterschieden werden.

Werden in einem I²C-Bussystem mehrere Master eingesetzt, spricht man von einem Multi-Master-Bus. Hier ist es entscheident, dass immer nur ein Master die Kontrolle über den Bus übernimmt. Hat ein Master einen Lese- oder Schreibvorgang beendet, gibt er den Bus

Page 74: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

74

wieder frei. Das I²C-Protokoll bietet hier Möglichkeiten um Kollisionen von mehreren Mastern im Bus zu vermeiden.

Nur ein Master kann eine Datenkommunikation am Bus einleiten. Ein Slave kann selbständig keine Daten senden. Er wird immer von einem Master aufgefordert die angefragten Daten zu senden.

11.2 Datenübertragung von einem Master zu einem Slave

Wie eingangs erwähnt, gibt es für den I²C-Bus ein genormtes Übertragungsprotokoll. Daten werden im 8-bit Format beginnend mit dem höchstwertigen Bit (MSB) nach genauen Regeln übertragen. Die folgende Abbildung zeigt die Abfolge einer Datenübertragung:

8Bit 8Bit 8Bit

Abb.23.3: Datenübertragung von einem Master zu einem Slave

Mit dem Senden eines START-Bits wird die Datenübertragung eingeleitet. Anschließend folgt die ADRESSE des anzusprechenden Slaves (7 Bit oder 10 Bit). Mit dem WRITE (W) oder READ (R) Bit wird dem Slave mittgeteilt ob Daten gesendet oder gelesen werden sollen. Hat der Slave die Übertragung verstanden, antwortet er mit einem ACKNOWLEDGE (ACK). Jetzt werden DATEN im 8-bit Format gesendet. Je nachdem ob es sich um einen Schreib- oder Lesevorgang (W/R) handelt, werden Daten vom Master an den Slave (write) oder vom Slave an den Master (read) gesendet. Nach jedem gesendeten Datenpaket wird die erfolgreiche Übertragung mit einem ACK bestätigt. Dieser Vorgang wiederholt sich nun solange Daten am Bus übertragen werden sollen. Ein Ende der Datenübertragung wird mit einer STOP-Bedingung abgeschlossen.

11.3 Datenübertragung von einem Slave zu einem Master

Ähnlich wie die Datenübertragung von einem Master zu einem Slave funktioniert auch die Datenübertragung von einem Slave zu einem Master. Nachdem der Master die Startbedingung eingeleitet hat folgt die Adresse des Slave mit einer Leseanforderung (Read). Der Master teilt dem Slave also mit, dass er nun bestimmte Daten lesen möchte. Nachdem der Slave mit einem Acknowledge bestätigt hat, sendet er die angeforderten Daten zum Master welcher anschließend mit einem Acknowledge bestätigt.

9.Bit 9.Bit 9.Bit

Page 75: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

75

Möchte der Master keine weiteren Daten vom Slave erhalten, sendet er ein NACK (No Acknowledge) und beendet den Datentransfer mit einem Stopbit.

Abb.23.4: Datenübertragung von einem Slave zu einem Master

Grundsätzlich unterscheidet man also zwei Modi zur Datenübertragung:

Master Transmitt Mode (Slave Address + Write) Im MT-Mode überträgt der Master an den Slave die Daten. Nach erfolgreicher Übertragung erhält der Master vom Slave ein ACK mit dem 9. Takt. Für ein ACK zieht der Slave die SDA-Leitung auf Low.

Master Receive Mode (Slave Address + Read) Im MR-Mode fordert der Master den adressierten Slave auf die gewünschten Daten zu senden. Sendet der Slave die entsprechenden Daten erfolgreich an den Master, bestätigt dieser mit einem ACK wenn er weitere Daten empfangen möchte oder mit einem NACK wenn keine weiteren Daten gewünscht werden. Um ein ACK an den Slave zu senden, zieht hier der Master die SDA-Leitung mit dem 9. Takt auf Low.

11.4 Bitübertragung

Jedes Datenbit welches am Bus übertragen wird, wird zum Zeitpunkt des Taktsignals übernommen. Für die Dauer des Taktsignals muss das Datenbit auf einem stabilen Level sein und darf sich in dieser Zeit nicht ändern. Die einzige Ausnahme ist die Start- und Stoppbedingung.

Abb.23.5: Gültigkeit einer Bitübertragung am I²C Bus

9.Bit 9.Bit 9.Bit

Page 76: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

76

11.5 Start- und Stopbedingung

Um einen Datentransfer einzuleiten muss der Master einen Start mit einer Startbedingung initiieren. Um eine Datenübertragung zu beenden und den Bus frei zu geben, muss der Master eine Stopbedingung übermitteln. Ein Startsignal wird durch eine fallende Taktflanke auf der SDA-Leitung erzeugt während das SCL-Signal stabil auf einen High-Zustand liegt. Ein Stopsignal wird durch eine steigende Taktflanke auf der SDA-Leitung erzeugt während das SCL-Signal stabil auf einen High-Zustand liegt. Nachdem ein Startsignal vom Master gesendet wird, ist der Bus belegt (busy).

Abb.23.6: I²C Start- und Stopbedingung

Es ist wichtig, dass die SCL-Leitung während eines Flankenwechsels auf der SDA-Leitung stabil auf High-Potential liegt. Um den Datendurchsatz etwas zu erhöhen, gibt es auch die Möglichkeit eine erneute Startbedingung (Repeated Start) zu senden.

11.6 Repeated Start

Nachdem der Master mit einer Startbedingung einen Datentransfer eingeleitet hat, ist der Bus bis zu einer Stopbedingung belegt. In dieser Zeit kann kein anderer Master am Bus einen Datentransfer einleiten. Eine Besonderheit stellt ein „Repeatet Start“ dar. Diese Bedingung wird erzeugt in dem zwischen einer Start- und Stopbedingung eine erneute Startbedingung vom Master generiert wird.

Abb.23.7: I²C Start, Repeated Start und Stopbedingung

Page 77: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

77

11.7 I²C – Beispielprojekt Temperaturmessung mit dem LM75

In diesem Beispielprojekt soll der Temperatursensor LM75 über die I²C-Schnittstelle des ATMega88 angesteuert werden. Der Temperatursensor soll die aktuelle Umgebungstemperatur alle 200ms messen und am PORTD auf 8 LEDs als Binärwert ausgeben. Die Versorgungsspannung von 3,3V wurde in diesem Beispiel mit dem Linearregler LM317 realisiert. Sollten Sie die Schaltung mit 5V versorgen, müssen Sie die Vorwiderstände der LEDs anpassen und z.B. 470Ω Widerstände verwenden.

Abb.23.12: LM75 Pinbelegung

Abb.23.13: Schaltung Temperaturmessung mit LM75

Page 78: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

78

11.8 I²C – Beispielprojekt Lichtmessung mit dem ISL29020

Der ISL29020 ist ein digitaler hochempfindlicher Lichtsensor mit einem I²C- bzw. TWI-Interface. Das vom Sensor gemessene Umgebungslicht wird direkt in Lux als 16bit Wert im Datenregister (LSByte und MSByte) des ISL29020 gespeichert und kann vom I²C-Master abgerufen werden. Die Empfindlichkeit des Lichtsensors kann im Register „command“ in vier Bereiche eingestellt werden:

Range 1: 0,015 bis 1000 Lux Range 2: 0,06 bis 4000 Lux Range 3: 0,24 bis 16000 Lux Range 4: 0,96 bis 64000 Lux

Der Stromverbrauch des Sensors beträgt im Betrieb ca. 55µA und kann im power-down mode auf rund 0,5µA herab gesetzt werden. Die Spannungsversorgung beträgt 2,25V bis 3,3V. Wie im Datenblatt angegeben, kann der Sensor unterschiedliche Lichtquellen detektieren. Auch Messungen von infrarotem Licht sind möglich.

Abb.23.14: Typische Beschaltung des ISL29020

Der ISL29020 besitzt drei Register. Im Register COMMAND mit der Adresse 0x00 werden die Grundeistellungen wie z.B. Auflösung, Messmethode, Messbereich usw. eingestellt.

Abb.23.15: ISL29020 Register Set

Page 79: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

79

12 Ansteuerung einer 7-Segmentanzeige im Multiplexbetrieb

In diesem Beispiel sollen drei 7-Segmentanzeigen mit dem ATMega88 angesteuert werden. Da normalerweise eine einzige 7-Segmentanzeige acht Portpins eines Mikrocontrollers benötigt, verwendet man üblicherweise entweder ein Schieberegister oder steuert die Anzeige im Multiplexbetrieb. Da Schieberegister im Abschnitt „Porterweiterung mit Schieberegister“ behandelt werden, wird hier der Multiplexbetrieb vorgestellt. Im Multiplexbetrieb wird eine Anzeigeeinheit nur für eine bestimmte kurze Zeit (5ms) aktiviert und anschließend auf die nächste Anzeigeeinheit weitergeschaltet. Das heißt, dass in unserem Beispiel zuerst die Anzeige 1 durch die Ansteuerung des Transistors T1 aktiviert wird. Es folgt Anzeige 2 und Anzeige 3. Danach beginnt das „ganze Spiel“ von vorne. Ab einer Wiederholfrequenz von ca. 50Hz beginnt sich bedingt durch die Trägheit des Auges ein Standbild der Anzeige einzustellen.

Abb.24.1: Schaltplan zur Ansteuerung einer 7-Segmentanzeige im Multiplexbetrieb

Über die Ansteuerung der PNP-Transistoren T1, T2 und T3 wird jeweils eine 7-Segmentanzeige aktiviert und die entsprechende Ziffer durch die Ansteuerung von PortD dargestellt. Die entsprechende Codierung der LED-Anzeigeelemente muss aus dem

Page 80: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

80

jeweiligen Datenblatt entnommen werden. In unserem Beispiel wird eine 7-Segmentanzeige von AVAGO (HDSP-315E) mit einer gemeinsamen Anode verwendet. Bei gemeinsamer Anode (CA engl. Common Anode) werden die einzelnen LED-Segmente mit einem Low-Signal aktiviert. Aus diesem Grund wird die Stromversorgung der Anzeigen mit PNP-Transistoren geschalten. Bei einem PNP-Transistor muss die Basis gegenüber dem Potential am Emitter um ca. 0,6V negativer sein. Da am Emitter +3,3V anliegen, muss die Basis mit einem Low-Signal angesteuert werden um den Transistor durch zu schalten.

Um beispielsweise die Zahl 2 anzuzeigen müssen die Segmente a+b+g+e+d leuchten. In unserem Fall (gemeinsame Anode) müssen also diese Segmente mit einem Low-Signal angesteuert werden. Das PortD muss für die Zahl 2 demnach auf 00100101 (0x25) gestellt werden.

Anzeige LED Segment

Hex Wert a b c d e f g dp

Bit Nr. 7 6 5 4 3 2 1 0

0 0 0 0 0 0 0 1 1 0x03

1 1 0 0 1 1 1 1 1 0x9F

2 0 0 1 0 0 1 0 1 0x25

3 0 0 0 0 1 1 0 1 0x0D

4 1 0 0 1 1 0 0 1 0x99

5 0 1 0 0 1 0 0 1 0x49

6 0 1 0 0 0 0 0 1 0x41

7 0 0 0 1 1 1 1 1 0x1F

8 0 0 0 0 0 0 0 1 0x01

9 0 0 0 0 1 0 0 1 0x09

1 1 1 1 1 1 1 0 0xFE

Abb.24.2: Codierungstabelle für eine 7-Segmentanzeige

Die entsprechende Codierung der Anzeigensegmente wird in einer Tabelle (ein Array mit 11 konstanten Werten) abgelegt.

const uint8_t segmenttable[11] = 0x03, 0xF3, 0x25, 0x0D, 0x99, 0x49, 0x41, 0x1F, 0x01, 0x19, 0xFE /* 0 1 2 3 4 5 6 7 8 9 dp */ ;

Soll beispielsweise die Zahl 7 angezeigt werden, muss das 7. Feld im Array aufgerufen werden. Dies geschieht durch PORTD = segmenttable [7]; // Aufruf von 0x1F

Abb.24.3: Pinbelegung AVAGO HDSP-315E

Page 81: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

81

13 Ansteuerung eines LC-Displays

Ein LC-Display ist im Grunde nichts anderes als ein Punktmatrix-Display welches von einem auf dem Display befindlichen Controllerchip angesteuert wird. Es gibt ein- zwei- und vierzeilige Displays mit bis zu 40 Zeichen pro Zeile. Jedes einzelne Zeichen davon besteht in der Regel aus einer Matrix mit 5x8 Punkten. Der Controllerchip HD44780 von Hitachi bzw. entsprechende kompatible Controller wie z.B. der KS0066 haben sich in der Vergangenheit als Standard durchgesetzt und werden von allen Displayherstellern verbaut. Der Controller ist mit einem parallelen Interface, einem Textpuffer mit 80 Zeichen und einem LCD-Treiber mit 16 Zeilen- und 80 Spaltenleitungen ausgestattet.

Abb.25.1: Beschaltung eines Displaytech 162B LC-Displays (HD44780 kompatibel)

Das alphanumerische LCD-Modul 162B von Displaytech verfügt über zwei Zeilen mit jeweils 16 Zeichen und verwendet den Controller KS0070B, der kompatibel zum Industriestandard HD44780 ist. Die Ansteuerung erfolgt parallel mit einem wahlweise 4 Bit oder 8 Bit breiten Datenbus.

Page 82: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

82

Abb.25.2: Anschlussbelegung Displaytech 162B aus dem Datenblatt:

Beachten Sie, dass es auch andere Anschlussbelegungen von LC-Displays gibt und ein falscher Anschluss zur Zerstörung des Displays führen kann. Prüfen daher immer die Pinbelegung im Datenblatt!

GND oder VSS wird mit Masse verbunden. An Vcc bzw. VDD wird die Betriebsspannung (4,5V bis 5,5V) angeschlossen.

V0 ist der Pin für die Kontrastspannung welche im Bereich zwischen 0V und 1,5V liegt und mit einem Poti eingestellt wird.

RS ist der Register Select Pin. Mit einer 0 sagen wir dem Display dass wir Steuerdaten und mit einer 1 Textdaten senden wollen.

R/W steht für Read / Write. Dieser Pin wird oft direkt mit Masse verbunden um einen Portpin zu sparen. Mit 0 an diesem Pin können Daten an das Display (der übliche Weg) gesendet werden. Mit einer 1 können aber auch Daten ausgelesen werden.

E steht für Enable und aktiviert mit einem High-Signal den Datenfluss des Displays. Damit wird dem Display signalisiert, dass es die Daten bzw. Kommandos übernehmen kann.

DB0…DB7 sind die Datenleitungen. Meist werden nur die oberen vier Datenleitungen (DB4…DB7) im 4-Bit Modus verwendet um Portpins zu sparen.

A / K (Anode / Kathode) sind die Anschlüsse für die Hintergrundbeleuchtung des Displays. Je nach Pinbelegung werden diese Pins über einen Vorwiderstand zur Strombegrenzung an +5V oder Masse angeschlossen.

Page 83: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

83

8-Bit / 4-Bit Modus

Grundsätzlich gibt es die Möglichkeit das Display im 8-Bit- oder im 4-Bit-Modus anzusteuern. Der 8-Bit-Modus hat den Vorteil, dass mit einem einzigen Zugriff ein ganzes Byte übertragen werden kann. Dafür werden aber auch 8 Portleitungen benötigt.

Im 4-Bit-Modus werden nur die obersten 4 Datenleitungen (DB4…DB7) verwendet. Damit kann aber nur ½ Byte (ein Nibble = 4 Bit) mit einem Schritt übertragen werden. In diesem Fall muss ein Datenbyte in zwei Schritten – zuerst das höherwertige Nibble, dann das niederwertige Nibble – übertragen werden. Die unteren vier Datenleitungen lässt man hier ganz einfach offen. Der große Vorteil der 4-Bit Übertragung ist die Einsparung von 4 Portleitungen.

Der HD44780 Controllerchip

Der HD44780-Controller besitzt ein paralleles Interface mit Treibern für die Displayansteuerung in 16 Zeilen und 40 Spalten. Die Textzeichen werden in einem 80 Zeichen langen Textpuffer zwischengespeichert. Jedes einzelne Zeichen wird aus einer Punktmatrix mit 5x8 Punkten dargestellt.

Jedes Zeichen wird im 80-Zeichen Textpuffer gespeichert und vom Display angezeigt. Dieser Textpuffer wird als DDRAM bezeichnet und ist in zwei Adressbereiche aufgeteilt.

Zeile1: Adressbereich von 00h bis 27h (00h bis 0Fh ist darstellbar) Zeile2: Adressbereich von 40h bis 67h (40h bis 4Fh ist darstellbar)

Abb.25.3: DDRAM-Adressen eines 2*16 Displays

Da der anzeigbare Adressbereich kleiner als der Textbuffer ist, kann der Textpuffer mit dem Kommando „SHIFT“ nach links bzw. rechts schrittweise verschoben werden.

Soll ein Zeichen in der 2. Zeile an der 2. Position dargestellt werden, ist das die DDRAM-Adresse 41h. Nach dem Einschalten befindet sich das Display an der DDRAM-Adresse 00h.

Page 84: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

84

Der Zeichengenerator CGRAM / CGROM

Ein Zeichen welches im Display dargestellt wird besteht aus einer Punktmatrix bestehend aus 8 Zeilen und 5 Spalten.

Das CGROM ist ein Speicher, wo jedes darstellbare Zeichen des LC-Displays gespeichert ist. Der Zeichensatz ist im Datenblatt dargestellt.

Das CGRAM ermöglicht es, eigene Zeichen z.B. für eine Balkengrafik mittels Punktmuster zu erstellen.

Abb.25.4: LCD-Punktmatrix

Die Zeichen des Zeichengenerators sind den ASCII-Codes zugeordnet. Das Zeichen “E“ hat beispielsweise im Zeichengenerator und im ASCI-Zeichensatz den Code 01000101 (54h). Um eigene Zeichen zu erstellen, muss der Bytecode für ein Zeichen ermittelt werden. Die folgende Abbildung zeigt, wie ein Bytecode (Jede Zeile = 1 Byte) eines Zeichens ermittelt wird:

Abb.25.5: Hex-Code für ein eigenes Zeichen berechnen

Das Ergebnis sind 8 Bytes (0x11, 0x1B, 0x15, 0x15, 0x15, 0x1F, 0x1F, 0x00) welche in die entsprechende Zelle des CGRAM mit den Kommandos “SET CG RAM ADDRESS“ und “WRITE DATA“ geschrieben werden müssen.

Schreibzugriff auf das LC-Display

Der „Startschuss“ für einen Schreibzugriff (auch Lesezugriff) ist eine Änderung des ENABLE-Pegels von Low auf High. Geht ENABLE auf High, fragt das Display die Pins RS und R/W ab. Ist der Pin R/W auf Low, weiß das Display dass Daten geschrieben werden sollen. Mir RS wird ausgewählt, ob ein Kommando oder ein Datenbyte an das Display gesendet werden soll.

Spalten 1…5

Zeilen 1…8

Page 85: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

85

14 LED Punktmatrix Display ansteuern

Ein LED Punktmatrix Display besteht aus einer Matrix von LEDs, welche in rechteckiger Form in Zeilen und Spalten angeordnet sind.

Abb.27.1: Pinbelegung 7x5 Punktmatrix Display KINGBRIGHT - TA12-11GWA

Über die Ansteuerung der entsprechenden Zeilen und Spalten kann somit jede beliebige Grafik dargestellt werden. Punktmatrix Displays gibt es in verschiedenen Ausführungen wie z.B. 7x5, 8x8, 7x15 etc. Die Abbildung zeigt ein 7x5 Display mit der entsprechenden Pinbelegung und LED-Anordnung.

Um nun alle LEDs des Displays ansteuern zu können, werden die LEDs im Multiplexverfahren betrieben. Möchte man z.B. alle LEDs des Displays über je eine Portleitung ansteuern, würden bei einem 7x5-Display insgesamt 35 Portpins dafür benötigt werden. Im Multiplexbetrieb wird in einer zeitlichen Abfolge eine LED (besser gesagt eine Spalte) nur für sehr kurze Zeit angesteuert. Da das menschliche Auge sehr träge auf eine Lichtänderung reagiert, werden die raschen Ein- und Ausschaltzeiten einer LED im Multiplexbetrieb nicht wahrgenommen.

Die zeitliche Abfolge von Ein- und Ausschaltzeit sollte hierbei mindestens 50Hz (20ms) besser 100Hz (10ms) betragen. Mit diesem Verfahren lassen sich sehr viele Portpins einsparen. Für jede Zeile und jede Spalte wird im Multiplexbetrieb nur je ein Portpin benötigt. D.h. für ein 7x5-Punktmatrix Display werden insgesamt 13 Portpins benötigt.

Wie in obiger Abbildung zu erkennen ist, sind die Anoden aller LEDs mit den Spalten C1 bis C5 und die Kathoden mit den Zeilen R1 bis R7 verbunden. Um beispielsweise die LED in der 1. Zeile und 1. Spalte anzusprechen, muss R1 mit einem Low- und C1 mit einem High-

Page 86: Inhaltsverzeichnis Leseprobe - newbooks-services.de · 4 Heimo Gaicher AVR-Mikrocontroller Programmieren in C für Einsteiger Vorwort Dieses Buch richtet sich an Einsteiger und Elektronik-Entwickler,

86

Signal angesteuert werden. Sollen z.B. alle LEDs der 2.Zeile leuchten, muss die Zeile R2 mit einem Low-Signal und alle Spalten (C1…C5) mit einem High-Signal angesteuert werden.

Da auch bei einem Punktmatrix Display einzelne LEDs angesteuert werden, muss der Strom über Vorwiderstände begrenzt werden. Werden hierbei größere Ströme benötigt als der Mikrocontroller liefern kann, müssen die Spalten über einen Treiber oder über Transistoren geschalten werden. (Siehe Abb.24.1: „ Schaltplan zur Ansteuerung einer 7-Segmentanzeige im Multiplexbetrieb“) Wird für eine LED beispielsweise ein Strom von 10mA benötigt, dann wird für das Zeichen C im 1. Schritt ein Strom von insgesamt 50mA in Spalte C1 benötigt, da in diesem Fall fünf LEDs gleichzeitig versorgt werden.

Abb.27.2: Zeitliche Abfolge der angesteuerten Punkte im Multiplexbetrieb

Die rasche Abfolge der Schritte 1 bis 5 ergibt letztendlich Schritt Nummer 6 und damit die Darstellung des Buchstaben C.

R1 R2 R3 R4 R5 R6 R7 C1 C2 C3 C4 C5

0 1 1 1 1 1 0 0 1 1 1 1

delay 1ms

1 0 0 0 0 0 1 1 0 1 1 1

delay 1ms

1 0 0 0 0 0 1 1 1 0 1 1

delay 1ms

1 0 0 0 0 0 1 0 1 1 0 1

delay 1ms

0 1 0 0 0 1 0 1 1 1 1 0

delay 1ms

1. 2. 3.

4. 5. 6.

R = Zeile (engl. row) C = Spalte (engl. column)

Schritt 1: R=0111110, C=01111

Schritt 2: R=1000001, C=10111

Schritt 3: R=1000001, C=11011

Schritt 4: R=1000001, C=01101

Schritt 5: R=0100010, C=11110