Computertechnik mit Mikrocontrollern
Computertechnik mit Mikrocontrollern
Computertechnik mit Mikrocontrollern
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
<strong>Computertechnik</strong><br />
<strong>mit</strong> <strong>Mikrocontrollern</strong><br />
Hanns-Konrad Unger<br />
mail@hanns-konrad.de<br />
2006 November 10<br />
Manuskript
Satz Hanns-Konrad Unger<br />
Fotos Hanns-Konrad Unger<br />
Gestaltung Hanns-Konrad Unger
Vorwort<br />
Computer sind als PCs verbreitet. Hinter intuitiv bedienbaren<br />
Fenstern arbeiten komplexe Programme, die versuchen, den<br />
Benutzer von der Technik fernzuhalten. Oft gelingt es.<br />
Dieses Buch wurde für Menschen geschrieben, die sich für die<br />
Grundlagen der <strong>Computertechnik</strong> interessieren und am liebsten<br />
praktisch lernen (learning by doing). Heute ist ein Mikrocontroller<br />
leicht handhabbar und preiswert. Trotzdem ist er<br />
ein gutes Beispiele für Computer.<br />
Die ersten beiden Teile des Buches bilden eine kurze<br />
Einführung. Um <strong>mit</strong> dem dritten Teil zurechtzukommen,<br />
sind gegebenenfalls Studien <strong>mit</strong> weiterer Literatur durchzuführen.<br />
Auch das Internet bietet z. B. <strong>mit</strong> der Enzyklopädie<br />
[wikipedia] gute Möglichkeiten zur Vertiefung.<br />
Die Hardware für die praktischen Übungen des Hauptteils ist<br />
vom Taschengeld finanzierbar und leicht erhältlich. Ein PC<br />
möglichst <strong>mit</strong> Druckerschnittstelle wird benötigt.<br />
Zielgruppen sind Schüler, Studenten und Praktiker.<br />
4
Für die Durchführung von Praktika in Gruppen können Masken<br />
<strong>mit</strong> mehreren Platinenlayouts gedruckt werden. Die Basisplatine<br />
ist in Bereiche aufgeteilt und kann auf verschiedene<br />
Arten <strong>mit</strong> Strom versorgt werden, um je nach Umfang und<br />
Kostenrahmen skalierbar zu sein. Der Mikrocontroller wird<br />
<strong>mit</strong> 4, 8 und 16 KB Flash-Speicher in der erforderlichen Bauart<br />
angeboten.<br />
Begriffe in eckigen Klammern [ ] weisen auf das Literaturverzeichnis<br />
am Ende des Buches hin.<br />
Die Fotos wurden <strong>mit</strong> höherer Auflösung gemacht, als drucktechnisch<br />
wiedergegeben wird. Die pdf-Version des Buches<br />
ermöglicht die Ansicht von Details.<br />
Bevor Sie <strong>mit</strong> dem Buch beginnen, erlauben Sie bitte einen<br />
Eingangstest:<br />
Verstehen Sie das Titelbild?<br />
Na klar! Die Themen der ersten beiden Teile<br />
werden Ihnen weitgehend vertraut sein.<br />
Ich glaube ja. Den ersten Teil können Sie vermutlich<br />
schnell lesen.<br />
Nein. Wahrscheinlich werden Sie das Buch<br />
zwei mal durcharbeiten müssen.<br />
5
Inhaltsverzeichnis<br />
I Einführung in die <strong>Computertechnik</strong> 13<br />
1 Entwicklung der Computer 14<br />
2 Zahlensysteme 17<br />
3 Rechnerarchitektur 25<br />
3.1 von-Neumann-Architektur . . . . . . . . . . . 25<br />
3.2 Register . . . . . . . . . . . . . . . . . . . . . 28<br />
3.3 Stackpointer . . . . . . . . . . . . . . . . . . . 28<br />
3.4 Statusregister . . . . . . . . . . . . . . . . . . 29<br />
3.5 Harvard-Architektur . . . . . . . . . . . . . . 29<br />
3.6 CISC und RISC . . . . . . . . . . . . . . . . . 29<br />
6
INHALTSVERZEICHNIS 7<br />
4 Computerschnittstellen 31<br />
4.1 Centronics . . . . . . . . . . . . . . . . . . . . 32<br />
4.2 RS-232 . . . . . . . . . . . . . . . . . . . . . 33<br />
4.2.1 RS232-Schnittstelle des IBM AT . . . . 35<br />
4.2.2 Schichten . . . . . . . . . . . . . . . . 38<br />
4.3 USB . . . . . . . . . . . . . . . . . . . . . . . 40<br />
5 Kurzeinführung in Linux 42<br />
5.1 Kern des Betriebssystems . . . . . . . . . . . 44<br />
5.2 Bäume wachsen – Dateisysteme . . . . . . . . 46<br />
5.2.1 Wurzelverzeichnis . . . . . . . . . . . . 49<br />
5.2.2 Heimatverzeichnis . . . . . . . . . . . . 50<br />
5.2.3 Arbeitsverzeichnis . . . . . . . . . . . . 50<br />
5.3 GNU - Tools . . . . . . . . . . . . . . . . . . 51<br />
5.3.1 bash . . . . . . . . . . . . . . . . . . . 53<br />
5.3.2 Editoren . . . . . . . . . . . . . . . . . 54<br />
5.3.3 make . . . . . . . . . . . . . . . . . . . 56<br />
5.3.4 X11 . . . . . . . . . . . . . . . . . . . 57<br />
5.3.5 Ghostscript . . . . . . . . . . . . . . . 58<br />
5.3.6 Datenbank . . . . . . . . . . . . . . . . 58
INHALTSVERZEICHNIS 8<br />
6 Assembler 61<br />
7 Programmiersprache C 64<br />
II Hardwaretechnik 68<br />
8 Hardware-Labor 69<br />
8.1 Lötkolben . . . . . . . . . . . . . . . . . . . . 69<br />
8.2 Multimeter . . . . . . . . . . . . . . . . . . . 71<br />
8.3 Netzgerät . . . . . . . . . . . . . . . . . . . . 76<br />
9 Kleine Bauteilekunde 77<br />
9.1 Platinenmaterial . . . . . . . . . . . . . . . . 77<br />
9.2 Stecker . . . . . . . . . . . . . . . . . . . . . . 78<br />
9.3 Kabel . . . . . . . . . . . . . . . . . . . . . . 79<br />
9.4 Widerstände . . . . . . . . . . . . . . . . . . . 80<br />
9.5 Kondensatoren . . . . . . . . . . . . . . . . . 83<br />
9.6 Quarze . . . . . . . . . . . . . . . . . . . . . . 85<br />
9.7 Dioden . . . . . . . . . . . . . . . . . . . . . . 87<br />
9.8 Transistoren . . . . . . . . . . . . . . . . . . . 89<br />
9.9 Integrierte Schaltungen . . . . . . . . . . . . . 91
INHALTSVERZEICHNIS 9<br />
10 Platinenlayouts 93<br />
10.1 Programmieren <strong>mit</strong> Klassen . . . . . . . . . . 93<br />
10.2 Klasse für elektronische Schaltungen . . . . . 97<br />
10.3 Platinen ätzen . . . . . . . . . . . . . . . . . . 101<br />
10.3.1 Material . . . . . . . . . . . . . . . . . 102<br />
10.3.2 Belichtungsmaske . . . . . . . . . . . . 103<br />
10.3.3 Belichtung . . . . . . . . . . . . . . . . 104<br />
10.3.4 Entwicklung . . . . . . . . . . . . . . . 106<br />
10.3.5 Ätzen . . . . . . . . . . . . . . . . . . 107<br />
10.3.6 Abschlussarbeiten . . . . . . . . . . . . 109<br />
11 Schaltalgebra 110<br />
11.1 Boolesche Algebra . . . . . . . . . . . . . . . . 110<br />
11.2 TTL . . . . . . . . . . . . . . . . . . . . . . . 113<br />
11.3 Flip-Flop . . . . . . . . . . . . . . . . . . . . . 115<br />
III Mikrocontroller 118<br />
12 Wurzeln 119<br />
12.1 Mikrocontroller . . . . . . . . . . . . . . . . . 122<br />
12.1.1 AVR Mikrocontroller . . . . . . . . . . 123
INHALTSVERZEICHNIS 10<br />
13 Aufbau des Systems 129<br />
13.1 Software . . . . . . . . . . . . . . . . . . . . . 130<br />
13.2 Programmier-Interface . . . . . . . . . . . . . 132<br />
13.2.1 Centronics Variante . . . . . . . . . . 132<br />
13.2.2 RS232 Variante . . . . . . . . . . . . . 136<br />
13.2.3 USB Variante . . . . . . . . . . . . . . 139<br />
13.3 Kabel . . . . . . . . . . . . . . . . . . . . . . 145<br />
13.4 Mikrocontroller-Board . . . . . . . . . . . . . 146<br />
13.4.1 Programmierschnittstelle . . . . . . . 146<br />
13.4.2 Erster Dialog . . . . . . . . . . . . . . 149<br />
13.4.3 Erste Baustufe . . . . . . . . . . . . . 153<br />
13.4.4 Netzteil . . . . . . . . . . . . . . . . . 168<br />
13.4.5 Oszillator . . . . . . . . . . . . . . . . 169<br />
13.4.6 RS232 Schnittstelle . . . . . . . . . . . 171<br />
13.4.7 Taster . . . . . . . . . . . . . . . . . . 191<br />
13.4.8 Buzzer . . . . . . . . . . . . . . . . . . 192<br />
13.4.9 Display . . . . . . . . . . . . . . . . . 195<br />
14 Erste Experimente 199<br />
14.1 RS232-Schnittstellen-Tester . . . . . . . . . . 199
INHALTSVERZEICHNIS 11<br />
14.2 Frequenzgenerator . . . . . . . . . . . . . . . 201<br />
14.3 Voltmeter . . . . . . . . . . . . . . . . . . . . 202<br />
14.4 Quarzuhr . . . . . . . . . . . . . . . . . . . . 204<br />
15 Weiterführende Experimente 207<br />
15.1 Messen . . . . . . . . . . . . . . . . . . . . . . 208<br />
15.2 Steuern . . . . . . . . . . . . . . . . . . . . . 208<br />
15.3 Regeln . . . . . . . . . . . . . . . . . . . . . . 208<br />
15.4 Solartechnik . . . . . . . . . . . . . . . . . . . 209<br />
15.5 Robotik . . . . . . . . . . . . . . . . . . . . . 209<br />
15.6 Fernwirken . . . . . . . . . . . . . . . . . . . . 209<br />
A Stolpersteine 211<br />
A.1 Reset und Brown-out . . . . . . . . . . . . . . 211<br />
A.2 Stackfault . . . . . . . . . . . . . . . . . . . . 212<br />
A.3 volatile . . . . . . . . . . . . . . . . . . . . . . 213<br />
A.4 Interrupts . . . . . . . . . . . . . . . . . . . . 213<br />
A.5 PORTx . . . . . . . . . . . . . . . . . . . . . 214<br />
A.6 Watchdog . . . . . . . . . . . . . . . . . . . . 214<br />
A.7 UCSRC . . . . . . . . . . . . . . . . . . . . . 214
INHALTSVERZEICHNIS 12<br />
A.8 Besonderheiten einzelner Modelle . . . . . . . 215<br />
A.8.1 AT90S1200 . . . . . . . . . . . . . . . 215<br />
A.8.2 AT90S2343 . . . . . . . . . . . . . . . 215<br />
A.8.3 Vom AT90S4433 zum ATmega8 . . . . 215<br />
B Technische Daten 217<br />
C Nachschlagebereich 219<br />
C.1 Assembler . . . . . . . . . . . . . . . . . . . . 219<br />
C.2 Programmiersprache C . . . . . . . . . . . . . 224<br />
C.3 Runtime . . . . . . . . . . . . . . . . . . . . . 226<br />
D Programm pcb 228<br />
E Skalieren des Systems 243<br />
F Die Datei Mikrocontroller.tgz 246<br />
G Rechtliches 248<br />
H Helfer 250
Teil I<br />
Einführung in die<br />
<strong>Computertechnik</strong><br />
13
Kapitel 1<br />
Entwicklung der<br />
Computer<br />
Betrachtet man die Entwicklung moderner Computer, so fallen<br />
Parallelen zum Auto auf. Beide sind Industrieprodukte <strong>mit</strong><br />
rasanter Entwicklung in jüngster Vergangenheit. Ich will hier<br />
nicht auf die Erfindung des Rades bzw. der Zahlen eingehen,<br />
sondern kurz den Weg zum Konsumartikel aufzeichnen.<br />
Die ersten Automobile konnten nur von Leuten <strong>mit</strong> beträchtlichem<br />
Fachwissen genutzt werden, wobei die Nutzung primär<br />
Selbstzweck war. Glatte Straßen gab es noch nicht. Nach der<br />
Gruppe der Pioniere kamen die Militärs, die <strong>mit</strong> ihren Kriegen<br />
die Entwicklung und industrielle Fertigung beschleunigten.<br />
In der Folgezeit waren Automobile elitären Schichten<br />
vorbehalten. Da immer mehr gefertigt wurde, konnte langsam<br />
die Bevölkerung <strong>mit</strong> Autos versorgt werden. Zwingen-<br />
14
KAPITEL 1. ENTWICKLUNG DER COMPUTER 15<br />
de Voraussetzung war, ein Automobil für jeden bedienbar zu<br />
machen. Die Automobiltechnik ist geschickt hinter dem Armaturenbrett<br />
verpackt. Die heutige Führerscheinausbildung<br />
beschäftigt sich primär <strong>mit</strong> dem Umgang der Verkehrsteilnehmer<br />
untereinander.<br />
Im zweiten Weltkrieg waren Computer zur Dechiffrierung von<br />
Nachrichten von hoher Bedeutung. Danach übernahmen sie<br />
wichtige Aufgaben in Industrie und Forschung, umgeben von<br />
Spezialisten. Mit dem Beginn der Massenfertigung in den 70er<br />
und 80er Jahren des letzten Jahrhunderts wurden naiv bedienbare<br />
Programmoberflächen notwendig. Heute ist es üblich<br />
und chic, Computer zu nutzen, ohne zu wissen, wo<strong>mit</strong> man<br />
eigentlich arbeitet. Die Technik ist hinter bunten Benutzeroberflächen<br />
verborgen, so komplex, dass manchmal der Eindruck<br />
entsteht, die Entwickler könnten den vollen Überblick<br />
nicht mehr behalten.<br />
Bei einem Projekt <strong>mit</strong> <strong>Mikrocontrollern</strong> erkannte ich einen<br />
meiner ersten Mikrocomputer wieder: KIM 1, eine Platine<br />
<strong>mit</strong> 8Bit-Prozessor, 2 KByte RAM (flüchtiger Speicher), 1<br />
KByte ROM (permanenter Speicher), Kassettenrecorder- und<br />
Fernschreiberinterface. Diese Platine, so groß wie ein heutiges<br />
PC-Motherboard, war im Jahre 1975 der Vorgänger des PET-<br />
Mikrocomputers der Firma Commodore. Die PC-Pioniere haben<br />
<strong>mit</strong> derartiger Hardware sogar Schach gespielt (und noch<br />
gewonnen). Jedenfalls haben sie dabei viel über Computer gelernt.<br />
Ein heutiger Mikrocontroller bietet im Vergleich bei ungefähr<br />
1 Promille an Gewicht, Preis und Energieverbrauch ähnlichen
KAPITEL 1. ENTWICKLUNG DER COMPUTER 16<br />
Hardwareumfang. Warum also nicht in die Tiefen der <strong>Computertechnik</strong><br />
eintauchen? Ein üblicher PC ersetzt den Fernschreiber,<br />
an den früher derartige Platinen angeschlossen wurden.<br />
Vor der Praxis steht noch ein wenig Theorie.
Kapitel 2<br />
Zahlensysteme<br />
Typisch für Computer ist, dass alles auf Zahlen abgebildet<br />
wird. Für einen normal denkenden Menschen erscheint das<br />
erst einmal ungewöhnlich. Im Laufe dieses Kurses wird jedoch<br />
langsam klar werden, wie das geht. Zur Rechtfertigung möchte<br />
ich nur darauf hinweisen, dass Mathematiker es als bewiesen<br />
betrachten, dass man alles Berechenbare letztendlich in einer<br />
einzigen Zahl unterbringen kann.<br />
Als die Menschen zu zählen anfingen, arbeiteten sie erst einmal<br />
<strong>mit</strong> Strichlisten. Das wurde zu aufwändig. Man entwickelte<br />
das Dezimalsystem 1 , hatte man doch 10 Finger zum Rechnen.<br />
Computer haben keine Finger, und so richtig zu funktionieren<br />
1 lateinisch: decem - zehn<br />
17
KAPITEL 2. ZAHLENSYSTEME 18<br />
begannen sie erst, als man stattdessen zwei Zustände in den<br />
Mittelpunkt stellte:<br />
0 Spannung nicht vorhanden<br />
1 Spannung vorhanden<br />
In Erinnerung an die Finger nannte man das Digitaltechnik 2 .<br />
Wie kann man aber statt <strong>mit</strong> zehn Ziffern nur <strong>mit</strong> zwei Spannungen<br />
rechnen?<br />
Dazu betrachte man den Aufbau unserer Zahlen, zum Beispiel<br />
4711, einmal genauer: Sie besteht aus einer Aneinanderreihung<br />
von Ziffern. Entscheidend für den Wert der Zahl ist<br />
der Stellenwert der Ziffern. In den sogenannten polyadischen<br />
Zahlensystemen [Formeln] berechnet sich der Wert einer Zahl<br />
Z folgendermaßen:<br />
Z = � ak · B k wobei B ≥ 2; 0 ≤ ak < B; ak, B ∈ N<br />
Unser Beispiel:<br />
also:<br />
Z = 4711; B = 10; a3 = 4; a2 = 7; a1 = 1; a0 = 1<br />
2 lateinisch: digitus - der Finger
KAPITEL 2. ZAHLENSYSTEME 19<br />
4711 = 4 · 10 3 + 7 · 10 2 + 1 · 10 1 + 1 · 10 0<br />
4711 = 4 · 1000 + 7 · 100 + 1 · 10 + 1 · 1<br />
4711 = 4000 + 700 + 10 + 1<br />
Tipps: Das Sigma � steht für lange Summen. Jede Zahl außer<br />
Null wird <strong>mit</strong> Null potenziert zu 1. Wenn das Verständnis von<br />
oben nach unten hakt, versuche man es von unten nach oben.<br />
Wichtig ist die Zahl B, auch Basis genannt, die in unserer<br />
gewohnten dezimalen Rechenwelt eben 10 ist.<br />
Verwendet man im polyadische Zahlensystem für B den Wert<br />
2, so bleiben die Ziffern 0 und 1 übrig. Das Rechensystem<br />
funktioniert aber immer noch, wie ein weiteres Beispiel demonstrieren<br />
soll:<br />
also:<br />
Z = 10102; B = 2; a3 = 1; a2 = 0; a1 = 1; a0 = 0<br />
10102 = 1 · 2 3 + 0 · 2 2 + 1 · 2 1 + 0 · 2 0<br />
10102 = 1 · 810 + 0 + 1 · 210 + 0<br />
10102 = 1010<br />
Tipps: 10102 liest man: Eins Null Eins Null zur Basis 2. Werden<br />
wie oben Zahlen gemischt, so muss die Basis ausdrücklich<br />
angegeben werden.
KAPITEL 2. ZAHLENSYSTEME 20<br />
Für B = 2 nennt man die Zahlen Dualzahlen oder Binärzahlen.<br />
Computer ordnen einfach den beiden Ziffern Spannungen<br />
zu. Eine duale Ziffer bezeichnet man auch als ein Bit 3 .<br />
Fasst man 4 Bits zusammen, so kann man Werte zwischen<br />
0..15 bezeichnen. Weist man diesen Werten die 16 Ziffern 0..9<br />
und A..F 4 zu, so hat man Hexadezimalzahlen, die manchmal<br />
auch Sedezimalzahlen genannt werden. B ist in diesem Fall<br />
16. Im Computerjargon nennt man eine solche Ziffer, die ein<br />
halbes Byte darstellt, auch Nibble.<br />
3Die Informationstheorie kommt bei der Definition eines Bits ohne<br />
Zahlen aus.<br />
4A..F werden hier als Ziffern betrachtet!
KAPITEL 2. ZAHLENSYSTEME 21<br />
Zahlensysteme<br />
B=2 B=8 B=10 B=16<br />
0 0 0 0<br />
1 1 1 1<br />
10 2 2 2<br />
11 3 3 3<br />
100 4 4 4<br />
101 5 5 5<br />
110 6 6 6<br />
111 7 7 7<br />
1000 10 8 8<br />
1001 11 9 9<br />
1010 12 10 A<br />
1011 13 11 B<br />
1100 14 12 C<br />
1101 15 13 D<br />
1110 16 14 E<br />
1111 17 15 F<br />
: : : :<br />
Alle Werte in einer Zeile der Tabelle der Zahlensysteme bezeichnen<br />
genau die selbe Zahl!<br />
Fasst man wiederum 2 Hexadezimalziffern zusammen, also 8<br />
Bit, so hat man jene Bytes, welche man von der PC-Werbung<br />
kennt. In den technischen Daten findet man Kilo- (1000, oft<br />
auch 1024 Bytes), Mega (1000 Kilobytes), Giga (1000 Megabytes)<br />
und Terabytes (1000 Gigabytes).<br />
Bytes haben deshalb eine hohe Bedeutung, da Buchstaben
KAPITEL 2. ZAHLENSYSTEME 22<br />
Bytes zugeordnet werden, früher als ASCII- oder EBSDIC-,<br />
heute als den ASCII- verwandten ISO-Codes.<br />
ISO-8859-1 Code-Tabelle<br />
0 1 2 3 4 5 6 7 8 9 A B C D E F<br />
0<br />
1<br />
2 ! ” # $ % & ’ ( ) ∗ + , - . /<br />
3 0 1 2 3 4 5 6 7 8 9 : ; < = > ?<br />
4 @ A B C D E F G H I J K L M N O<br />
5 P Q R S T U V W X Y Z [ \ ] ˆ<br />
6 ‘ a b c d e f g h i j k l m n o<br />
7<br />
8<br />
9<br />
p q r s t u v w x y z { | } ˜<br />
A ¡ ? £ ? ? S ˇ § ˇs c○ ā ≪ ¬ ? ?<br />
−<br />
B<br />
◦<br />
±<br />
2 3<br />
´ µ ¶ · ˇz<br />
1<br />
o<br />
¯ ≫ 1 C À Á Â Ã Ä ˚A Æ Ç È É Ê Ë<br />
4<br />
Ì<br />
1<br />
2<br />
Í<br />
3<br />
4<br />
Î<br />
¿<br />
Ï<br />
D<br />
E<br />
–D<br />
à<br />
Ñ<br />
á<br />
Ò<br />
â<br />
Ó<br />
ã<br />
Ô<br />
ä<br />
Õ<br />
˚a<br />
Ö<br />
æ<br />
×<br />
ç<br />
Ø<br />
è<br />
Ù<br />
é<br />
Ú<br />
ê<br />
Û<br />
ë<br />
Ü<br />
ì<br />
Y´ í<br />
bl î<br />
ß<br />
ï<br />
F ∂ ñ ò ó ô õ ö ÷ ø ù ú û ü ´y bl ¨y<br />
Beispiel: Das Zeichen ? ist der Zahl 3F16 zugeordnet. In der<br />
Programmiersprache C schreibt man auch 0x3F oder 0x3f.<br />
Die anderen Fragezeichen vertreten Buchstaben, die nicht gedruckt<br />
werden konnten.<br />
Die Werte von 0x00 bis 0x1f und 0x7f bis 0x9f werden nicht<br />
für Buchstaben, sondern für Befehle an verschiedene Geräte<br />
genutzt. So interpretieren verschiedene Geräte den Wert 0x0a<br />
dergestalt, dass der nächste Buchstabe am Zeilenanfang ausgegeben<br />
werden soll.<br />
Da Computer sehr häufig Buchstaben und Texte verarbeiten<br />
müssen, werden die meisten Datenwege 8Bit oder n · 8Bit<br />
breit ausgelegt.<br />
Es stellt sich jetzt die Frage, wie kann ein Computer eine Zahl<br />
von einem Buchstaben unterscheiden. Der Fachmann würde
KAPITEL 2. ZAHLENSYSTEME 23<br />
sagen, der Computer erkennt das am Kontext. Übertragen<br />
entspricht es der Frage:<br />
Woran kann ein Mensch die Ziffer Null vom Buchstaben O<br />
unterscheiden?<br />
In der Programmiersprache C wird diese Frage genauer betrachtet.<br />
Abbildung 2.1: Direkter Nachfahre des Abakus.<br />
Um noch einmal auf die Geschichte zurückzukommen: Es gab<br />
bereits in der Antike funktionierende Rechenmaschinen, heute<br />
als Abakus bekannt.
KAPITEL 2. ZAHLENSYSTEME 24<br />
Vertiefung: Warum kann man einen Brief als Zahl zur Basis<br />
256 ansehen?<br />
Herr Jubel feiert seit seinem 30. Geburtstag alle fünf Jahre<br />
den 50. Wie macht er das?
Kapitel 3<br />
Rechnerarchitektur<br />
3.1 von-Neumann-Architektur<br />
Moderne Rechner gehen im Wesentlichen auf die theoretischen<br />
Arbeiten von Burks, Goldstine und von Neumann aus den<br />
Jahren 1946/47 zurück. Man spricht deshalb häufig von von-<br />
Neumann-Architektur. Es wurde ein universeller Rechenautomat<br />
postuliert, der sich in vier Teile gliedert:<br />
• Speicherwerk<br />
• Steuerwerk (auch Leitwerk genannt) <strong>mit</strong> Befehlszähler<br />
• Rechenwerk<br />
• Ein-/Ausgabewerk<br />
25
KAPITEL 3. RECHNERARCHITEKTUR 26<br />
Das Speicherwerk ist geeignet, duale Zahlen zu speichern. Jede<br />
Speicherstelle besitzt eine eindeutige Adresse. Die Adressen<br />
sind natürliche Zahlen in aufsteigender Reihenfolge.<br />
Grundsätzlich enthält das Speicherwerk Programm- und Datenworte.<br />
Für die Verarbeitung der Programmworte ist das<br />
Steuerwerk zuständig. Hierzu besitzt es einen Zeiger, Befehlszähler<br />
1 genannt. Der Befehlszähler zeigt auf den aktuell<br />
gültigen Programmbefehl. Nach Bearbeitung des Befehls gibt<br />
es drei Varianten:<br />
• Der Befehlszähler zeigt auf den nächsten Befehl.<br />
• Der Befehlszähler zeigt auf einen anderen Befehl.<br />
• Abhängig vom Ausgang der Bearbeitung des Befehls<br />
zeigt der Befehlszähler auf den nächsten oder einen anderen<br />
Befehl.<br />
Für die Verarbeitung von Datenworten ist das Rechenwerk 2<br />
zuständig. Es kennt logische Verknüpfungen und höhere Operationen<br />
wie Addieren und Subtrahieren. Aufwendige Rechenwerke<br />
können sogar Multiplizieren und Dividieren. Gesteuert<br />
wird das Rechenwerk vom Steuerwerk, das hierzu das Programmwort<br />
analysiert.<br />
Programmbefehle kann man in drei Gruppen einteilen:<br />
1 Im Englischen Program Counter, häufig als PC abgekürzt.<br />
2 Im Englischen oft ALU genannt, die Abkürzung für Arithmetic and<br />
Logical Unit.
KAPITEL 3. RECHNERARCHITEKTUR 27<br />
• Befehle für das Kopieren von Daten zwischen Speicher-,<br />
Rechen- und Ein-/Ausgabewerk.<br />
• Befehle, die Berechnungen im Rechenwerk anstoßen.<br />
• Befehle zum Ändern des Befehlszählers. Die anderen Befehle<br />
zeigen nach der Bearbeitung auf den nächsten Befehl.<br />
Das Eingabewerk besorgt Aufgaben, die im Speicher abgelegt<br />
werden, das Ausgabewerk präsentiert die Ergebnisse.<br />
Für einen derartig aufgebauten Rechner kann man zeigen,<br />
dass er jedes berechenbare Problem lösen kann. Derartige<br />
Überlegungen übergehen die Grenzen von Zeit- und Materialaufwand.<br />
Hierzu sei bemerkt, dass der Preis für ein Speicherbyte<br />
Anfang der 70er Jahre noch bei umgerechnet einem Euro<br />
lag, dass die praktische Bewertung von Zeit- und Materialaufwand<br />
sich ständig verändert. Wissenschaftler und Techniker<br />
neigen häufig dazu, bei ihren Überlegungen einen Aspekt getrennt<br />
zu betrachten. Als Arbeitsmethode ist das sinnvoll, als<br />
Lebensweg fatal.<br />
Heutige Mikroprozessoren und Mikrocomputer haben Steuerwerk<br />
und Rechenwerk in einem Baustein. Mikrocontroller<br />
beherbergen darin sogar noch Ein-/Ausgabewerk, inzwischen<br />
auch das Speicherwerk. Ferner sind Register, Stackpointer<br />
(SP) und Statusregister 3 (SR) dazu gekommen, was Geschwindigkeit<br />
und Programmiertechnik entgegenkommt.<br />
3 Manchmal wird statt Statusregister Programm-Status-Wort (PSW)<br />
verwendet.
KAPITEL 3. RECHNERARCHITEKTUR 28<br />
3.2 Register<br />
Um Daten im Rechenwerk zu verknüpfen, benötigt dieses Zwischenspeicher,<br />
manchmal Akkumulatoren oder Akku genannt.<br />
Diese sind gegenüber dem Speicherwerk schneller. Da alle Teilberechnungen<br />
<strong>mit</strong> wenig Daten auskommen, besitzen moderne<br />
CPUs 4 nicht nur einen Akku, sondern mehrere Speicherplätze<br />
im Rechenwerk, Register genannt. Manchmal spricht<br />
man auch vom Registerwerk. Den Aufbau des Registerwerks,<br />
wie Namen und Funktion der Register, nennt man Registermodell.<br />
Das Registermodell ist einer der wesentlichen Unterschiede<br />
verschiedener CPU-Typen.<br />
3.3 Stackpointer<br />
Der Stackpointer ist ein Zeiger in den Datenspeicher. Die<br />
indirekt über den Stackpointer durchgeführten Speicherzugriffe<br />
arbeiten nach dem FiFo 5 -Prinzip. So lassen sich bequem<br />
Rücksprungadressen von Unterprogrammen als auch<br />
ausschließlich in diesen Unterprogrammen verwendete lokale<br />
Daten speichern. Einige CPU-Befehle wie Unterprogrammsprünge<br />
nutzen den Stackpointer. Höhere Programmiersprachen<br />
bauen besonders stark auf der Verwendung des Stackpointers<br />
auf.<br />
4Central Processing Unit, eine Bezeichnung, die Steuer- und Rechenwerk<br />
zusammenfasst.<br />
5FiFo steht für first in - first out. Ein anderes Prinzip ist last in - first<br />
out, LiFo.
KAPITEL 3. RECHNERARCHITEKTUR 29<br />
3.4 Statusregister<br />
Im Statusregister merkt sich die ALU das logische Ergebnis<br />
der letzen Berechnung. Die Bits des Statusregister zeigen an,<br />
ob das Ergebnis Null war, ob es negativ war, ob ein Übertrag<br />
statt fand usw. Hauptsächlich werden diese Werte für bedingte<br />
Programmsprünge verwendet.<br />
3.5 Harvard-Architektur<br />
Die zuvor beschriebene, in Princeton entwickelte von-<br />
Neumann-Architektur arbeitet <strong>mit</strong> einem Speicherwerk, das<br />
sowohl Programm als auch Daten in einem Speicher beherbergt.<br />
Bei der Harvard Architektur, der der in diesem<br />
Buch verwendete AVR Mikrocontroller entspricht, werden<br />
Programm und Daten in getrennten Speichern gehalten. Derartige<br />
Rechner sind robuster.<br />
3.6 CISC und RISC<br />
Nach den vorherigen Rezepten wurden viele Computer entwickelt.<br />
Dabei haben sich zwei Lager gebildet. CISC 6 kennen<br />
Befehle komplexer Art. Sie haben eine große, meist variable<br />
Wortbreite. Die Befehle haben sehr unterschiedliche<br />
Ausführungszeiten. Pentiums und Verwandte gehören dazu.<br />
6 Complex Instruction Set Computers
KAPITEL 3. RECHNERARCHITEKTUR 30<br />
RISC 7 haben einen schlanken Befehlsvorrat, feste Befehlslängen<br />
und Bearbeitungszeiten. Die in diesem Buch verwendeten<br />
AVR CPUs gehören zu dieser Gruppe.<br />
Übrigens verhält es sich nicht so, dass kleine Mikrocontroller<br />
RISC und große Mikroprozessoren CISC sind. Hier gibt es<br />
keinen Zusammenhang. Zum Beispiel sind Sparcs, die CPUs<br />
die in den Rechnern der Firma Sun arbeiten, RISC. Der Urahn<br />
der Mikrocontroller, der 8048 der Firma Intel, ist ein CISC.<br />
Manchmal ist es schwierig, eine CPU konkret einzuordnen.<br />
7 Reduced Instruction Set Computers
Kapitel 4<br />
Computerschnittstellen<br />
Fernschreiber, elektrische Schreibmaschinen, CD-Spieler,<br />
Fernseher oder Kameras waren ursprünglich nicht für Computer<br />
gedacht. Die Ein-/Ausgabewerke der Computer werden<br />
meist von anderen Firmen gebaut als die Computer selbst. Da<strong>mit</strong><br />
Produkte verschiedener Firmen zusammen funktionieren,<br />
müssen Schnittstellen vereinbart werden. Von diesen gibt es<br />
inzwischen unüberschaubar viele, meist <strong>mit</strong> netten Abkürzungen<br />
bedacht: RS232 RS485 VGA GDI PCI AGP I2C PS2 IDE<br />
ATAPI SCSI PCMCIA USB JETEC ... 1<br />
Technologisch kann man Schnittstellen in Gruppen einteilen.<br />
Es gibt<br />
• serielle – parallele Verbindungen<br />
1 Da fällt mir gerade ein Gesellschaftsspiel ein: Nenne eine Computerschnittstelle<br />
und lass sie von einem Mitspieler erklären.<br />
31
KAPITEL 4. COMPUTERSCHNITTSTELLEN 32<br />
• synchrone – asynchrone Verbindungen<br />
• unidirektionale – bidirektionale Verbindungen<br />
• Punkt zu Punkt Verbindung – Sternverbindung – Busverbindungen<br />
Man sollte noch zwischen norm- und nicht normgerecht verwendeten<br />
Verbindungen unterscheiden.<br />
Drei sehr wichtige Schnittstellen werden etwas tiefer behandelt,<br />
nicht nur, weil sie später tatsächlich verwendet werden.<br />
4.1 Centronics<br />
Diese eigentlich nur für Druckwerke gedachte Schnittstelle<br />
wurde vom gleichnamigen Drucker-Hersteller eingeführt.<br />
Wahrscheinlich aus historischen Gründen hat diese Schnittstelle<br />
einen Namen, der keine Abkürzung darstellt. Die Firma<br />
Centronics baute sehr schnelle mechanische Druckwerke, zuletzt<br />
Nadeldrucker. Zwar gibt es, glaube ich, keine Centronics-<br />
Drucker mehr, aber noch viele Druckermodelle <strong>mit</strong> dieser<br />
Schnittstelle.<br />
Es ist eine parallele, ehemals unidirektionale Schnittstelle <strong>mit</strong><br />
vielen Quittungssignalen. In den letzten Jahren wurden weitere<br />
Möglichkeiten zum Beispiel für die Nutzung von Scannern<br />
eingeführt. Vor diesen Erweiterungen war die Schnittstelle<br />
stabil und zuverlässig. Über Centronics angeschlossene
KAPITEL 4. COMPUTERSCHNITTSTELLEN 33<br />
Drucker funktionierten reibungslos. Die Kabel haben jedoch<br />
über 20 Leitungen. Die Reichweite ist auf ca. 10 m begrenzt.<br />
Die Funktionsweise ist im Prinzip synchron. Nachdem der<br />
Rechner die 8 Bit eines Zeichens auf 8 Datenleitungen eingestellt<br />
hat, signalisiert er dem Drucker <strong>mit</strong> dem, Strobe genannten,<br />
Signal, dass das Zeichen bereit ist. Der Drucker verarbeitet<br />
das Zeichen und antwortet auf der Leitung Acknowledge,<br />
dass er fertig ist. Ferner gibt es Leitungen für Paper<br />
out und andere Fehler.<br />
Die Anwendungen dieser Schnittstelle werden <strong>mit</strong>tlerweile<br />
durch USB ersetzt.<br />
Auch die Kommunikation <strong>mit</strong> unserem Mikrocontroller<br />
missbraucht diese Schnittstelle. Der ursprüngliche Sinn<br />
der Leitungen wird nicht angewendet. Da aber die PC-<br />
Architektur der Software ein Durchgreifen auf die einzelnen<br />
Leitungen erlaubt, eignen sich Centronicsschnittstellen dafür<br />
hervorragend.<br />
Am PC-Gehäuse ist diese Schnittstelle als DB-25 Buchse erkennbar.<br />
4.2 RS-232<br />
Dies ist eine asynchrone symmetrische bidirektionale Schnittstelle<br />
aus den 60er Jahren. Manchmal wird sie auch V24 genannt.<br />
Unter diesem Namen wurde die Schnittstelle für den<br />
Telefonbereich genormt.
KAPITEL 4. COMPUTERSCHNITTSTELLEN 34<br />
In vielen Dingen ist sie technisch überholt. Ursprünglich ersetzte<br />
sie die langsame Fernschreiberschnittstelle 2 zum Anschluß<br />
von Dialogschnittstellen (engl. Terminals) in Rechenzentren.<br />
Da die Verbindungsleitungen nur etwa Raumlänge<br />
haben konnten, wurden <strong>mit</strong> Hilfe von Modems beliebig lange<br />
Telefonverbindungen realisiert. So sind externe Modems<br />
heute noch die klassische Anwendung dieser Schnittstelle, deren<br />
Tage wegen ISDN und DSL gezählt werden. Im Laufe ihres<br />
langen Lebens wurde sie für fast alle Peripheriegeräte wie<br />
Drucker, Plotter, Maus, Kamera eingesetzt. Heutige Rechner<br />
haben oft noch zwei von diesen Schnittstellen eingebaut, ein<br />
Ersatz durch USB-Adapter wird aber üblich.<br />
Auch der hier verwendete Mikrocontroller enthält in seinem<br />
Ein-/Ausgabewerk etliche Vorkehrungen zur Unterstützung<br />
dieser Schnittstelle. Ein einziger gängiger Baustein zur elektrischen<br />
Pegelwandlung genügt für die Anpassung an die normgerechte<br />
Schnittstelle.<br />
Die Norm sah 25-polige Steckverbinder vor, die bei Modem<br />
und Computer so unterschiedlich belegt waren, dass eine einszu-eins<br />
Verbindung möglich war. Dies ist einer der möglichen<br />
Fallstricke, den RS232 bietet. Bei vielen Anwendungen ist<br />
schwer zu entscheiden, welche Seite das Modem und welche<br />
den Computer vertritt.
KAPITEL 4. COMPUTERSCHNITTSTELLEN 35<br />
Abbildung 4.1: DB9-Stecker des IBM-AT<br />
4.2.1 RS232-Schnittstelle des IBM AT<br />
Zur Vereinfachung werden PCs <strong>mit</strong> auf 9 Pole reduzierten<br />
RS232-Verbindungen ausgestattet. Abbildung 4.1 zeigt die<br />
Pin-Belegung eines derartigen Steckers. Die Pins haben folgende<br />
Funktion:<br />
Pin 1, DCD, data carrier detect<br />
Das Modem hat ein Trägersignal erkannt.<br />
Dieses Signal wird von Modems verwendet.<br />
Signalrichtung: input. Spannung: positiv.<br />
Pin 2, RXD, receive data<br />
Daten werden seriell empfangen.<br />
2 Der Marktführer für Fernschreiber war in Amerika die Firma Teletype.<br />
Von deren Firmennamen leitet sich die Abkürzung TTY ab.
KAPITEL 4. COMPUTERSCHNITTSTELLEN 36<br />
Dieses Signal wird immer verwendet.<br />
Signalrichtung: input. Spannung: wechselnd.<br />
Pin 3, TXD, trans<strong>mit</strong> data<br />
Daten werden seriell gesendet.<br />
Dieses Signal wird immer verwendet.<br />
Signalrichtung: output. Spannung: wechselnd.<br />
Pin 4, DTE, data terminal ready<br />
Der Computer ist bereit, eine Verbindung einzugehen.<br />
Dieses Signal wird weniger genutzt.<br />
Signalrichtung: output. Spannung: positiv.<br />
Pin 5, GND, ground<br />
Dies ist das Massepotential, auf das sich die anderen Signale<br />
beziehen.<br />
Diese Leitung wird immer verwendet.<br />
Signalrichtung: keine. Spannung: Massepotential.<br />
Pin 6, DSR, data set ready<br />
Die Gegenstation ist bereit, eine Verbindung einzugehen.<br />
Dieses Signal wird weniger genutzt.<br />
Signalrichtung: input. Spannung: positiv.<br />
Pin 7, RTS, request to send
KAPITEL 4. COMPUTERSCHNITTSTELLEN 37<br />
Der Computer ist bereit, Daten zu empfangen.<br />
Diese Leitung wird beim sogenannten Hardware-Handshake<br />
verwendet.<br />
Signalrichtung: output. Spannung: positiv.<br />
Pin 8, CTS, clear to send<br />
Die Gegenstation ist bereit, Daten zu empfangen.<br />
Diese Leitung wird beim sogenannten Hardware-Handshake<br />
verwendet.<br />
Signalrichtung: input. Spannung: positiv.<br />
Pin 9, RI, ring indicator<br />
Das Modem hat ein Klingelsignal erkannt.<br />
Dieses Signal wird von Modems verwendet.<br />
Signalrichtung: input. Spannung: positiv.<br />
Werden PCs <strong>mit</strong>einander verbunden, so müssen bestimmte<br />
Leitungen gekreuzt werden.<br />
Neben Varianten der Verdrahtung zweier Geräte gibt es noch<br />
Varianten in der Übertragungsgeschwindigkeit, im Aufbau der<br />
Übertragungsrahmen und in der Synchronisation. Die Multiplikation<br />
dieser Möglichkeiten ergibt eine beachtliche Anzahl,<br />
die schon manchen Nutzer verzweifeln ließ.<br />
Neben den üblichen Varianten der seriellen Schnittstelle gibt<br />
es obendrein auch noch solche <strong>mit</strong> unterschiedlichen Steckern<br />
und Spannungen. Auch die Programmierschnittstelle dasa2
KAPITEL 4. COMPUTERSCHNITTSTELLEN 38<br />
zu unserem Mikrocontroller nutzt die serielle Schnittstelle des<br />
PCs ohne Rücksicht auf Konventionen, trotzdem funktioniert<br />
es in der Regel.<br />
4.2.2 Schichten<br />
Im Prinzip kann man an RS232-Verbindungen sehr schön ein<br />
Schichtenmodell studieren<br />
• Kabel und Stecker<br />
• Spannungen<br />
• Signalform und Bitsynchronisation<br />
• Synchronisation<br />
• Treiber des Betriebsystems<br />
• Anwendung<br />
Alle Schichten sind weitgehend unabhängig voneinander und<br />
arbeiten über definierte Schnittstellen <strong>mit</strong>einander. Die Analyse<br />
eines Systems wird wiederum schichtenweise durchgeführt:<br />
• Ist das Kabel in Ordnung, stimmt die Belegung der<br />
Steckkontakte?
KAPITEL 4. COMPUTERSCHNITTSTELLEN 39<br />
• Sind die Spannungspegel richtig?<br />
• Stimmen Geschwindigkeit und Rahmenaufbau (Anzahl<br />
der Daten-, Prüf- und Stopbits)?<br />
• Welche Synchronisation wird verwendet?<br />
• Treiber geladen? Gerätename richtig?<br />
• Anwendung installiert?<br />
Besonders verwirrend ist die Synchronisation. Historisch sind<br />
drei Grundformen gewachsen:<br />
Hardware Handshake: Synchronisation <strong>mit</strong> Hilfe der<br />
Quittungsleitungen. Am wichtigsten sind CTS und<br />
RTS.<br />
Software Handshake: Synchronisation durch Steuerzeichen<br />
im Datenstrom. Meist werden ctrl-S 3 für Stop<br />
und ctrl-Q für Weiter verwendet. Diese Synchronisation<br />
funktioniert sogar in der shell.<br />
kein Handshake: Beide Partner sind so schnell, dass eine<br />
Synchronisation überflüssig ist.<br />
3 Die Eingabe dieses Steuerzeichens ist nach wie vor möglich. Man läßt<br />
sich einen sehr langen Text durch das Programm cat anzeigen. Durch<br />
gleichzeitiges Drücken der Tasten Strg und S wird die Anzeige angehalten,<br />
<strong>mit</strong> Strg und Q geht es weiter. Dies ist ein Relikt aus der Zeit,<br />
in der an Computer-Terminals <strong>mit</strong> RS232-Schnittstellen angeschlossen<br />
wurden.
KAPITEL 4. COMPUTERSCHNITTSTELLEN 40<br />
Teilweise werden die Synchronisationsarten bunt gemischt,<br />
weshalb sehr häufig Brücken in die Kabel eingebaut werden.<br />
CTS <strong>mit</strong> RTS und DSR <strong>mit</strong> DTR <strong>mit</strong> DCD sind übliche<br />
Brücken.<br />
4.3 USB<br />
USB ist eine moderne asynchrone serielle bidirektionale<br />
Schnittstelle <strong>mit</strong> Bus-Charakter. Bei der Entwicklung wurde<br />
vorgesehen, die meisten tradionellen Schnittstellen auf USB<br />
abbilden zu können. USB hat nur vier Leitungen, von denen<br />
zwei sogar eine 5 V Stromversorgung bis zu 500 mA übernehmen.<br />
Die beiden anderen verdrillten Leitungen übertragen ein<br />
serielles Signal, indem die Spannungen zwischen 0 V und 3,3 V<br />
hin und hergeschaltet werden. Jede Leitung überträgt das Gegenteil<br />
der anderen. Sie werden D+ und D- genannt.<br />
Da<strong>mit</strong> bis zu 128 Geräte in einer baumartigen Verdrahtung<br />
zuletzt über ein Kabel kommunizieren können, ist ein<br />
aufwändiges Protokoll für die Verteilung von Ressourcen und<br />
Adressen notwendig. Letztendlich befindet sich hinter jedem<br />
USB-Stecker ein eigener Mikrocontroller <strong>mit</strong> speziellen USB-<br />
Fähigkeiten. Für den Anschluß von RS232 und Centronics<br />
gibt es fertige Adaptergeräte, die zwischen alt und neu ver<strong>mit</strong>teln.<br />
Während bei RS232 noch viel Know-How vom Anwender erwartet<br />
wurde, funktioniert USB oder auch nicht. Die Nutzung<br />
der USB-Schnittstelle für eigene Experimente ohne zu-
KAPITEL 4. COMPUTERSCHNITTSTELLEN 41<br />
gekaufte Soft- und Hardware ist in der Regel ausgeschlossen.<br />
Die auf der USB-Homepage [usb] erhältliche Beschreibung der<br />
Schnittstelle enthält fast 600 Seiten.<br />
Die Wiener Firma Objective Development [obdev] hat einen<br />
USB-Treiber für Mikrocontroller ins Internet gestellt. Dieser<br />
Treiber ermöglichte die Entstehung einer Programmierhardware<br />
<strong>mit</strong> USB-Schnittstelle, wie sie im dritten Teil des Buches<br />
noch vorgestellt wird.
Kapitel 5<br />
Kurzeinführung in Linux<br />
Auch wenn der Aufbau der Hardware in diesem Buch <strong>mit</strong><br />
beschrieben wird, liegt der eigentliche Schwerpunkt bei der<br />
Entwicklung der Programme, also der Software. Zum Erzeugen<br />
der Programme braucht man wiederum Programme und<br />
diese brauchen wieder ein Programmsystem, Betriebssystem<br />
genannt.<br />
Dieses Projekt ist über eine Reihe von Schichten verteilt, die<br />
wie ein Obstkuchen aufeinander aufbauen: Mürbeteig, Marmelade,<br />
Biskuit, Obst, Guss, Sahne. Ich hoffe, der nächste<br />
Bäcker hat noch auf.<br />
Unser Projekt ist wie folgt aufgebaut:<br />
• PC Hardware<br />
42
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 43<br />
• Betriebssystem Linux<br />
• Dialogprogramm bash<br />
• Werkzeuge wie Editor, Compiler, Assembler, Linker<br />
• Mikrocontroller, Kommunikationsprogramm<br />
Wenn diese Schichten gebacken sind, kann der Mikrocontroller<br />
wiederum in Schichten geteilt werden:<br />
• Mikrocontroller Platine<br />
• Mikrocontroller Bestückung<br />
• Verbindung <strong>mit</strong> PC<br />
• Verschiedene Test-Programme<br />
Wichtig ist, dass jede Schicht ausreichend funktionieren muss,<br />
bevor die nächste Schicht darauf aufgesetzt werden kann. Der<br />
Leser sollte sich also <strong>mit</strong> jeder Schicht so vertraut machen,<br />
dass er deren Funktionsfähigkeit beurteilen kann. Vor dem<br />
Aufbau der nächsten Schicht müssen Unklarheiten durch weitergehende<br />
Studien ausgeräumt werden, sonst ist ein Erfolg<br />
so gut wie ausgeschlossen.
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 44<br />
5.1 Kern des Betriebssystems<br />
Es gibt zwei gebräuchliche Anwendungen des Begriffs Betriebssystem.<br />
Der weitergehende Begriff umfasst einen Kern<br />
als auch darüber angesiedelte Schichten von <strong>mit</strong> dem System<br />
gelieferten Dialogprogrammen und Werkzeugen.<br />
In diesem Buch soll nur der reine Kern als Betriebssystem<br />
bezeichnet werden.<br />
Zweck des Betriebssystems ist die Verteilung der verschiedenen<br />
Ressourcen, die der Computer verwaltet, an die laufenden<br />
Anwendungsprogramme. Ressourcen sind insbesondere<br />
• CPU-Zeit<br />
• RAM 1 , auch Kernspeicher 2 genannt<br />
• Plattenspeicher<br />
• Geräte (Bildschirm, Tastatur, Maus, Drucker, Modem,<br />
Netzwerk, ...)<br />
• ...<br />
1 engl.: random acesss memory, Speicher <strong>mit</strong> zufällig verteilbarem Zu-<br />
griff 2als Transistoren noch teuer waren, wurden Speicher <strong>mit</strong> kleinen Ma-<br />
gnetringen, sogenannten Kernen, aufgebaut
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 45<br />
Anwendungsprogramme sind Programmschichten, die auf<br />
dem Betriebssystem aufbauen. Diese können erweiterte Systemfunktionalitäten<br />
realisieren als auch vom Anwender gestartete<br />
Programme sein.<br />
Der Betriebssystemkern von Linux ist ein im Jahre 1991 auf<br />
Initiative des damaligen Studenten Linus Torvalds 3 im Internet<br />
entstandener Clone des Betriebssystems Unix. Auslöser<br />
war, dass die damals etablierte PC-CPU der 80386 der Firma<br />
Intel mehr bot als die damals gängigen Betriebssysteme<br />
nutzten.<br />
Unix ist ein Betriebssystem, dass aus der Welt der Rechenzentren<br />
kommt, in der mehrere Benutzer einen Computer<br />
gleichzeitig nutzen. Die relativ hohe Rechengeschwindigkeit<br />
der CPU wird in Zeitscheiben an die Nutzer verteilt. Jeder<br />
Nutzer hat das Gefühl, einen eigenen Computer zu besitzen.<br />
Da<strong>mit</strong> die Nutzer sich nicht gegenseitig stören können, wird<br />
von Unix hoher Wert darauf gelegt, die Nutzer voneinander<br />
abzuschirmen. Daraus ergeben sich Vor- und Nachteile gegenüber<br />
Betriebssystemen, die scheinbar 4 von nur einem Benutzer<br />
genutzt werden.<br />
Nachteilig ist, dass die erhöhte Sicherheit für die Nutzer unbequem<br />
ist, da an verschiedenen Stellen zusätzliche Eingaben<br />
erforderlich sind. Vorteil ist, dass unter Unix ein Absturz des<br />
3 Die Biographie von Linus Torvalds gibt es als lesenswertes Taschenbuch<br />
[Torvalds].<br />
4Da Computernutzer in der Regel Programme von mehreren Programmierern<br />
ausführen, trügt der Schein, es gebe nur einen Benutzer!
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 46<br />
Betriebssystems eine seltene Ausnahme ist. Ein Nutzer kann<br />
mehrere Programme gleichzeitig rechnen lassen.<br />
Da Unix von Anfang an einen durchdachten Ansatz verfolgt<br />
hat, sind Unverträglichkeiten im Verlauf der Weiterentwicklung<br />
selten.<br />
Linus Torvalds hat seines Geistes Kind sehr bald unter die<br />
GNU-Lizenz gestellt. Seit der Zeit hat sich ein regelrechter<br />
Markt von frei erhältlichen Unix-ähnlichen Betriebssystemen<br />
entwickelt. Für die weltweite Situation der Software war das<br />
ein entscheidender Schub in eine Richtung, die der ehemalige<br />
MIT-Mitarbeiter Richard Stallman <strong>mit</strong> der Free Software<br />
Foundation (FSF) eingeschlagen hatte.<br />
Die folgende Einführung in Linux ist knapp gehalten. Auch<br />
zum späteren Nachschlagen gut geeignet ist das Linux Anwenderhandbuch<br />
[Linux], das einen ernsthaften Einstieg in Linux<br />
gut begleitet.<br />
5.2 Bäume wachsen – Dateisysteme<br />
Ein wichtiger Punkt für den bewussten Umgang <strong>mit</strong> Computern<br />
ist das Verständnis des Dateisytems auf den Festplatten.<br />
Unter Unix wird ein Modell angewendet, welches sich Dateibaum<br />
nennt. Dateibäume bestehen vorwiegend aus zwei verschieden<br />
Typen von Objekten:
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 47<br />
Verzeichnisse: werden auch Directory oder Ordner genannt.<br />
Bei Unix dürfen für deren Benennung Worte aus<br />
fast allen Buchstaben verwendet werden, was jedoch bei<br />
zu freizügigem Umgang zu Problemen <strong>mit</strong> den Werkzeugen<br />
führen kann. Man wählt anfangs besser nur Worte, die man<br />
ganz natürlich als Namen vergeben würde.<br />
Dateien: werden auch File genannt. Namen werden wie<br />
für Verzeichnisse gebildet. Die Dateien enthalten die Daten,<br />
die unter dem Dateinamen für (vorläufig unbegrenzte Zeit)<br />
gespeichert werden.<br />
Nun gelten drei einfache Regeln:<br />
1. Ein Dateibaum hat genau einen Anfang. Dieser Anfang<br />
wird Wurzelverzeichnis oder Root-Directory genannt.<br />
Das Wurzelverzeichnis hat keinen frei wählbaren Namen,<br />
sondern heisst ,, / ”.<br />
2. Jedes Verzeichnis (inklusive Wurzelverzeichnis) darf beliebig<br />
viele Dateien und Verzeichnisse enthalten.<br />
3. Die Namen werden <strong>mit</strong> dem Zeichen / getrennt.<br />
Wem obiges System zu abstrakt ist, stelle sich eine schön gewachsene<br />
Eiche vor: Der Stamm ist das Wurzelverzeichnis, die<br />
Verzeichnisse sind die Äste, die Blätter sind die Dateien und<br />
der Benutzer ist das Eichhörnchen.
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 48<br />
Manchmal gibt es beim Verständnis des Baummodells ein kleines<br />
Problem: Bäume wachsen von unten nach oben. Wird das<br />
in Schriftform niedergelegt, geht das natürlich besser von oben<br />
nach unten, weil wir das Schreiben in dieser Richtung gewohnt<br />
sind.<br />
Dieses System wurde in einer vereinfachend modifizierten<br />
Form auch für MS-DOS und seine Töchter übernommen. Da<br />
das Internet primär in der Unix-Welt aufgewachsen ist, wird<br />
auch dort das Baummodell verwendet. Das Wurzelverzeichnis<br />
heißt dort http://, die ersten Bezeichner heißen Domain<br />
wie zum Beispiel www.google.de, die Adresse einer beliebten<br />
Suchmaschine.<br />
Dem Betriebssystemkern ist es egal, wie die Benutzer den Dateibaum<br />
wachsen lassen, solange sie die Festplattenkapazität<br />
beachten. Da<strong>mit</strong> die Unordnung nicht zu groß wird, gelten bei<br />
Linux weitere Regeln:<br />
/ Das Wurzelverzeichnis darf nur der Systemadministrator<br />
beschreiben.<br />
/bin Hier befinden sich die Programme, die manchmal auch<br />
zum Betriebssystem hinzugezählt werden. Siehe Abschnitt<br />
5.1.<br />
/sbin Programme für die Systemverwaltung<br />
/dev hier befinden sich die Geräteschnittstellen<br />
/etc Dateien zur Einstellung des Betriebsystems
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 49<br />
/home die Heimatverzeichnisse der Nutzer<br />
/lib Bibliothek von Unterprogrammen<br />
/usr wichtige Programme und Daten; ziemlich unordentlich.<br />
/usr/bin die Fortsetzung von /bin<br />
/tmp Hier darf jeder Nutzer vorübergehende, unwichtige,<br />
Dateien ablegen. In manchen Systemen werden diese<br />
später automatisch gelöscht.<br />
Es soll eindringlich darauf hingewiesen werden, dass ein sicherer<br />
Umgang <strong>mit</strong> heutigen Computern, gleich welcher Art,<br />
ein Verständnis dieses Baummodells voraussetzt. Schon eine<br />
vernünftige Planung der notwendigen Datensicherung scheitert<br />
ohne dessen Verständnis.<br />
Da es so wichtig ist, möchte ich nochmal auf das Dateisystem<br />
eingehen. Es gibt drei besondere Verzeichnisse.<br />
5.2.1 Wurzelverzeichnis<br />
Dateinamen <strong>mit</strong> / am Anfang heißen absolute Dateinamen.<br />
Sie beziehen sich auf das Wurzelverzeichnis.<br />
Man gibt den kompletten Weg durch den Dateibaum vom<br />
Wurzelverzeichnis aus an. Beispiel eines Zugriffs auf nicht im<br />
Arbeitsverzeichnis liegende Daten:<br />
grep $HOME /etc/passwd
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 50<br />
5.2.2 Heimatverzeichnis<br />
Es heißt auch Home Directory.<br />
$HOME entspricht dem Wurzelverzeichnis des Benutzers. Jedem<br />
Benutzer ist genau ein Heimatverzeichnis zugewiesen. In<br />
diesem Verzeichnis darf er seinen eigenen Teil des Dateibaums<br />
aufbauen. Un<strong>mit</strong>telbar nach der Anmeldung beim System ist<br />
das im nächsten Unterpunkt beschriebene Arbeitsverzeichnis<br />
auf das Heimatverzeichnis gesetzt.<br />
5.2.3 Arbeitsverzeichnis<br />
Dateinamen ohne / am Anfang heißen relative Dateinamen.<br />
Sie beziehen sich auf das Arbeitsverzeichnis.<br />
Das Arbeitsverzeichnis, die englische Bezeichnung ist Current<br />
Working Directory, ist das Verzeichnis, auf das sich in der<br />
Regel die Befehle des Nutzers beziehen. Falls es vorkommt,<br />
dass man den Namen des Arbeitsverzeichnisses gerade nicht<br />
weiß, da es ja variabel ist, gibt das Programm<br />
pwd<br />
(print working directory) Auskunft. Es ist sinnvoll, für getrennte<br />
Arbeiten getrennte Verzeichnisse anzulegen.<br />
Zum Wechseln des Arbeitsverzeichnisses gibt es das Programm
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 51<br />
cd<br />
(change directory). Nicht immer ist es ausreichend, Dateien<br />
im Arbeitsverzeichnis anzusprechen, da es Dateien gibt, die<br />
für verschiedene Arbeitsvorgänge angelegt werden. In diesem<br />
Fall verwendet man absolute Dateinamen.<br />
Nach meiner Beobachtung ist ein wichtiger Grund für<br />
Missverständnisse zwischen Anfängern und fortgeschrittenen<br />
Nutzern das Unwissen um die Existenz des Arbeitsverzeichnisses!<br />
5.3 GNU - Tools<br />
Richard Stallman, der bereits vorgestellte Gründer der FSF,<br />
ist der Überzeugung, dass geistige Entwicklungen zwar einen<br />
Autor haben, der als solcher auch erwähnt werden muss, die<br />
Nutzung einer Idee aber allen Menschen verfügbar gemacht<br />
werden soll.<br />
Aus dieser Überzeugung heraus entwickelte er eine Softwarelizenz,<br />
die GPL, die einen Vertrag zwischen Autor und Nutzer<br />
knüpft und die Software vor eigennützigen Interessen schützt.<br />
Die wesentlichen Vertragspunkte sind:<br />
1 Die Software darf von jedem verteilt oder verkauft werden.<br />
2 Der Nutzer darf das Programm sogar ändern.
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 52<br />
3 Der Nutzer hat Anspruch auf die Programmquellen.<br />
4 Der Vertrag darf nicht eingeschränkt werden (auch wenn<br />
nur Programmteile genutzt werden).<br />
7 Betroffene Patente müssen für Jedermann frei nutzbar<br />
sein.<br />
11 Der Autor gewährt keine Haftung.<br />
Richard Stallman legt Wert darauf, dass es nur eine<br />
gültige Version der Lizenz gibt. Diese findet man unter<br />
www.gnu.org/licences [gnu].<br />
GNU ist ein sogenanntes Akronym als Abkürzung für ,,GNU<br />
is Not Unix”, was wohl auf die Lizenzpolitik des ursprünglichen<br />
Unix anspielen soll.<br />
Es wurden GNU-Versionen der wichtigsten Unix-Werkzeuge<br />
neu programmiert:<br />
ls Listet den Inhalt eines Verzeichnisses.<br />
cat Zeigt Inhalt von Dateien, kann viel mehr.<br />
cp Kopierprogramm<br />
rm Löschprogramm
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 53<br />
mkdir Erzeugt Verzeichnisse.<br />
rmdir Entfernt leere Verzeichnisse.<br />
find Sucht im Dateibaum.<br />
man Gibt Hilfe zu dem im Argument benannten Befehl.<br />
tar Sicherungsprogramm<br />
Dies ist nur eine kleine Auswahl wichtiger Programme der<br />
großen Menge der GNU-Werkzeuge, die sich vor allem in den<br />
Verzeichnissen /bin /usr/bin und /sbin befinden. Jedes Programm<br />
kennt eine Menge von Schaltern und Optionen, die<br />
man <strong>mit</strong> dem Schaltern -h oder --help abrufen kann. Weitere<br />
Hilfe bieten die Befehle man ls ... und info ls ...<br />
5.3.1 bash<br />
Der Betriebssystemkern kann nicht direkt <strong>mit</strong> dem Nutzer<br />
kommunizieren. Hierzu ist ein weiteres wichtiges Programm<br />
notwendig, dem der bildhafte Name Shell gegeben wurde, da<br />
es wie eine harte Schale den Kern vom Nutzer trennt. Die erste<br />
Shell, die weite Verbreitung fand, wurde von S. R. Bourne<br />
geschrieben. Da diese Shell noch viele Wünsche offen ließ,
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 54<br />
entstanden andere Shells, wie die cshell, die leider recht inkompatibel<br />
zur Bourne-Shell war. Diesen Fehler korrigierte<br />
die Korne-Shell <strong>mit</strong> anderen Problemen.<br />
Bei der FSF entschied man sich, zur Bourne-Shell kompatibel<br />
zu bleiben, neue Features aber so gut wie möglich einzubauen.<br />
Es entstand die mächtige bash. Der Name ist eine Abkürzung<br />
von Bo(u)rn(e) Again SHell.<br />
Neben der notwendigen Eigenschaft, Befehle in der Form von<br />
Programmnamen und eventuellen Schaltern und Argumenten<br />
von der Tastatur anzunehmen, ist die Shell auch Programmiersprache.<br />
Man kann Befehle <strong>mit</strong> einem Editor in eine Datei<br />
schreiben und diese Datei wiederum wie ein Programm<br />
starten. Es ist möglich, Programme über Schleifen und Bedingungen<br />
zu komplexeren Programmen zu verbinden. Es gibt<br />
auch Unterprogramme. Ein derartiges Programm wird auch<br />
Shellscript genannt.<br />
So werden zwei wichtige Unix-Konzepte unterstützt: Programme<br />
einfach und begrenzt zu halten und <strong>mit</strong> einfachen<br />
Bausteinen komplexere Dinge zu realisieren.<br />
5.3.2 Editoren<br />
Editoren verwendet man, um Texte in den Computer einzugeben.<br />
Texte sind nicht nur Briefe und Aufsätze, es können<br />
auch Daten, Programme, Bücher usw. sein. Editoren sind also<br />
die wichtigsten Eingabeprogramme für Computer. Prinzipiell
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 55<br />
könnten im nicht grafischen Bereich alle Eingaben über Editoren<br />
geschehen.<br />
Aus diesem Grund haben viele Leute ihren eigenen Editor<br />
geschrieben (Autor eingeschlossen). Sechs wichtige Editoren<br />
möchte ich erwähnen:<br />
vi ist der Nachfolger des ersten Unix-Editors ed. vi konnte<br />
<strong>mit</strong> den damals neuen Bildschirmterminals umgehen. ed funktionierte<br />
noch <strong>mit</strong> Fernschreibern. Eine wichtige Eigenschaft<br />
von vi ist, dass er <strong>mit</strong> dem Zehn-Finger-System blind bedient<br />
werden kann.<br />
vim ist eine umfangreiche Nachprogrammierung des vi <strong>mit</strong><br />
vielen Erweiterungen. In der Lizenz des vim wird man eingeladen,<br />
Kinder in Uganda finanziell zu unterstützen.<br />
emacs gehört zum Grundstock der FSF. emacs ist um einen<br />
Kern der Programmiersprache Lisp gebaut worden und in Lisp<br />
erweiterbar. Der Autor ist Richard Stallman. Leider entspricht<br />
emacs nicht mehr dem Unixkonzept, klein zu sein, weshalb die<br />
Meinung dazu recht gespalten ist.<br />
e3 ist ein sehr kleiner (8KB) in Assembler programmierter<br />
Editor, der dennoch Oberflächen bietet, die sich an vi, emacs,<br />
wordstar, nedit und pico anlehnen.
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 56<br />
pico ist ein relativ einfach zu bedienender Editor ohne komplexe<br />
Funktionen.<br />
gvim ist der für X11-Oberflächen erweiterte vim. gvim<br />
setzt Farbe zur Hervorhebung von Programmiersprachen ein<br />
und kann auch sinnvoll <strong>mit</strong> der Maus bedient werden.<br />
Alle erwähnten Editoren sind für die Eingabe von Programmen<br />
geschrieben worden. Obwohl es für Linux auch sehr gute<br />
WYSIWYG 5 - Editoren gibt, werden diese vom Autor bewusst<br />
nicht eingesetzt. Der Autor nutzt heute vim, da dieser<br />
das Zehn-Finger-Blindschreiben am besten unterstützt. Mehr<br />
zu diesem Thema im makefile.latex auf der Homepage [unger]<br />
des Autors.<br />
5.3.3 make<br />
make wurde geschrieben, um das wiederholte Aufrufen von<br />
Programmierwerkzeugen zu erleichtern. In einem Makefile<br />
werden die Abläufe und Abhängigkeiten für die Übersetzung<br />
von Programmen formuliert. make kann <strong>mit</strong> dieser Beschreibung<br />
den Übersetzungslauf automatisieren und optimieren.<br />
Die Optimierung wird über die Angabe der Abhängigkeiten<br />
im Makefile und Änderungszeiten der beteiligten Dateien entschieden.<br />
In großen Systemen, wie zum Beispiel bei der Übersetzung<br />
des Linux Betriebssystems, wird dadurch viel Zeit<br />
gewonnen. In kleinen Systemen dokumentiert das Makefile<br />
5 What You See Is What You Get
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 57<br />
immerhin noch den Entstehungsvorgang. make ist nicht auf<br />
Programmentwicklung beschränkt. Es leistet auch gute Dienste<br />
bei der Pflege von Datenbanken und mehr.<br />
In den Verzeichnissen, die die Software für das<br />
Mikrocontroller- Experimentiersystem enthalten, befindet<br />
sich meist ein Makefile <strong>mit</strong> integrierter Dokumentation.<br />
Der Aufruf von ,,make” oder ,,make help” erzeugt die<br />
Ausgabe<br />
Usage: make same as make help<br />
make help same as make<br />
make vi edit sourcefile<br />
make eeprom create data for eeprom<br />
make flash compile flashable file<br />
make upload upload flash into processor<br />
make upload_fuse program fuse<br />
make upload_eeprom upload eeprom into processor<br />
make download read data from processor and compare<br />
make disasm disasm flash<br />
make verify verify flash<br />
make erase erase chip<br />
make clean remove redundant data<br />
Die verfolgte Absicht dieses Konzeptes besteht darin, nur<br />
einen Befehl kennen zu müssen, nämlich ,,make”. Der Rest<br />
ergibt sich.<br />
5.3.4 X11<br />
Die graphische Oberfläche für Unix heißt X11. Das Konzept<br />
ist tief durchdacht. So ist es möglich, X11-Programme auf<br />
anderen Rechnern im Internet zu starten, d.h. Maus, Tastatur,<br />
Bildschirm und Programm können auf verschiedene Rechner<br />
verteilt werden.
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 58<br />
Für X11 wurden verschiedene Fenstermanager programmiert.<br />
Modern sind Gnome und KDE. Ein sehr kleiner Fenstermanager<br />
wurde von den Entwicklern von X11 selbst entworfen.<br />
Er heißt twm. Wahrscheinlich dient er bei der Entwicklung<br />
als Testumgebung. Kleineren Computern ermöglicht twm eine<br />
grafische Oberfläche anzubieten, auf der man gut mehrere<br />
Fenster öffnen, Bilder betrachten, Bücher lesen und andere<br />
grafikorientierte Tätigkeiten erledigen kann.<br />
5.3.5 Ghostscript<br />
Da Drucker sehr unterschiedlich angesteuert werden, hat sich<br />
in der Unix-Welt eine Sprache für Druckwerke, namentlich<br />
Postscript etabliert. Postscript wurde von der Firma Adobe<br />
[adobe] entwickelt.<br />
Drucker, die Postscript direkt verstehen, sind manchmal teurer<br />
als einfachere Modelle. Um preiswerte Drucker einsetzen<br />
zu können, übersetzt das Programm ghostscript den<br />
Postscript-Code in einfache Druckerbefehle. Natürlich muss<br />
bei der Installation das vorhandene Druckermodell eingestellt<br />
werden.<br />
5.3.6 Datenbank<br />
Die folgenden Programme ermöglichen unter Zuhilfenahme eines<br />
Editors die Realisierung kleiner Datenbanken. Neben der
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 59<br />
Textverarbeitung ist das eine häufige und wichtige Anwendung<br />
von Computern.<br />
grep selektiert Zeilen in Tabellen.<br />
cut selektiert Spalten in Tabellen.<br />
join vereinigt Tabellen.<br />
sort sortiert Tabellen.<br />
awk Programmiersprache für Tabellenbearbeitung.<br />
sed editiert Dateien programmgesteuert.<br />
Zu Zeilen sagt man oft Datensätze 6 . Spalten werden häufig<br />
Felder 7 . genannt. Tabellen speichert man in Dateien. Die<br />
Grundfunktionen grep, cut und join erzeugen wiederum Tabellen.<br />
Ein kleines Beispiel soll eine Idee der Funktion von Datenbanken<br />
ver<strong>mit</strong>tlen:<br />
Eine Tabelle <strong>mit</strong> dem Dateinamen ,,geburtstage” enthält folgende<br />
Daten:<br />
Huber:1980Apr01:Hamburg<br />
Meier:1975Mar04:Frankfurt<br />
Molch:1977Feb11:München<br />
Eine Anfrage an die Datenbank, wer am 1. April Geburtstag<br />
hat, sähe folgendermaßen aus:<br />
6 In der englischsprachigen Literatur records genannt.<br />
7 In der englischsprachigen Literatur fields genannt.
KAPITEL 5. KURZEINFÜHRUNG IN LINUX 60<br />
grep Apr01 geburtstage|cut -d: -f1<br />
Eine weitere Tabelle <strong>mit</strong> dem Dateinamen ,,telefon” enthält<br />
diese Daten:<br />
Huber:0123-1111111<br />
Meier:0111-1212121<br />
Molch:0333-3333333<br />
Eine Tabelle der Telefonnummern der Geburtstagskinder des<br />
1. April:<br />
grep Apr01 geburtstage|join -t: - telefon|cut -d: -f4<br />
Wer wundert sich noch über Werbeanrufe?<br />
Vertiefung: Man studiere die man-pages von grep, join und<br />
cut, um das vorherige Kommando zu verstehen.
Kapitel 6<br />
Assembler<br />
Assembler sind Sprachen, die die Befehlscodes der jeweiligen<br />
CPU direkt abbilden. Jede CPU-Familie hat ihre eigene<br />
Assembler-Sprache. Da alle CPUs dem im Kapitel 3 beschriebenen<br />
Modell folgen, kann man mühelos von einer Assembler-<br />
Sprache auf eine andere umsteigen.<br />
Beim ersten Studium einer Assembler-Sprache sind Abbildungen<br />
der CPU, welche das Registermodell veranschaulichen,<br />
hilfreich.<br />
Neben der prinzipiell einfachen Umsetzung der Befehle, Mnemonics<br />
genannt, in die binären Befehlscodes, leisten Assembler<br />
noch die Berechnung von Sprung- und Datenadressen, die<br />
frei bezeichnet werden dürfen.<br />
Eine lästige Pflicht bei der Programmierung <strong>mit</strong> Assembler<br />
ist das Erfinden von Namen für Sprungmarken. Mit Hilfe der<br />
61
KAPITEL 6. ASSEMBLER 62<br />
im nächsten Kapitel erklärten strukturierten Programmierung<br />
und einem Notizzettel für das Abstreichen verwendeter Nummern<br />
kann man sich das Programmieren vereinfachen, wie folgendes<br />
Beispiel einer Schleife, die im Register1 von 1 bis 100<br />
zählt, zeigt:<br />
;nach Semikolon folgt ein Kommentar<br />
;r1=1<br />
ldi r1,1 ;load immediate<br />
;loop<br />
loop1: ;Sprungmarke<br />
;if r1==100 then breakloop endif<br />
cpi r1,100 ;compare immediate<br />
breq endloop1;branch if equal<br />
;r1=r1+1<br />
addi r1,1 ;add immediate<br />
;endloop:<br />
jmp loop1 ;jump<br />
endloop1: ;Sprungmarke<br />
Mit dieser Methode bereitet das beliebig tiefe Schachteln von<br />
Programmschleifen kein Problem mehr. if-then-else-endif behandelt<br />
man analog.<br />
Programme werden oft in mehrere Teile zerlegt. Im Idealfall<br />
nennt man das ,,modulares Programmieren”. Nachdem der<br />
Assembler alle Programmmodule übersetzt hat, werden diese<br />
vom Linker zu einer Datei zusammengefügt. Beim Linkvorgang<br />
müssen außerdem absolute Speicheradressen für die
KAPITEL 6. ASSEMBLER 63<br />
freien Symbole der Sprung- und Datenadressen berechnet und<br />
vergeben werden.<br />
Vertiefung: Wie lange rechnet obiges Programm, wenn der<br />
Prozessor pro Takt ein Befehl ausführt und <strong>mit</strong> 8 Mhz getaktet<br />
ist?
Kapitel 7<br />
Programmiersprache C<br />
Der große Trick bei der Entwicklung von Unix war die Programmiersprache<br />
C. C ist einfach auf Maschinensprachen abbildbar,<br />
besitzt aber dennoch eine eindeutige Syntax und eine<br />
nahezu eindeutige Semantik. Über 90 Prozent von Unix<br />
konnten in C formuliert werden. Dadurch war die Portierung<br />
des Betriebssystems auf neue Prozessoren vereinfacht worden.<br />
Ferner war <strong>mit</strong> jeder Portierung des Betriebssystems sofort<br />
eine höhere Programmiersprache verfügbar. C hat relativ<br />
schnell die damals etablierten Programmiersprachen wie Algol,<br />
Cobol und Fortran verdrängt.<br />
Der C-Compiler von GNU, gcc genannt, hat inzwischen Referenzstatus.<br />
Später kommt er auch hier zum Einsatz.<br />
Zum Lernen von C ist das Originalbuch [C] der Autoren der<br />
Sprache bestens geeignet. Nicht nur, dass es die ursprüngli-<br />
64
KAPITEL 7. PROGRAMMIERSPRACHE C 65<br />
che Sprachdefinition darstellt, es kann auch als vorbildliches<br />
Lehrbuch bezeichnet werden.<br />
Das erste Programmierprojekt des Buches ist ein triviales Programm,<br />
das den Text<br />
hello, world<br />
ausgibt. Diese didaktische Idee bekam viele Nachahmer wie<br />
man in der Wikipedia [wikipedia] nachlesen kann.<br />
Wichtiges Konzept der Sprache C ist die sogenannte strukturierte<br />
Programmierung. Strukturierte Programme lassen<br />
sich in Blöcke gliedern <strong>mit</strong> genau einem Eingang und genau<br />
einem Ausgang. Um dies zu erreichen, werden Programmsprünge,<br />
die das von-Neumann-Konzept in ungezügelter Art<br />
und Weise zulässt, auf den Vorwärtssprung <strong>mit</strong>tels if-thenelse-endif<br />
und den Rückwärtssprung <strong>mit</strong>tels loop-endloop<br />
eingeschränkt. Für das Beenden von Schleifen gibt es ein<br />
breakloop. Beliebiges Ineinanderschachteln der Form loop1loop2-endloop2-endloop1<br />
usw. ist erlaubt.<br />
Nicht erlaubt ist ein Verschachteln der Form loop1-loop2endloop1-endloop2.<br />
Die Bedingung, genau einen Eingang zu<br />
haben, wäre verletzt.<br />
Die Sprache C verwendet zur Blockbildung geschweifte Klammern:<br />
{ und }. Für den Vorwärtssprung gibt es if, else und<br />
switch, case. Der Rückwärtssprung kann durch while oder for<br />
oder durch do <strong>mit</strong> while ausgedrückt werden.
KAPITEL 7. PROGRAMMIERSPRACHE C 66<br />
if-then-else-endif wird in C folgendermaßen formuliert:<br />
if (Bedingung)<br />
{<br />
Anweisungen;<br />
}<br />
else<br />
{<br />
Anweisungen;<br />
}<br />
Der else-Teil kann auch fehlen.<br />
Für loop-endloop gibt es in C drei mögliche Formulierungen,<br />
die nachfolgend <strong>mit</strong> der loop-Metasprache 1 erklärt werden:<br />
while (Bedingung) loop<br />
{ if not Bedingung then breakloop endif<br />
Anweisungen; Anweisungen<br />
} endloop<br />
for (Ausdruck1;Bedingung;Ausdruck2) Ausdruck1<br />
{ loop<br />
Anweisungen; if not Bedingung then breakloop endif<br />
} Anweisungen<br />
Ausdruck2<br />
endloop<br />
do loop<br />
{ Anweisungen<br />
Anweisungen; if not Bedingung then breakloop endif<br />
} while (Bedingung) endloop<br />
Da sich in einigen Fällen, oft bei Fehlerbehandlung, nicht<br />
strukturierte Sprünge vorteilhaft auswirken, kennt C auch goto<br />
und Label als Sprungziele zur verantwortungsvollen Nutzung.<br />
Ferner formuliert man den selten vorkommenden allgemeinsten<br />
Fall eines loop <strong>mit</strong> <strong>mit</strong>tiger Abruchbedingung in der<br />
Sprache C <strong>mit</strong> Hilfe von goto:<br />
1 Ein Metasprache ist eine Sprache, die eine andere Sprache erklärt.
KAPITEL 7. PROGRAMMIERSPRACHE C 67<br />
loopA: loop<br />
Anweisungen1; Anweisungen1<br />
if (Bedingung) goto endloopA; if Bedingung then breakloop endif<br />
Anweisungen2; Anweisungen2<br />
goto loopA; endloop<br />
endloopA:<br />
Die Korrektheit eines strukturierten Programmes kann bewiesen<br />
werden. Einen solchen Beweis nennt man Programmverifikation.<br />
Da derartige Beweise sehr aufwändig sind, werden sie<br />
nur selten durchgeführt.<br />
Auf Grund des geordneten Programmflusses gibt es viele Vorteile.<br />
Strukturierte Programme sind<br />
• leserlicher<br />
• verständlicher<br />
• robuster<br />
• leichter änderbar<br />
• eher wiederverwendbar<br />
All diese Vorzüge sind Gründe dafür, dass eigentlich alle modernen<br />
Programmiersprachen dieses Konzept unterstützen.<br />
Fortran, Cobol und Basic sind in ihrer ursprünglichen Form<br />
aussterbende Sprachen, weil sie das Konzept noch nicht kannten.
Teil II<br />
Hardwaretechnik<br />
68
Kapitel 8<br />
Hardware-Labor<br />
Mit diesem Buch soll ein komplettes Entwicklungssystem für<br />
Mikrocontroller der Firma Atmel aufgebaut werden. Aus diesem<br />
Grund wird kurz auf einige unverzichtbare Utensilien eines<br />
Hardware-Labors eingegangen.<br />
8.1 Lötkolben<br />
Für elektronische Bauteile braucht man einen Lötkolben<br />
<strong>mit</strong> ca. 16 Watt. Besser ist ein Gerät <strong>mit</strong> mehr Leistung<br />
und einer Temperaturregelung. Als Lötdraht verwendet man<br />
Elektronik-Lot <strong>mit</strong> 1 mm Durchmesser.<br />
Um einwandfreie Lötverbindungen herzustellen muss man ein<br />
69
KAPITEL 8. HARDWARE-LABOR 70<br />
Abbildung 8.1: Gute und schlechte Lötverbindungen.<br />
wenig üben und wissen, dass es drei Feinde einer guten Lötverbindung<br />
gibt:<br />
Zu geringe Temperatur. Der Lötkolben muss ausreichend<br />
Zeit zum Anheizen bekommen. Erst wenn der Lötdraht<br />
sofort schmilzt, ist die Anheizzeit vorbei. Lötkolben und Lot<br />
werden gleichzeitig zur Lötstelle geführt. Die Lötspitze wird<br />
noch ca. 1 Sekunde im flüssigen Lot gelassen, bis das Lot sich<br />
<strong>mit</strong> allen Teilen verbindet. Dies erkennt man an der Form der<br />
Oberfläche. Siehe Abbildung 8.1.<br />
Oxydation. An zwei Stellen macht Oxydation zu schaffen:<br />
Vor allem blanke Kupferoberflächen an Bauteilen oxydieren.<br />
Geringe Oxydation wird vom Fluss<strong>mit</strong>tel im Lot unterwandert.<br />
In schweren Fällen, zum Beispiel, wenn Handschweiß<br />
mehrere Tage auf Kupfer einwirken konnte, muss <strong>mit</strong> hartem<br />
Radiergummi oder <strong>mit</strong> feinem Schmirgelpapier Abhilfe<br />
geschaffen werden.
KAPITEL 8. HARDWARE-LABOR 71<br />
Wird der Lötkolben mehrere Minuten nicht benutzt, so verdampft<br />
die schützende Fluss<strong>mit</strong>telhülle um das heiße Lot herum.<br />
Danach entsteht eine Oxydationsschicht, die weiteres Arbeiten<br />
behindert. In diesem Fall muss die Lötspitze zum Beispiel<br />
<strong>mit</strong> einem Papiertaschentuch gereinigt und sofort <strong>mit</strong> ein<br />
wenig frischem Lot wieder geschützt werden.<br />
Bewegung beim Erstarren. Wird der Lötkolben von der<br />
Lötstelle entfernt, beginnt die mehrere Sekunden dauernde<br />
Erkaltungsphase. Wurde vor dem Löten nicht dafür gesorgt,<br />
dass die Teile unbeweglich sind, führt das zu einer sogenannten<br />
kalten Lötstelle. Die Oberfläche des Lotes ist nicht mehr<br />
glatt. Solche Stellen müssen unbedingt nachgelötet werden,<br />
da sie u. a. zu Wackelkontakten führen können!<br />
8.2 Multimeter<br />
Um zum Beispiel Spannungen nachzuweisen, ist es gut, ein<br />
Multimeter zu besitzen. Es ist quasi das wichtigste Messgerät,<br />
wenn man <strong>mit</strong> Elektrizität zu tun hat. Diese Geräte<br />
sind für Messungen von Spannung [Volt], Strom [Ampere] und<br />
Widerstand [Ohm] ausgelegt. Es gibt analoge Zeigerinstrumente<br />
und digitale Messgeräte. Auch wenn die technischen<br />
Daten bei gleichem Preis für digitale Messgeräte sprechen,<br />
würde ich als erstes Gerät ein Zeigerinstrument empfehlen.<br />
Der Grund dafür liegt darin, dass der zeitliche Verlauf des<br />
Zeigerausschlags weit mehr über das laufende physikalische
KAPITEL 8. HARDWARE-LABOR 72<br />
Experiment aussagt, als auch ein teures digitales Messgerät<br />
ver<strong>mit</strong>teln kann.<br />
Für den Umgang ist wieder etwas Theorie notwendig.<br />
In der Physik verwendet man oft vier Bezeichnungen: Den<br />
Namen des physikalischen Phänomens und dessen Abkürzung<br />
und die Dimension zur quantitiven (größenmäßigen) Bestimmung<br />
und dessen Abkürzung.<br />
Drei wichtige Größen der Elektrotechnik<br />
Phänomen Abkürzung Dimension Abkürzung<br />
Spannung U Volt V<br />
Strom I Ampere A<br />
Widerstand R Ohm Ω<br />
Die drei physikalischen Größen gehorchen unter bestimmten<br />
Bedingungen dem Ohmschen Gesetz:<br />
R · I = U<br />
⇔ U<br />
= R<br />
I<br />
⇔ U<br />
= I<br />
R<br />
Ströme kommen oft in sehr kleinen Größen vor und werden<br />
dann in Milliampere <strong>mit</strong> 1 mA = 0,001 A angegeben. Aus dem<br />
Ohmschen Gesetz kann man folgern, dass Widerstände <strong>mit</strong><br />
großen Werten vorkommen. Sie werden <strong>mit</strong> Kiloohm bezeichnet,<br />
wobei 1 KΩ = 1000 Ω ist.
KAPITEL 8. HARDWARE-LABOR 73<br />
Bei der Anwendung des Multimeters muss man sich als erstes<br />
darüber klar werden, welche Größe man messen will, da<br />
das Gerät entsprechend eingestellt und angeschlossen werden<br />
muss:<br />
Spannung: Dies ist die häufigste Messung <strong>mit</strong> dem Multimeter.<br />
Nach Einstellung des Messbereichs, in unseren Fällen<br />
auf Gleichspannung, wird der Minus-Eingang des Gerätes<br />
<strong>mit</strong> der Masse der Schaltung verbunden und <strong>mit</strong> dem Plus-<br />
Eingang zum Beispiel ein Ausgang des Mikrocontrollers<br />
berührt. Der größte Fehler, der bei dieser Messung passieren<br />
kann, wäre, das Messgerät auf Stommessung einzustellen,<br />
ein Kurzschluss wäre die Folge. Andere Fehler äußern sich in<br />
unsinnigen Messwerten.<br />
Abbildung 8.2: Schaltung einer Spannungsmessung.
KAPITEL 8. HARDWARE-LABOR 74<br />
Strom: Strommessungen sind seltener. Sie gehören zu den<br />
komplizierteren Messungen <strong>mit</strong> dem Multimeter. Nach Einstellen<br />
des Gleichstrombereiches verhält sich das Messgerät<br />
zwischen den beiden Messspitzen annähernd wie ein Stück<br />
Draht (niedriger Innenwiderstand). Verwendet man jetzt die<br />
Messspitzen wie ein Voltmeter, so kommt es zu einem Kurzschluss.<br />
Multimeter haben für diesen Fall eine Sicherung, welche<br />
dann eventuell gewechselt werden muss.<br />
Bei der Strommessung muss in der Schaltung eine Leitung,<br />
zum Beispiel die Stromversorgungsleitung, unterbrochen werden.<br />
Die Unterbrechung wird dann <strong>mit</strong> den Messspitzen überbrückt.<br />
Siehe Abbildung 8.3.<br />
Abbildung 8.3: Schaltung einer Strommessung.<br />
Die bei <strong>Mikrocontrollern</strong> vorkommenden Ströme sind meist<br />
so klein, dass sie im Bereich der unteren Messbereichsgrenzen<br />
liegen. Wer nun die gute Idee hat, das Ohmsche Gesetz einzusetzen,<br />
kommt leider auch nicht zum Ziel, da die Messung des<br />
Widerstandes <strong>mit</strong> dem Multimeter nur <strong>mit</strong> sogenannten Ohmschen<br />
Leitern (Schaltungen ohne Halbleiter, Spulen, Konden-
KAPITEL 8. HARDWARE-LABOR 75<br />
satoren) funktioniert.<br />
Widerstand: Widerstände werden außerhalb der Schaltung<br />
gemessen. Selbst Drehspulinstrumente <strong>mit</strong> Zeiger, die<br />
bei Strom- und Spannungsmessungen ihre Energie aus der<br />
zu messenden Schaltung beziehen (und da<strong>mit</strong> den Messwert<br />
etwas verfälschen), setzen für diese Messungen eine Batterie<br />
ein. Die Batterie wird geprüft, indem die Messspitzen kurzgeschlossen<br />
werden. Das Multimeter muss dann Null Ohm<br />
anzeigen.<br />
Abbildung 8.4: Schaltung einer Widerstandsmessung.<br />
Das Messgerät wird auf den größten Widerstandsbereich<br />
eingestellt und dann stufenweise heruntergeschaltet, bis der<br />
Messbereich optimal genutzt wird.<br />
Manche Geräte haben zur Durchgangsprüfung von Leitungen<br />
(sehr geringer Widerstand) einen Summer, der davon<br />
entlastet, bei solchen Prüfungen die Anzeige beobachten zu<br />
müssen. Zur Fehlersuche in neu aufgebauten Schaltungen ist<br />
das recht nützlich.
KAPITEL 8. HARDWARE-LABOR 76<br />
8.3 Netzgerät<br />
Netzgeräte gibt es in den verschiedensten Ausführungen. Sie<br />
können fehleranfällige Batterien ersetzen. Gute Netzgeräte besitzen<br />
eine einstellbare maximale Spannung und einen einstellbaren<br />
maximalen Strom. Mit Strom- und Spannungsanzeige<br />
können auf einen Blick die wichstigsten Parameter einer<br />
Schaltung kontrolliert werden.<br />
Für die Schaltungen in diesem Buch ist ein Netzgerät nicht unbedingt<br />
erforderlich. Für diejenigen, die weiter arbeiten wollen,<br />
steht es weit oben auf der Wunschliste.
Kapitel 9<br />
Kleine Bauteilekunde<br />
Die folgende Bauteilekunde geht nur auf solche Teile ein, die<br />
für unser Projekt gebraucht werden. Selbstverständlich gibt<br />
es weit mehr Bauteilesorten und Untersorten als hier erwähnt<br />
sind.<br />
Von jedem Bauteil werden Bezeichnung, Aussehen, wesentliche<br />
Eigenschaften und ein Funktionstest beschrieben.<br />
9.1 Platinenmaterial<br />
Wir verwenden fotobeschichtetes 1,5 mm starkes Epoxyd-<br />
Glashartgewebe <strong>mit</strong> einseitiger Kupferauflage von 35 µm<br />
Dicke. Diese Bezeichnung impliziert, dass es auch nicht fotobeschichtetes<br />
Material gibt, andere Dicken, zweiseitige Kupfer-<br />
77
KAPITEL 9. KLEINE BAUTEILEKUNDE 78<br />
auflage und andere Basismaterialien. Epoxyd-Glashartgewebe<br />
hat neben hoher Stabilität den Vorteil, dass die Kupferauflage<br />
gut an der Platine haftet. Das ist eine wichtige Eigenschaft, da<br />
es bei den Experimenten vorkommen kann, dass ein Bauteil<br />
wieder entlötet werden muss. Bei preiswerterem Hartpapier<br />
ist es normal, dass die Leiterbahn sich bei wiederholtem Erhitzen<br />
vom Basismaterial löst.<br />
9.2 Stecker<br />
Abbildung 9.1: Stecker<br />
Stecker werden hauptsächlich für die Stromversorgung und<br />
für Signalwege eingesetzt. Für die Stromversorgung setzen wir<br />
Hohlstecker ein, wie sie bei Steckernetzteilen Verwendung fin-
KAPITEL 9. KLEINE BAUTEILEKUNDE 79<br />
den. Diese gibt es <strong>mit</strong> verschiedenen Durchmessern. Wir verwenden<br />
häufig vorkommende 2,1 mm. Für den Übergang auf<br />
andere Durchmesser gibt es Adapter.<br />
Für die Signale verwenden wir Pfostenstecker und D-<br />
Sub-Steckverbinder. Auf der PC-Seite kommen die D-Sub-<br />
Steckverbinder DB-9 und DB-25 zum Einsatz. Deren Pole sind<br />
in der Regel auf der Lötseite eindeutig durchnummeriert.<br />
Für unsere Platine nehmen wir Pfostenstecker und Buchsen,<br />
die sich leicht und präzise <strong>mit</strong> Flachbandkabel verbinden<br />
lassen. Leider wird bei diesen meist nur der Pin 1 durch<br />
einen Pfeil gekennzeichnet. Obendrein gibt es Versionen ohne<br />
Führung und Kodiernase. Auch die Reihenfolge der Nummerierung<br />
ist anders als bei den D-Sub-Steckern!<br />
9.3 Kabel<br />
Bei Kabeln unterscheidet man Querschnitt, Isolation und Kabelaufbau.<br />
Für ein Ampere Strombelastung benötigt man<br />
0,1 mm 2 Querschnitt. Zu geringer Querschnitt führt zur Erhitzung.<br />
Isolation und Kabelaufbau wird durch die Art der<br />
Verwendung festgelegt. Nur bei fester Verlegung verwendet<br />
man massive Kabel. Sonst kommen Litzen zum Einsatz, da<br />
diese nicht so leicht brechen. Für Messkabel verwendet man<br />
teure, hoch flexible Litzen.<br />
Rote Kabel signalisieren positive Gleichspannung; das zugehörige<br />
schwarze Kabel signalisiert Masse.
KAPITEL 9. KLEINE BAUTEILEKUNDE 80<br />
Fehler in Steckverbindungen und Kabel sucht man <strong>mit</strong> dem<br />
Ohmmeter.<br />
9.4 Widerstände<br />
In Bauteilelisten werden Widerstände durch ein R und eine<br />
Nummer bezeichnet. Zum Beispiel R1. Amerikanische<br />
Schaltpläne stellen Widerstände auf andere Weise dar als europäische:<br />
Abbildung 9.2: Amerikanisches und europäisches Widerstandssymbol<br />
Der Widerstandswert wird durch einen Code von farbigen<br />
Ringen gekennzeichnet. Der letzte Ring kennzeichnet die Toleranz,<br />
zum Beispiel:<br />
silber 10%<br />
gold 5%<br />
Der vorletzte Ring gibt die Anzahl der Nullen an. Die Ringe<br />
davor bezeichnen die Ziffern nach folgendem Code:
KAPITEL 9. KLEINE BAUTEILEKUNDE 81<br />
Abbildung 9.3: Widerstände
KAPITEL 9. KLEINE BAUTEILEKUNDE 82<br />
schwarz 0<br />
braun 1<br />
rot 2<br />
orange 3<br />
gelb 4<br />
grün 5<br />
blau 6<br />
violett 7<br />
grau 8<br />
weiß 9<br />
In der für 10% Toleranz vorgesehenen Reihe E12 gibt es die<br />
Ziffernfolgen 10, 12, 15, 18, 22, 17, 33, 39, 47, 56, 68, 82. Ein<br />
Widerstand <strong>mit</strong> 4700 Ohm 1 und einer Toleranz von 5% trägt<br />
die Ringe rot, violett, rot und gold. Er wird auch <strong>mit</strong> 4700 Ω<br />
oder 4,7 kΩ oder 4k7 bezeichnet. Ausgesprochen wird das als<br />
,,4,7 Kiloohm”.<br />
Die maximale Verlustleistung von Widerständen variiert <strong>mit</strong><br />
der Größe. In unseren Schaltungen fließen nur kleine Ströme,<br />
so dass kleine Widerstände <strong>mit</strong> 0,25 Watt ausreichen. Bei<br />
Platzmangel kann man SMD-Widerstände einsetzen, die,<br />
wenn überhaupt, den Wert als Ziffern aufgedruckt haben. Die<br />
letzte Ziffer bezeichnet wieder die Anzahl der Nullen.<br />
Die Funktion eines Widerstandes prüft man <strong>mit</strong> dem Ohmmeter.<br />
Die umgebende Schaltung bestimmt, ob er für die<br />
1854<br />
1 benannt nach dem deutschen Physiker Georg Simon Ohm, 1787–
KAPITEL 9. KLEINE BAUTEILEKUNDE 83<br />
Messung separiert werden muss, was der Fall ist, wenn nicht<br />
annähernd der erwartete Wert gemessen wird.<br />
9.5 Kondensatoren<br />
Abbildung 9.4: Kondensator und Elektrolytkondensator<br />
Kondensatoren sperren Gleichstrom und sind durchlässig für<br />
Wechselstrom. Auch Stromimpulse sind eine Form von Wechselstrom.<br />
So wie es Wechselströme verschiedener Stärke, Wellenform<br />
und Frequenz gibt, so gibt es Kondensatoren <strong>mit</strong> verschiedener<br />
Kapazität. Die Einheit der Kapazität ist das Farad<br />
2 <strong>mit</strong> der Abkürzung F.<br />
Zwei Grundtypen von Kondensatoren müssen unterschieden<br />
werden. Elektrolyt-Kondensatoren besitzen eine hohe Kapazität,<br />
der sich im Bereich von µF bewegt. Dafür sind sie empfindlich<br />
gegen zu hohe Spannung. Kondensatoren im Bechergehäuse<br />
sind relativ groß, Tantalkondensatoren sind kleiner.<br />
2 benannt nach dem englischen Chemiker und Physiker Michael Fara-<br />
day 1791–1867
KAPITEL 9. KLEINE BAUTEILEKUNDE 84<br />
Beim Einbau von Elektrolyt-Kondensatoren muss man auf die<br />
Polung achten. Das Gehäuse ist entsprechend beschriftet. Bei<br />
manche Kondensatoren hat der positive Pol ein längeres Bein.<br />
Kondensatoren <strong>mit</strong> kleiner Kapazität sind meist keine Elektrolytkondensatoren<br />
und dürfen beliebig eingebaut werden.<br />
Auch sie haben eine begrenzte Spannungsfestigkeit, <strong>mit</strong> der<br />
auch die Baugröße schwankt. Die Kapazität hat ebenfalls Einfluß<br />
auf die Größe.<br />
Ein wichtiger Einsatz in digitalen Schaltungen ist das Filtern<br />
von Störimpulsen, die quasi kurz geschlossen werden.<br />
Abbildung 9.5: Kondensatoren<br />
Während große Kondensatoren meist im Klartext beschriftet<br />
werden, sind kleine Kondensatoren verschieden oder gar nicht<br />
beschriftet.<br />
Bessere Multimeter haben Messbereiche für Kapazitäten.<br />
Mit etwas Erfahrung kann man <strong>mit</strong> einem Zeigerinstrument<br />
Elektrolyt-Kondensatoren testen, indem man sie auflädt und
KAPITEL 9. KLEINE BAUTEILEKUNDE 85<br />
über das Messgerät wieder entlädt. Zuletzt bleibt nur die<br />
Möglichkeit, <strong>mit</strong> dem Ohmmeter zu prüfen, ob der Kondensator<br />
wirklich Gleichstrom sperrt, was sich als hoher Widerstandswert<br />
ausdrückt. Dieser Test sagt aber nichts über die<br />
ganze Funktion aus. Zum Trost sei vermerkt, dass defekte<br />
Kondensatoren häufig auch so aussehen.<br />
9.6 Quarze<br />
Abbildung 9.6: Schaltsymbol für einen Quarz<br />
Quarze sind piezokeramische Teile, die sich beim Anlegen<br />
einer Spannung verformen. Trifft man <strong>mit</strong> einer Wechselspannung<br />
die Resonanzfrequenz des Kristalls, so versucht der<br />
Quarz, diese Frequenz zu halten.<br />
Die Frequenz ist der wichtigste Wert des Quarzes und meist<br />
auf dem Gehäuse aufgedruckt oder eingeprägt. Die Einheit<br />
ist Kilo-, Mega- oder Gigahertz 3 . Die Funktion von Quarzen<br />
ist noch schwieriger zu messen als die von Kondensatoren. Im<br />
3 benannt nach dem deutschen Physiker Heinrich Hertz, 1857-1894
KAPITEL 9. KLEINE BAUTEILEKUNDE 86<br />
Abbildung 9.7: Quarze
KAPITEL 9. KLEINE BAUTEILEKUNDE 87<br />
Zweifel tauscht man meist das verdächtige Exemplar gegen<br />
ein Neuteil. Meist liegt der Fehler jedoch woanders.<br />
Das untere Bauteil in der Abbildung 9.7 ist kein reiner Quarz,<br />
sondern eine integrierte Schaltung <strong>mit</strong> Quarz. Für dieses als<br />
Quarzoszillator bezeichnete Bauteile gelten auch die folgenden<br />
Worte über integrierte Schaltungen.<br />
9.7 Dioden<br />
Abbildung 9.8: Schaltsymbole verschiedener Dioden<br />
Dioden leiten Strom nur in einer Richtung. Strom fließt nur,<br />
wenn die Anode ca. 0,7 V positiver als die Kathode ist. Die<br />
Kathode der Dioden wird auf dem Gehäuse durch einen Strich<br />
gekennzeichnet, denn auch diese Bauteile müssen richtig eingesetzt<br />
werden. Ein wichtiger Wert von Dioden ist der maximale<br />
Durchlassstrom, der auch die Größe des Gehäuses beeinflußt.<br />
Es gibt viele Untersorten, wobei Leuchtdioden und Schottky-<br />
Dioden nicht unerwähnt bleiben sollen: Erstere werden weni-
KAPITEL 9. KLEINE BAUTEILEKUNDE 88<br />
Abbildung 9.9: Dioden
KAPITEL 9. KLEINE BAUTEILEKUNDE 89<br />
ger als Dioden sondern, als Ersatz für Glühlampen eingesetzt.<br />
Ohne Strom begrenzenden Widerstand gehen sie kaputt.<br />
Schottky-Dioden haben gegenüber normalen Dioden die Eigenschaft,<br />
schon bei 0.5 V für Strom durchlässig zu sein.<br />
Die Funktion von Dioden kann man <strong>mit</strong> dem Ohmmeter<br />
prüfen, falls die Spannung zwischen den Prüfspitzen ausreicht.<br />
Digitale Multimeter haben oft einen eigenen Messbereich für<br />
Diodenmessung und zeigen dabei die Durchlassspannung an.<br />
9.8 Transistoren<br />
Abbildung 9.10: Transistoren<br />
Die frühen elektrischen Computer wurden <strong>mit</strong> Relais aufgebaut.<br />
Nach einem kurzen Zwischenspiel der elektronischen
KAPITEL 9. KLEINE BAUTEILEKUNDE 90<br />
Abbildung 9.11: Transistoren<br />
Röhren haben sich Transistoren in digitalen Schaltungen<br />
durchgesetzt. Ein kleiner Strom, der durch die Basis zum<br />
E<strong>mit</strong>ter fließt, öffnet den Transistor zwischen Kollektor und<br />
E<strong>mit</strong>ter für einen großen Strom. Das Verhältnis der beiden<br />
Ströme ist der Verstärkungsfaktor des Transistors. In digitalen<br />
Schaltungen werden nur zwei Arbeitspunkte genutzt.<br />
Der Transistor bleibt geschlossen oder wird ganz geöffnet, wie<br />
beim Relais. Auch Transistoren müssen richtig herum eingebaut<br />
werden. Leider gibt es keine Regeln für die Anordnung<br />
der Beine. Die Bestückungsliste oder das Datenblatt des Transistors<br />
sind zu Rate zu ziehen.<br />
Auch preiswerte digitale Multimeter können den<br />
Verstärkungsfaktor von Transistoren messen (hFE-Bereich).<br />
Die Messöffnung für den Kollektor wird wegen der englischen<br />
Schreibweise <strong>mit</strong> C gekennzeichnet. Ansonsten prüft man<br />
von Basis zu E<strong>mit</strong>ter und von Basis zu Kollektor wie Dioden.
KAPITEL 9. KLEINE BAUTEILEKUNDE 91<br />
Die npn-Typen haben eine gemeinsame Anode, pnp-Typen<br />
ein gemeinsame Kathode.<br />
Komplette Schaltungen aus mehreren Transistoren auf einem<br />
Halbleiterkristall heißen ...<br />
9.9 Integrierte Schaltungen<br />
Abbildung 9.12: Integrierte Schaltungen<br />
Hersteller, Typ und Woche der Herstellung sind die typische<br />
Aufschrift integrierter Schaltungen. Aus den Ziffern der Wo-
KAPITEL 9. KLEINE BAUTEILEKUNDE 92<br />
che und den letzten beiden Ziffern des Jahres wird der vierstellige<br />
Code für das Herstellungsdatum gebildet.<br />
Integrierte Schaltungen sind empfindlich gegenüber falschen<br />
Spannungen. Das gilt sogar für bei trockener Luft vorkommende<br />
statische Aufladungen. Meist werden sie deshalb in einer<br />
speziellen Verpackung geliefert.<br />
Es ist wichtig Pin 1 zu erkennen und richtig in die Schaltung<br />
einzusetzen. Die Funktion prüft man, indem man die individuelle<br />
Beschreibung nachvollzieht, meist durch Messen von<br />
Spannungen. Oft wird das IC 4 für einen Funktionstest ausgetauscht.<br />
Da das Auslöten von ICs schwierig ist, werden sie<br />
gerne in Sockel gesetzt. Sockel sind leider häufiger Fehlerquelle<br />
als die ICs selber. Eine ältere gesockelte integrierte Schaltung<br />
wird deshalb erstmal entfernt und wieder eingesetzt, was eventuelle<br />
Oxydationen beseitigen soll. Wurde auf diese Weise ein<br />
Fehler gefunden, ist es sinnvoll, das IC im Sockel festzulöten.<br />
4 Abkürung der englischen Bezeichnung integrated cicuit
Kapitel 10<br />
Platinenlayouts<br />
Auch Hardware wird Heute <strong>mit</strong> Software entworfen.<br />
10.1 Programmieren <strong>mit</strong> Klassen<br />
Nachdem sich die Programmiersprache C gut verbreitet hat,<br />
wurde über Verbesserungen der Sprache nachgedacht. Durchgesetzt<br />
hat sich die Erweiterung von Bjarne Stroustrup, die er<br />
C++ nannte [C++]. C++ ist ein Konstrukt aus der Sprache<br />
C selbst und bedeutet soviel wie ein Schritt weiter als C.<br />
Eine wesentliche Erweiterung gegenüber C ist die Einführung<br />
von Klassen. Eine Klasse beschreibt eine Familie von Daten<br />
und Methoden, die logisch zusammengehören. Methoden wurden<br />
in C als Unterprogramme programmiert. Der Zugang zu<br />
93
KAPITEL 10. PLATINENLAYOUTS 94<br />
einer Klasse führt über den Klassennamen und einen Punkt.<br />
Die Eigenschaften einer Klasse können von einer neuen Klasse<br />
geerbt werden. Als Beispiel denke man sich eine Klasse<br />
Viereck <strong>mit</strong> Methoden Viereck.umfang, Viereck.flaeche. Leitet<br />
man von der Klasse Viereck die Klasse Quadrat ab, so erbt<br />
sie die Methoden Quadrat.umfang und Quadrat.flaeche.<br />
Beim Umgang <strong>mit</strong> den <strong>Mikrocontrollern</strong> kommen wir nicht<br />
so weit, da der Einsatz von C++ eher bei größeren Programmen<br />
sinnvoll ist. Trotzdem wird das Klassenkonzept auch in<br />
diesem Kurs genutzt. Bevor der Mikrocontroller richtig zum<br />
Einsatz kommt, werden Platinen angefertigt. Hierfür wird ein<br />
Shellscript <strong>mit</strong> Namen pcb bereit gestellt. Die Quelle des Programms<br />
findet sich im Anhang D.<br />
Das Programm ist unter Anwendung eines Klassenkonzepts<br />
programmiert worden. Dieses Klassenkonzept wurde entwickelt,<br />
weil Shellscripte einige Gemeinsamkeiten haben:<br />
• Häufig entstehen Familien von Programmen, die sich<br />
<strong>mit</strong> einem Thema beschäftigen.<br />
• Wird ein Shellscript nicht so oft benutzt, gerät es wegen<br />
der Vielfalt der Namen in Vergessenheit.<br />
• Shellscripten fehlt meist eine ausreichende Dokumentation.<br />
Dies hat mehrere Gründe:<br />
– Man meint, das Programm sei so einfach, dass es<br />
keine braucht.
KAPITEL 10. PLATINENLAYOUTS 95<br />
– Im Notfall könne man ja das Script lesen, was<br />
später leider erforderlich wird.<br />
– Die Dokumentation geht verloren.<br />
• Sind nicht alle aufgerufenen Programme installiert, brechen<br />
Shellscripte <strong>mit</strong>unter ohne ausreichende Fehlermeldung<br />
den Programmlauf ab.<br />
• Shellscripten fehlt manchmal eine gewisse innere Ordnung.<br />
Es wurde eine Mutterklasse <strong>mit</strong> Namen class geschaffen, die<br />
folgende Grundeigenschaften bietet:<br />
• Alle Methoden sind über den Klassennamen und einen<br />
Punkt zwischen Klassen- und Methodennamen erreichbar.<br />
Das wurde von C++ abgeschaut.<br />
• Schon die Mutterklasse kennt ein mehrstufiges Hilfekonzept:<br />
– Aufruf der Klasse ohne den Methodennamen: Die<br />
Klasse gibt eine Kurzinformation über Name,<br />
Funktion, Version, Autor und erste Hilfe.<br />
– Aufruf der Klasse <strong>mit</strong> falschen Argumenten: Es<br />
wird eine Kurzhilfe ausgegeben.<br />
– Aufruf der Klasse <strong>mit</strong> dem Methodennamen help:<br />
Alle Methoden werden <strong>mit</strong> einer Kurzhilfe vorgestellt.
KAPITEL 10. PLATINENLAYOUTS 96<br />
– Aufruf der Klasse <strong>mit</strong> dem Methodennamen man:<br />
Es wird eine ausführlichere Hilfe über die im Argument<br />
benannte Methode gegeben.<br />
– Aufruf der Klasse <strong>mit</strong> dem Methodennamen info:<br />
Die Klasse wird <strong>mit</strong> ihren Konzepten ausführlich<br />
vorgestellt.<br />
Die Dokumentation ist Bestandteil des Programms,<br />
kann also nicht einzeln verloren gehen.<br />
• Methodenname new: Die Klasse vererbt ihre Methoden<br />
an eine neue Klasse. Das Argument bezeichnet den neuen<br />
Klassennamen.<br />
• Methodenname deinstall: Die Klasse kann sich deinstallieren.<br />
Installalliert hat sie sich beim Aufruf ohne Methodenname.<br />
Ferner vererbt die Mutterklasse die Fähigkeit der Reinkarnation.<br />
Wird eine Tochterklasse <strong>mit</strong> der Methode new und dem<br />
Argument class aufgerufen, zum Beispiel<br />
pcb.new class<br />
so entsteht wieder die reine Mutterklasse. Jeder, der das Konzept<br />
verwenden möchte, weil ihn eine Klasse überzeugt hat,<br />
kann dies also tun. Der Zugang zur Programmquelle ist Bestandteil<br />
des Programms. Die GPL läßt grüßen.<br />
Weitere Informationen bekommt man durch die Befehlsfolge:
KAPITEL 10. PLATINENLAYOUTS 97<br />
pcb.new class<br />
./class<br />
./class.info | less<br />
Es sei erwähnt, dass der Autor weitere Klassen auf seiner Homepage<br />
[unger] zum Download bereithält:<br />
bks Buchhaltungssystem<br />
data Kleine Datenbank<br />
learn Eine Lernhilfe<br />
ahnen Ahnentafeln verwalten und präsentieren.<br />
stamm Stammbäume verwalten und präsentieren.<br />
photo Fotoarchiv<br />
xdesk Desktop für X11 <strong>mit</strong> twm<br />
make.latex ist ein <strong>mit</strong> ähnlichen Konzepten ausgestattetes<br />
Makefile für Anwender von L ATEX.<br />
10.2 Klasse für elektronische Schaltungen<br />
Das Programm pcb wurde von class abgeleitet. Die Grundidee<br />
des Programms ist, eine elektronische Schaltung in Tabellenform<br />
zu speichern. Die Schaltung kann auf einer Lochrasterplatine<br />
aufgebaut oder auf einer photoempfindlichen Leiterplatte<br />
belichtet, entwickelt und geätzt werden.
KAPITEL 10. PLATINENLAYOUTS 98<br />
Für eine kleine Platine, auf der ein Quarz montiert wird, sieht<br />
die Tabelle folgendermaßen aus:<br />
#<br />
# Name: hardware/quarz.pcb<br />
# Function: Oszillator-Modul für Mikrocontollerboard<br />
# History: 2004Jan19 Hanns-Konrad Unger<br />
#<br />
(d7)board\<br />
(b6)(c6)wire (c6)(c2)wire (c3)(d3)wire (b1)(d1)wire (b4)(b2)wire (b2)(a2)wire\<br />
(a2)(a1)wire :1:PCB:Platine 7*4 :Bestellnummer:herstellen<br />
(b6)pad(b4)pad:1:Q1 :Quarz 7.372800Mhz :Bestellnummer:einlöten<br />
(b2)pad(b1)pad:2:C1 :Kondensatoren 22pF evtl. SMD:Bestellnummer:einlöten<br />
(c2)pad(c1)pad:0:C2 :Kondensator 22pF evtl. SMD :Bestellnummer:einlöten<br />
(a1)pad(a7)pad(d1)pad\<br />
(d3)pad(d7)pad:1:So :DIL-14 Präzisions-Sockel :Bestellnummer:<strong>mit</strong> Platine verbinden<br />
Die Datensätze beginnen am Anfang einer Zeile. Felder werden<br />
durch Doppelpunkt getrennt. Wenn ein Datensatz über<br />
mehrere Zeilen verteilt ist, so wird die unvollständige Zeile<br />
<strong>mit</strong> dem ,,\” beendet.<br />
Die Felder haben folgende Bedeutung:<br />
1. Feld: Befehle zum Zeichnen des Platinenlayouts<br />
2. Feld: Anzahl der Bauteile für Einkaufsliste<br />
3. Feld: Kurzbezeichnung des Bauteils für Bestückungsliste<br />
4. Feld: Beschreibung des Bauteils<br />
5. Feld: Bestellnummer des Bauteils<br />
6. Feld: Text für Bauanleitung
KAPITEL 10. PLATINENLAYOUTS 99<br />
Die Befehle zum Zeichnen des Platinenlayouts entsprechen<br />
der Syntax der Sprache Postscript. Erst werden Koordinaten<br />
des Platinenlayouts genannt. (a1) entspricht auf der Lötseite<br />
links oben. Die rechten Nachbarn von (a1) sind (b1) ... (z1),<br />
dann (A1) ... (Z1). Der rechte untere Punkt einer Euro-Platine<br />
der Größe 100 mm × 160 mm ist (M63). Hinter (lat.: post)<br />
den Koordinaten wird eines der folgenden Unterprogramme<br />
aufgerufen:<br />
board legt die Größe der Platine fest.<br />
wire zeichnet eine Verbindung zwischen zwei Pads.<br />
pad zeichnet ein Pad.<br />
smd zeichnet ein Pad für SMD-Bauteile.<br />
xpad zeichnet eine horizontale Reihe von Pads.<br />
ypad zeichnet eine vertikale Reihe von Pads.<br />
Die Klasse pcb verfügt über folgende Methoden zur Umwandlung<br />
der Tabellen:<br />
pcb.layout erzeugt ein Postscriptfile für die Belichtungsmaske.<br />
pcb.layout quarz.pcb | lpr<br />
pcb.list erzeugt eine Einkaufsliste als Textfile.<br />
pcb.list quarz.pcb|sed ”/ˆ0:/d”
KAPITEL 10. PLATINENLAYOUTS 100<br />
1:Platine 7*4 :Bestellnummer<br />
1:Quarz 7.372800Mhz :Bestellnummer<br />
2:Kondensatoren 22pF evtl. SMD:Bestellnummer<br />
1:DIL-14 Präzisions-Sockel :Bestellnummer<br />
pcb.kit erzeugt eine Beschreibung 1 als Textfile.<br />
pcb.kit quarz.pcb<br />
( ) PCB:Platine 7*4 :herstellen (a2) (a1)<br />
( ) Q1 :Quarz 7.372800Mhz :einlöten (b6) (b4)<br />
( ) C1 :Kondensatoren 22pF evtl. SMD:einlöten (b2) (b1)<br />
( ) C2 :Kondensator 22pF evtl. SMD :einlöten (c2) (c1)<br />
( ) So :DIL-14 Präzisions-Sockel :<strong>mit</strong> Platine verbinden (d3) (d7)<br />
Die Methoden pcb.list und pcb.kit sind einfach zu verstehen<br />
und eignen sich gut für das Studium von Shellscripten.<br />
Wenn im Rahmen von Unterricht für größere Gruppen Platinen<br />
hergestellt werden sollen, gibt es eine Methode, die mehrere<br />
Layouts nebeneinander ausdruckt:<br />
pcb.mlayout quarz.pcb 5 3<br />
Dieser Aufruf zeichnet eine Ätzmaske für 15 (5 × 3)Platinen.<br />
Falls der Leser keine Platinen ätzen möchte, sind die Layouts<br />
so ausgelegt, dass man die Schaltungen auch auf handelsüblichen<br />
Lochrasterplatinen aufbauen kann.<br />
1 Bausätze der früheren Firma Heathkit hatten ähnliche Listen zum<br />
Abhaken.
KAPITEL 10. PLATINENLAYOUTS 101<br />
Abbildung 10.1: Ätzmaske für 15 Platinen.<br />
10.3 Platinen ätzen<br />
Für die Experimente <strong>mit</strong> dem Mikrocontroller werden zwei<br />
Leiterplatten benötigt. Auf einer Platine im Europaformat<br />
(160 mm × 100 mm) wird das Computersystem aufgebaut. Eine<br />
kleinere Platine dient als Verbindungsglied 2 zwischen PC<br />
und Mikrocontroller.<br />
Beide Schaltungen wurden auf Lochrasterplatinen entwickelt.<br />
Wer dieses Kapitel überspringen möchte, kann die Schaltungen<br />
ebenso auf Lochrasterplatten aufbauen. Die Vor- und<br />
Nachteile muss man selbst abwägen.<br />
Platinen ätzen basiert auf foto-chemischen Verfahren, wie sie<br />
in der Fotographie wie auch bei der Herstellung von Halbleitern<br />
angewendet werden. Für Kleinserien werden Maschinen<br />
<strong>mit</strong> Pumpen und Heizungen angeboten, die Aquarien ähnlich<br />
sind. Das hier vorgestellte Verfahren für Einzelstücke kommt<br />
dagegen <strong>mit</strong> Entwicklerschalen aus.<br />
2 Die englische Bezeichnung ist Interface.
KAPITEL 10. PLATINENLAYOUTS 102<br />
10.3.1 Material<br />
Folgende Materalien werden benötigt:<br />
2 Fotobeschichtete Epoxydplatinen im Europaformat<br />
1 Laubsäge <strong>mit</strong> Sägeblättern<br />
1 Glasscheibe größer 160 mm × 100 mm<br />
1 Schutzbrille<br />
3 g Natriumhydroxyd als Granulat für Entwickler<br />
300 ml Wasser<br />
2 Entwicklerwannen 180 mm × 105 mm<br />
1 Kunststoffpinzette<br />
300 ml Wasser<br />
50 ml Salzsäure <strong>mit</strong> der Konzentration 32 %<br />
50 ml Wasserstoffperoxid <strong>mit</strong> der Konzentration 30 %<br />
1 Kunststoffflasche für verbrauchtes Ätz<strong>mit</strong>tel<br />
1 Kunststofftrichter<br />
1 Bohrmaschine <strong>mit</strong> Bohrer von 0,8 mm Durchmesser<br />
10 ml Aceton<br />
1 Kolophoniumblock<br />
1 kleiner Pinsel<br />
Die Chemikalien erhält man in Apotheken. Kolophonium 3<br />
gibt es in Musikgeschäften. Die Glasscheibe bekommt man<br />
am einfachsten <strong>mit</strong> einem Bilderrahmen.<br />
3 Kolophonium ist ein dem Bernstein ähnliches Harz-Produkt. Es<br />
wird im Geigenhandel in Blöcken verkauft, die etwa so groß wie Streichholzschachteln<br />
sind. Musiker streichen da<strong>mit</strong> ihre Bögen ein.
KAPITEL 10. PLATINENLAYOUTS 103<br />
10.3.2 Belichtungsmaske<br />
Die Belichtungsmaske wird <strong>mit</strong> dem Laserdrucker oder einem<br />
Fotokopierer auf Overheadfolie gedruckt. Da der Toner nicht<br />
gänzlich lichtdicht ist, muss man nachgebessern: Die (rauhe)<br />
Druckseite <strong>mit</strong> wasserlöslicher schwarzer Tinte bestreichen.<br />
Nach Eintrocknen der Tinte wird die Folie <strong>mit</strong> einem feuchten<br />
Tuch gesäubert.<br />
Eine zweite Methode besteht darin, zusätzlich eine seitenverkehrte<br />
Folie auszudrucken und die beiden Folien <strong>mit</strong> der<br />
Druckseite gegeneinander zu fixieren.<br />
Seit neuerem verwende ich eine dritte Methode, die einige<br />
Vorteile bietet: Mit Laser- oder Tintendrucker wird das Layout<br />
auf normalem Papier ausgedruckt. Der Ausdruck wird <strong>mit</strong><br />
Speiseöl in einen opaken Zustand versetzt, der genügend Licht<br />
zum Belichten der Platine durchläßt. Der einzige Nachteil des<br />
Verfahrens besteht darin, dass die Belichtungszeit gegenüber<br />
Folien verdoppelt werden muss.<br />
Eine falsch herum belichtete Platine ist vermeidbarer Abfall.<br />
Wenn das Layout keinen Schriftzug enthält, an dem man die<br />
richtige Orientierung erkennen kann, sollte man die dem Licht<br />
zugewandte Seite <strong>mit</strong> permanentem Filzstift als solche kennzeichnen.<br />
Bei der dritten Methode wird die Papierseite <strong>mit</strong><br />
der Druckerschwärze direkt auf den Fotolack gelegt. Das muss<br />
natürlich bereits beim Ausdruck berücksichtigt werden.
KAPITEL 10. PLATINENLAYOUTS 104<br />
10.3.3 Belichtung<br />
Die Platine wird <strong>mit</strong> der Laubsäge auf das passende Maß zugeschnitten.<br />
Bei gedämpften Licht (z. B. im Keller) wird die<br />
Schutzschicht entfernt. Unter der Belichtungsmaske wird die<br />
Platine nun in den Fotorahmen eingespannt, so dass die Glasplatte<br />
die Maske plan auf den Fotolack presst.<br />
Der problematische Vorgang bei der Platinenherstellung ist<br />
die richtige Belichtungszeit. Neben Temperatur, Konzentration<br />
und Alter der Chemikalien treten hier die breitesten<br />
Schwankungen auf, wie folgende Tabelle verdeutlicht:<br />
Lichtquelle Abstand Zeit<br />
[cm] [min]<br />
Höhensonnne (UV-A) 1000 W 50 1<br />
Sonne 5<br />
Nitraphotlampe 250 W 50 7<br />
Hallogenlampe 300 W 40 40<br />
Kryptonlampe 150 W 20 60<br />
Kryptonlampe 60 W 20 120<br />
Weiterhin haben Platinen von verschiedenen Herstellern unterschiedliche<br />
Belichtungszeiten. Auch das Alter der Platine<br />
wirkt sich aus: Ist der Fotolack sehr alt, verkürzt sich die<br />
Belichtungszeit. Aus diesem Grund haben gute Platinen ein<br />
Datum aufgedruckt.<br />
Der Abstand von der Lichtquelle wirkt sich quadratisch auf<br />
die Belichtungszeit aus: Zum Beispiel erfordert 1,4-facher Abstand<br />
die doppelte Zeit, doppelter Abstand bereits 4-fache
KAPITEL 10. PLATINENLAYOUTS 105<br />
Zeit. Außerdem muss der Abstand zwischen Lampe und Platine<br />
größer sein als die Diagonale der Platine. Die Lichtquelle<br />
darf den Fotolack nicht überhitzen.<br />
Die einfache Belichtung <strong>mit</strong> Sonnenlicht hat den Nachteil,<br />
dass Faktoren wie Luftfeuchtigkeit, Sonnenstand und Luftverschmutzung<br />
die Lichtmenge beeinflussen. Trotzdem ist die<br />
Methode praktikabel, da der Film auf den Platinen unkritisch<br />
ist, verschiedene Belichtungen also zum Erfolg führen.<br />
Zur Er<strong>mit</strong>tlung der richtigen Belichtungszeit gehe man nach<br />
folgender Methode aus dem Fotolabor vor:<br />
Ein Teststreifen Platinenmaterial der Größe 2 cm × 10 cm herrichten<br />
und <strong>mit</strong> dem Filzstift in 5 quadratische Felder unterteilen.<br />
Mit Hilfe der obigen Angaben schätzt man die Belichtungszeit,<br />
zum Beispiel 6 Minuten. Die Felder <strong>mit</strong> dem Viertel,<br />
dem Halben, dem Ganzen, dem Doppelten und Vierfachen der<br />
Zeit belichten, indem der Teststreifen während des Belichtens<br />
zu 80, 60, 40, 20 und 0 % abdeckt. Zwischen Abdeckung und<br />
Belichtungsmaske darf keine Glasscheibe gelegt werden, da<br />
das Streulicht das Ergebnis verfälscht. Unser Beispiel könnten<br />
wir ab 17:00 Uhr zu 80 % abdecken und belichten. Um<br />
17:12 Uhr werden zwei Felder, um 17:18 Uhr drei Felder, um<br />
17:21 Uhr vier Felder, um 17:22:30 Uhr der ganze Streifen bis<br />
17:24 Uhr belichtet.<br />
Statt Teststreifen kann man auch mehrere Versuche <strong>mit</strong> der<br />
kleinen Oszillatorplatine des Experimentiersystems machen.<br />
Woran man das richtig belichtete Feld erkennt, folgt in der<br />
Beschreibung des Entwicklungsvorgangs:
KAPITEL 10. PLATINENLAYOUTS 106<br />
10.3.4 Entwicklung<br />
Die Schutzbrille ist beim Umgang <strong>mit</strong> Entwicklerlauge und<br />
Ätzsäure unverzichtbar. Die Chemikalien können bei unsachgemäßer<br />
Anwendung Personen- und Sachschäden anrichten!<br />
Die Nebenprodukte Chlorgas und Ozon sind zwar sehr kurzlebig,<br />
aber unangenehme Atemgifte. Alle Chemikalien sind<br />
immer innerhalb ihrer Dosierung zu betrachten. Selbst reiner<br />
Sauerstoff ist giftig. Eine Liste von verschiedenen Konzentrationen<br />
und ihrer Anwendungen soll das verdeutlichen:<br />
Natronlauge 1 % Platinenherstellung:<br />
Entwickeln<br />
Wasserstoffperoxid 30 % Platinenherstellung:<br />
Kupfer oxidieren<br />
Wasserstoffperoxid 10 % Haare blond bleichen<br />
Wasserstoffperoxid 3 % Wunden desinfizieren<br />
Salzsäure 38 % konzentrierte Lösung<br />
Salzsäure 32 % technische Lösung<br />
Salzsäure 6 % Platinenherstellung<br />
Kupferoxid auflösen<br />
Salzsäure 0,5 % Magensaft<br />
Die 3 g Natriumhydroxid in 0,3 l handwarmem Wasser 4<br />
auflösen. Die belichtete Platine einlegen. Nach ca. 10, spätestens<br />
120 Sekunden müssen sich die belichteten Lackflächen<br />
verfärben, auflösen und wegschwimmen. Was bleibt, ist unterbelichtet.<br />
Leiterbahnen, die sich auflösen, sind überbelich-<br />
4 Eine Minderung der Temperatur um ein Grad führt bereits zu einer<br />
Verdopplung der Entwicklungszeit. Kellertemperatur ist zu kühl.
KAPITEL 10. PLATINENLAYOUTS 107<br />
tet. Nur Leiterbahnen, die nach dem Laugenbad unter fließendem<br />
Wasser klar sichtbar sind, wurden richtig belichtet.<br />
Beim nachfolgenden Ätzen müssen die freien Flächen sofort<br />
ermatten, sonst wurde unterbelichtet. 20 % Nachbelichten<br />
ohne Maske und wiederholtes Entwickeln ist eine mögliche<br />
Notlösung. Eine warme Lauge führt zu schnellen und scharfen<br />
Ergebnissen. Lange Entwicklungszeiten auf Grund kühler<br />
Lösung wirken sich negativ auf die Qualität der fertigen Platine<br />
aus.<br />
Der unbenutzte Entwickler kann in einer Kunststoffflasche unter<br />
sicherem Luftabschluß aufgehoben werden. Er reagiert <strong>mit</strong><br />
dem Kohlendioxid der Luft. Der benutzte Entwickler ist nur<br />
einige Wochen haltbar. Die Entsorgung <strong>mit</strong> viel Wasser ist<br />
unkritisch.<br />
10.3.5 Ätzen<br />
Die Salzsäure <strong>mit</strong> dem Wasserstoffperoxid in der Wanne bei<br />
Zimmertemperatur ansetzen. Wasser NICHT zur Säure gießen,<br />
sondern zuerst das Wasser in die Wanne füllen, da es<br />
sonst spritzen kann. Die Platine <strong>mit</strong> der Kupferseite nach oben<br />
einlegen und <strong>mit</strong> einem Streifen Plastikfolie die Flüssigkeit so<br />
bewegen, dass die entstehenden Gasblasen an die Oberfläche<br />
steigen. Nach ca. 10 bis 15 Minuten sollten die Leiterbahnen<br />
auf der Platine herausgeätzt sein. Das in Kupferchlorid umgesetzte<br />
Kupfer färbt die Lösung blaugrünlich.<br />
Wird sie aufgehoben, vor der Wiederverwendung Wasserstoffperoxid<br />
nachfüllen, da dieses in wenigen Tagen in Sauerstoff
KAPITEL 10. PLATINENLAYOUTS 108<br />
und Wasser zerfällt. Falls es Zweifel an der Qualität des Wasserstoffperoxids<br />
gibt, kann man <strong>mit</strong> Katalysatoren wie Braunstein<br />
aus Zink-Kohle-Batterien den Sauerstoffgehalt prüfen.<br />
Wegen des Kupferchlorids muss das Ätzbad letztendlich als<br />
Sondermüll entsorgt werden! Vor dem Verschließen der Kunststoffflasche<br />
die Lösung einige Tage ausgasen lassen.<br />
Die folgende Berechnung soll den Ätzvorgang verständlich<br />
machen:<br />
Das Kupfer wird zu Kupferchlorid und Wasser umgesetzt:<br />
H2O2 → O + H2O<br />
Cu + O → CuO<br />
CuO + 2 HCl → CuCl2 + H2O<br />
Ein Mol eines Stoffes enthält 6 ∗ 10 23 Moleküle. 5<br />
Ein Mol Cu benötigt ein Mol H2O2 und zwei Mol HCl. Der<br />
Zusammenhang zwischen Mol und Gramm ergibt sich aus den<br />
Atomgewicht der Elemente. In Gramm ausgedrückt: 64 g Cu<br />
brauchen 34 g H2O2 und 73 g HCl.<br />
Eine Europaplatine ist <strong>mit</strong> 10 cm × 16 cm × 0.0035 cm Kupfer<br />
beschichtet. Bei einer Dichte des Kupfers von 8,9 g<br />
cm3 sind das<br />
fast 5 g Kupfer.<br />
Für eine Europaplatine werden so<strong>mit</strong><br />
5 Diese Zahl heißt Avogadro-Konstante. In deutschsprachiger Literatur<br />
wird sie oft auch Loschmidt-Konstante genannt.
KAPITEL 10. PLATINENLAYOUTS 109<br />
ca. 9 g 30 %ige Wasserstoffperoxidlösung<br />
und 18 g 32 %ige Salzsäure<br />
verbraucht. Da<strong>mit</strong> die Reaktionen einigermaßen schnell ablaufen,<br />
müssen in der Ätzlösung ca. das dreifache an Salzsäure<br />
und ca. das sechsfache Wasserstoffperoxid und reichlich Wasser<br />
vorhanden sein. Der Überschuß an Chemikalien ist der<br />
Tribut, den das einfache Verfahren fordert.<br />
Ein anderes verbreitetes Ätzverfahren <strong>mit</strong> Eisen-III-Clorid ...<br />
2 FeCl3 + Cu → 2 FeCl2 + CuCl2<br />
... hat den gravierenden Nachteil, dass es bei Zimmertemperatur<br />
sehr langsam ist (ca. 10 bis 20 Stunden). Das Erwärmen<br />
dieses Ätzbades auf ca. 45 Grad bedeutet aber einen erheblichen<br />
Umstand.<br />
10.3.6 Abschlussarbeiten<br />
Die Löcher bohren und alles entgraten. Mit einem Tuch und<br />
Aceton kann der Fotolack entfernt werden, da dieser das Löten<br />
behindert. Zum Schutz des Kupfers und als Flusshilfe beim<br />
Löten eine Mischung aus einem Teelöffel Aceton und etwas<br />
abgeschabtem Kolophonium über die Leiterbahnen streichen.<br />
Die Platine ist nun fertig zum Bestücken.
Kapitel 11<br />
Schaltalgebra<br />
11.1 Boolesche Algebra<br />
Die Boolesche Algebra 1 ist jener Teil der Mathematik, der<br />
sich <strong>mit</strong> zweiwertigen Variablen beschäftigt. Die Aussagen gelten<br />
für Systeme, die <strong>mit</strong> ja – nein, wahr – falsch, geöffnet –<br />
geschlossen, oder eben ,,Spannung” – ,,keine Spannung” beschrieben<br />
werden.<br />
Das Interessante an diesem Teil der Mathematik ist, dass die<br />
meistens untersuchte Grundmenge {0, 1} so klein ist, dass die<br />
daraus entstehenden Grundfunktionen durchaus überschaubar<br />
sind. Dies ist letztendlich die Ursache, dass digitale Geräte<br />
sich gegenüber analogen so durchsetzen.<br />
1864).<br />
1 Benannt nach dem englischen Mathematiker George Boole (1815 –<br />
110
KAPITEL 11. SCHALTALGEBRA 111<br />
Betrachtet man zweidimensionale Funktionen f(x)=y, die bereits<br />
Stoff für etliche Schuljahre Mathematik bieten, so gibt<br />
es für 0 und 1 nur noch vier Funktionen:<br />
f(x) = 0 Konstanz<br />
f(x) = 1 Konstanz<br />
f(x) = x Identität<br />
f(x) = ¯x Negation<br />
Realisiert man die vier Funktionen durch elektronische Schaltungen,<br />
so ist nur die Negation nennenswert. Man benötigt<br />
zwei Widerstände und einen Transistor.<br />
Auch die nächste Stufe, die dreidimensionalen Funktionen<br />
f(x,y)=z bilden eine überschaubare Menge <strong>mit</strong> 16 Elementen.<br />
Ein bekannter Vertreter ist die Und-Funktion, auch Konjunktion<br />
genannt:<br />
f(0,0) = 0<br />
f(0,1) = 0<br />
f(1,0) = 0<br />
f(1,1) = 1<br />
Da die Und-Funktion der Multiplikation der natürlichen Zahlen<br />
ähnelt, wird sie oft wie eine Muliplikation dargestellt,<br />
manchmal auch <strong>mit</strong> dem Operator & oder <strong>mit</strong> ∧.<br />
Die Oder-Funktion wird ebenfalls oft verwendet. Wegen ihrer<br />
Verwandschaft zur Addition wird sie manchmal durch + symbolisiert.<br />
Ein anderes Symbol ist das ∨, das an das lateinische
KAPITEL 11. SCHALTALGEBRA 112<br />
Wort für ,,oder” nämlich ,,vel” erinnert. Die Punkt vor Strich<br />
Regel gilt analog für ∧ und ∨.<br />
Liste der Funktionen <strong>mit</strong> zwei Eingangsvariablen<br />
x = x = 0 1 0 1<br />
y = y = 0 0 1 1<br />
f(x,y) = 0 = 0 0 0 0 Konstanz<br />
f(x,y) = x∧y = 0 0 0 1 Konjunktion, und<br />
f(x,y) = ¯x∧y = 0 0 1 0 Inhibition<br />
f(x,y) = y = 0 0 1 1 Identität<br />
f(x,y) = x∧¯y = 0 1 0 0 Inhibition<br />
f(x,y) = x = 0 1 0 1 Identität<br />
f(x,y) = x∧¯y ∨ ¯x∧x = 0 1 1 0 Antivalenz, exklusiv<br />
f(x,y) = x ∨ y = 0 1 1 1 Disjunktion, oder<br />
f(x,y) = ¯x∧¯y = 1 0 0 0 NOR, weder noch<br />
f(x,y) = x∧y ∨ ¯x∧¯y = 1 0 0 1 Äquivalenz<br />
f(x,y) = ¯x = 1 0 1 0 Negation<br />
f(x,y) = ¯x ∨ y = 1 0 1 1 Implikation<br />
f(x,y) = ¯y = 1 1 0 0 Negation<br />
f(x,y) = x ∨ ¯y = 1 1 0 1<br />
f(x,y) = ¯x∨¯y = 1 1 1 0 NAND<br />
f(x,y) = 1 = 1 1 1 1 Konstanz<br />
Bemerkenswert ist, dass sowohl NAND- als auch NOR-<br />
Funktion geeignet sind, alle 16 Funktionen durch geeignete<br />
Verknüpfung nachzubilden. Hierin liegt die Ursache, dass diese<br />
den Grundbaustein digitaler IC-Familien bilden.
KAPITEL 11. SCHALTALGEBRA 113<br />
11.2 TTL<br />
Die Entstehung von Bausteinen läuft immer nach einem gewissen<br />
Schema. So entstand in den 60er Jahren eine Familie<br />
von digitalen integrierten Schaltungen, die TTL genannt wurde.<br />
TTL steht für Transistor-Transistor-Logik im Gegensatz<br />
zu Dioden-Transistor-Logik und anderen Techniken.<br />
Abbildung 11.1: IC SN7400 <strong>mit</strong> 4 NAND-Gattern<br />
Es entstand die Bausteinserie 74xxx, deren Grundvertreter<br />
das IC 7400 ist. Wie von Bausteinen erwartet, hat die Familie<br />
viele gemeinsame Eigenschaften wie<br />
• genormte Gehäuse<br />
• gleiche Versorgungsspannung<br />
• zueinander passende Aus- und Eingänge<br />
• ähnliches Zeitverhalten
KAPITEL 11. SCHALTALGEBRA 114<br />
Für Bausteinsysteme typisch, entstanden bald große Umsätze,<br />
was Rationalisierung und kleine Preise nach sich zog. Die 74er<br />
Familie hat in der Größenordnung 100 Mitglieder, von denen<br />
einige erwähnt werden sollen:<br />
7400 Vier NAND-Gatter <strong>mit</strong> 2 Eingängen<br />
7402 Vier NOR-Gatter <strong>mit</strong> 2 Eingängen<br />
7404 Sechs NICHT-Gatter (Inverter)<br />
7408 Vier UND-Gatter <strong>mit</strong> 2 Eingängen<br />
7410 Drei NAND-Gatter <strong>mit</strong> 3 Eingängen<br />
7430 Ein NAND-Gatter <strong>mit</strong> 8 Eingängen<br />
7432 Vier OR-Gatter <strong>mit</strong> 2 Eingängen<br />
7471 RS-Flipflop <strong>mit</strong> drei Eingängen, Preset und Clear<br />
7483 4 Bit Volladdierer<br />
74367 Sechs Bus-Leistungstreiber <strong>mit</strong> zwei Enable<br />
74681 4 Bit Binär Akkumulator<br />
Je komplexer die Schaltung, desto kürzer ist oft der Zeitraum<br />
der Produktion. Die Grundfunktionen werden nach wie vor<br />
hergestellt und angeboten, allerdings wandeln sich auch die<br />
Technologien. Es gibt sehr schnelle 74S00 (Schottky), stromsparende<br />
74LS00 (low power Schottky), schnelle und stromsparende<br />
74HC00 (high speed CMOS) und viele weitere Technologien,<br />
die nach wie vor neu auf den Markt kommen.<br />
Zu unserem Mikrocontroller passend ist die HC-Technologie,<br />
die inzwischen gut verfügbar ist. Betreibt man die Schaltung<br />
<strong>mit</strong> 5 Volt, wird auch ein alter 7400 noch funktionieren. Man<br />
konsultiere das Datenblatt für folgende Werte:<br />
• Versorgungsspannung
KAPITEL 11. SCHALTALGEBRA 115<br />
• Belastbarkeit der Ausgänge (Fan-Out)<br />
• Spannungsbereiche für High und Low<br />
11.3 Flip-Flop<br />
Eine wichtige Funktion erhält man durch Rückführung des<br />
Ergebnisses in den Eingang. Die Schaltung bekommt ein<br />
Gedächtnis, es entsteht ein RS-Flip-Flop. RS steht für set und<br />
reset.<br />
Abbildung 11.2: Prellfreie Taste<br />
Betrachtet man die Arbeitsweise der Schaltung in Abbildung<br />
11.2, so muss man für Ein- und Ausgänge x,y,z acht Zustände<br />
untersuchen:
KAPITEL 11. SCHALTALGEBRA 116<br />
x y z a<br />
0 0 0 1 unmöglich wegen Taster<br />
0 0 1 1 unmöglich wegen Taster<br />
0 1 0 1 unmöglich wegen ā∧¯x=z<br />
0 1 1 0<br />
1 0 0 1<br />
1 0 1 1 unmöglich wegen ā∧¯x=z<br />
1 1 0 1<br />
1 1 1 0<br />
Zwei Zustände sind wegen der Funktion des Tasters<br />
unmöglich: Der Kontakt des Tasters kann nur <strong>mit</strong> einem der<br />
beiden Eingänge x oder y verbunden sein, oder er befindet<br />
sich gerade auf dem Weg dazwischen.<br />
Zwei weitere Zustände sind durch die Rückführung des Signals<br />
z unmöglich, da z nur einen Wert annehmen kann.<br />
Simuliert man die beiden Schaltvorgänge, wobei es durchaus<br />
passiert, dass der Schaltkontakt wie ein Ball mehrfach vom<br />
Kontakt wieder weghüpft, so reicht das Hilfssignal a, um den<br />
Ausgang z von diesen unerwünschten Prellern zu befreien. Befindet<br />
sich der Schalter zwischen den Kontakten, erinnert sich<br />
die Schaltung an den letzten regulären Schaltzustand.
KAPITEL 11. SCHALTALGEBRA 117<br />
Einschalten Ausschalten<br />
x y a z alternativ x y a z<br />
1 0 1 0 0 1 0 1<br />
1 1 1 0 1 1 0 1<br />
0 1 0 1 1 0 1 0<br />
1 1 0 1 1 1 1 0<br />
0 1 0 1 1 0 1 0<br />
: :<br />
: :<br />
Die beiden Gatter NAND3 und NAND4 wurden nur deshalb<br />
verwendet, um die Eingänge des ICs nicht offen zu lassen,<br />
was bei einigen Technologien zu Schwingungen führt, welche<br />
Schaltung sogar zerstören können.<br />
Für unseren späteren Mikrocontroller kann die prellfreie Taste<br />
die Funktion eines Quarzoszillators <strong>mit</strong> manuell gespeister<br />
Frequenz übernehmen.
Teil III<br />
Mikrocontroller<br />
118
Kapitel 12<br />
Wurzeln<br />
Vor den <strong>Mikrocontrollern</strong> entstanden die Mikroprozessoren.<br />
Die Firma Intel hatte den Auftrag, einen damals hoch integrierten<br />
Baustein für den Einsatz in Taschenrechnern zu entwerfen.<br />
Der Ingenieur Ted Hoff legte einen Entwurf vor, der<br />
bald als allgemein einsetzbare 4-Bit CPU erkannt wurde. Ab<br />
dem 15. November 1971 wurde der 4004 für 200 Dollar pro<br />
Stück angeboten. 1972 folgte eine 8-Bit Version, der 8008.<br />
Der 8080 wurde bereits zum Welterfolg, dem die Typen 8085<br />
8086 8088 80186 80286 80386 80486 und Pentium folgten.<br />
Neben Intel haben auch andere Firmen versucht, den Markt<br />
der Mikroprozessoren zu gewinnen. Mostek entwickelte den<br />
6502, der in KIM, Comodore Pet und Apple II rechnete. Zilog<br />
verbesserte den 8085 zum Z80, der im Tandy TRS80 arbeitete.<br />
Bald kamen Mikroprozessoren <strong>mit</strong> 16 Bit Wortbreite auf den<br />
119
KAPITEL 12. WURZELN 120<br />
Abbildung 12.1: KIM-1 Mikrocomputer der Firma MOS aus<br />
dem Jahr 1975.
KAPITEL 12. WURZELN 121<br />
Markt. Zilog Z8000 und Texas Instruments TMS9900 sind<br />
von Motorolas M86000 und Intels 8086 wohl überholt worden.<br />
Motorola durfte an Apple für den Macintosh liefern und IBM<br />
hatte sich für eine Intel-CPU entschieden.<br />
Das Registermodell aller PC-kompatiblen CPUs ist zum<br />
8080 abwärtskompatibel. So konnten für den 8080 entwickelte<br />
Assembler-Programme durch einfaches Neuübersetzen auf<br />
den 8086 portiert werden. Der 8086 war intern und extern<br />
eine 16-Bit-CPU. Der 8088 war intern ein 8086, extern war<br />
er noch eine 8-Bit-CPU. Da ein Mikrocomputer <strong>mit</strong> 8-Bit im<br />
Jahr 1981 noch erheblich billiger als ein Mikrocomputer <strong>mit</strong><br />
16 Bit hergestellt werden konnte, wählte IBM den Kompromiss<br />
<strong>mit</strong> der 8088-CPU für den ersten IBM-PC. Erst im Jahr<br />
1984 wurde die PC-Architektur auf 16 Bit umgestellt. Dieser<br />
PC hieß IBM-AT und hatte eine 80286-CPU.<br />
Der technologische Durchbruch war die 80386-CPU. Sie hatte<br />
eine Speicherverwaltung auf dem Chip und kannte verschiedene<br />
Prioritätsstufen. Dies ermöglichte ihren Einsatz unter<br />
Bedingungen eines Rechenzentrums. Die Prozesse mehrerer<br />
Benutzer konnten gegenseitig abgesichert werden. So entstanden<br />
für den 80386 mehrere Unixversionen, von denen sich bekanntlich<br />
Linux am besten durchgesetzt hat. Der erste IBM-<br />
PC <strong>mit</strong> 80386 war das Modell 80, das im Jahr 1987 auf den<br />
Markt kam.<br />
Inzwischen werden sogar Supercomputer durch Zusammenschluß<br />
vieler preiswerter Mikroprozessoren gebaut.<br />
Der 80186 ist ein 8086, der einige Teile des Ein-/Ausgabewerks
KAPITEL 12. WURZELN 122<br />
<strong>mit</strong> auf den Chip bekommen hat.<br />
12.1 Mikrocontroller<br />
Während auf Seite der Mikroprozessoren die Möglichkeiten<br />
der höheren Integration zur Leistungssteigerung genutzt wurden,<br />
war es bei kleinen Anwendungen möglich, neben Rechenwerk<br />
und Steuerwerk das Ein-/Ausgabewerk <strong>mit</strong> auf den Chip<br />
zu nehmen. Die Mikrocontroller wurden geboren. Richtig interessant<br />
wurde ihr Einsatz in Telefonen, Fernsehern, Waschmaschinen,<br />
Autos usw., als auch das Speicherwerk in das IC<br />
integriert werden konnte.<br />
Einer der klassischen Mikrocontroller ist der 8051 der Firma<br />
Intel. Es gibt viele Varianten. Ein Vorzug dieser Familie ist,<br />
daß verschiedene Hersteller Bausteine anbieten.<br />
Die PIC Mikrocontroller der Firma Microchip werden vor allem<br />
in kleinen Systemen gerne eingesetzt.<br />
Der MSP430 von Texas Instruments ist ein weiterer moderner<br />
Mikrocontroller.<br />
Ferner gibt es eine schwer überschaubare Typenvielfalt verschiedener<br />
Hersteller, die meist direkt in Industrieprodukten<br />
eingesetzt und deshalb einzeln weniger angeboten werden.<br />
In diesem Buch wird ein AVR Mikrocontroller eingesetzt, weil<br />
er folgende Kritierien erfüllt:<br />
• Gute Dokumentation ist leicht erhältlich.
KAPITEL 12. WURZELN 123<br />
• Der Baustein ist in einem Gehäuse erhältlich, was manuelle<br />
Anfertigung von Prototypen erleichtert (DIL).<br />
• Eine Programmierschnittstelle, die im Zielsystem funktioniert<br />
(ISP), ermöglicht schnelles Testen ohne Umsetzen<br />
des Bausteins.<br />
• Ein leicht löschbarer Programmspeicher (Flash) beschleunigt<br />
ebenfalls die Reprogrammierung.<br />
• Programmierhardware in verschiedenen Ausführungen<br />
ist sehr preiswert verfügbar.<br />
• Programmiersoftware ist <strong>mit</strong> Quellen vorhanden.<br />
• Preiswerter C-Compiler ist <strong>mit</strong> Quellen verfügbar.<br />
• Das System ist skalierbar, was verschiedenste Projekte<br />
ermöglicht.<br />
• Unterstützung wird von verschiedenen Betriebssystemen<br />
angeboten.<br />
12.1.1 AVR Mikrocontroller<br />
Die Firma Atmel spezialisierte sich anfangs auf Halbleiterspeicher,<br />
die wie ROMs 1 ihren Inhalt ohne Spannungsversorgung<br />
erhalten, trotzdem wie RAMs 2 innerhalb der endgülti-<br />
1 Abkürzung für read only memories<br />
2 Abkürzung für random access memories, Speicher <strong>mit</strong> wahlfreiem<br />
Zugriff, so wie es das von-Neumann-Modell fordert.
KAPITEL 12. WURZELN 124<br />
gen Schaltung mehrfach beschrieben und gelöscht werden<br />
können. Diese Speicher heißen EEPROMs 3 . Während RAMs<br />
beliebig oft gelöscht werden dürfen, sind EEPROMs in dieser<br />
Hinsicht stark beschränkt. Ferner dauert das Ändern des<br />
Inhalts länger. Typische Anwendung sind Scheck- und Speicherkarten.<br />
EEPROMs eignen sich vorzüglich als Programmspeicher von<br />
<strong>Mikrocontrollern</strong>. So stellte Atmel zuerst 8051 kompatible<br />
Mikrocontroller her, entwickelte aber auch einen eigenen<br />
Typ, den AVR. Der erste AVR Mikrocontroller war<br />
der AT90S1200 aus dem Jahr 1997. Er hatte ein 20-poliges<br />
Gehäuse <strong>mit</strong> 1 KB Programmspeicher, 64 Byte EEPROM,<br />
15 Ein-/Ausgabeleitungen, Timer und Analogkomperator.<br />
Da er noch kein RAM für einen Stack hat, kann man nur<br />
zwei geschachtelte Unterprogrammsprünge ausführen. Der<br />
AT90S1200 eignet sich deshalb nur zur Programmierung <strong>mit</strong><br />
Assembler.<br />
Nach diesem Modell kam ein ganze Serie von <strong>Mikrocontrollern</strong><br />
für verschiedenste Anwendungen auf den Markt. Gemeinsame<br />
Eigenschaft der AVR-Serie sind:<br />
• Registermodell <strong>mit</strong> 32 Registern<br />
• Flash von 1..128.. KB als Programmspeicher<br />
• EEPROM von 0..4.. KB, analog einer Festplatte verwendbar<br />
3 Abkürzung für electric erasable programable read only memories
KAPITEL 12. WURZELN 125<br />
• RAM von 0..4.. KB<br />
• 3..53.. Ein-/Ausgabeleitungen<br />
• 0..11.. Analogeingänge<br />
• 8..64.. poliges Gehäuse<br />
• weitgehend zueinander kompatibel<br />
• innerhalb der Spezifikation <strong>mit</strong> jeder Frequenz taktbar<br />
• in der Anwendungsschaltung reprogrammierbar<br />
Für unser System wurde ursprünglich der AT90S4433 ausgewählt.<br />
Dieser Prozessor war vergleichbar <strong>mit</strong> den alten<br />
Mikrocomputer-Entwicklungssystemen, hatte dabei ein kleines<br />
Gehäuse und einen moderaten Preis. Die AT90-Serie<br />
wird inzwischen durch die ATtiny-Serie im unteren und die<br />
ATmega-Serie im oberen Bereich ersetzt. Der ATmega8 ist<br />
pinkompatibel zum AT90S4433, auch preislich ist er <strong>mit</strong> dem<br />
älteren Typ vergleichbar. Seine inneren Werte haben sich quasi<br />
verdoppelt:
KAPITEL 12. WURZELN 126<br />
AT90S4433 ATmega8<br />
maximaler Takt [Mhz] 8 16<br />
interner kalibrierter Oszillator x<br />
Befehle incl. Multiplikation 118 130<br />
Sleep-modes 2 5<br />
Flash [KB] 4 8<br />
Flash selbst programmierbar x<br />
Löschzyklen des Flash 1000 10.000<br />
EEPROM [Bytes] 256 512<br />
Löschzyklen des EEPROM 100.000 100.000<br />
RAM [Bytes] 128 1024<br />
8 Bit-Timer 1 2<br />
PWM-Kanäle 1 3<br />
I/O Lines (Reset,Xtal1,Xtal2) 20 23<br />
Serial I/O UART USART<br />
2 wire serial Interface x<br />
2.56V AD-Spannungsreferenz x<br />
Trotz der Verbesserungen wird bei der Herstellung für den<br />
ATmega8 weniger Siliziumfläche verbraucht. Dies ist ein wesentlicher<br />
variabler Kostenfaktor bei der Herstellung von ICs.<br />
Zur Abbildung 12.2 sei noch folgendes bemerkt: Stackpointer<br />
(SP) und Statusregister (SR) liegen zusätzlich im Adressraum<br />
des Ein-/Ausgabewerks (I/O). Die Adressräume von Registerwerk<br />
und Ein-/Ausgabewerk liegen zusätzlich im Adressraum<br />
des Datenspeichers (RAM). Dadurch vereinigt der AVR die<br />
Vorteile von zwei Konzepten:<br />
• Schnelle und effiziente Spezialbefehle für Register und<br />
I/O.
KAPITEL 12. WURZELN 127<br />
Abbildung 12.2: Architektur des ATmega8
KAPITEL 12. WURZELN 128<br />
• Variable Adressierungsmöglichkeiten für Register und<br />
I/O über die memory mapped Adressierung.<br />
Programmspeicher (Flash) und EEPROM haben jeweils einen<br />
eigenen Adressraum.<br />
Programmspeicher und EEPROM sind über Register des Ausgabewerks<br />
beschreibbar.<br />
Im Jahr 2004 will Atmel die Typen ATmega48, ATmega88<br />
und ATmega168 <strong>mit</strong> 4, 8 und 16 KB Flash im 28-poligen<br />
Gehäuse herausbringen.<br />
Diese Prozessoren haben weitere Vorteile:<br />
• Der Energieverbrauch ist durch kleinere Versorgungsspannung,<br />
neue Oszillatorschaltung und abschaltbare<br />
I/O-Bereiche reduzierbar.<br />
• Der Takt kann bis zu 20 Mhz eingestellt werden.<br />
• Alle I/O-Pins können einen Interrupt auslösen.<br />
• Der timer0 kennt CTC-Mode.<br />
• Alle Analogeingänge haben 10 Bit Auflösung.<br />
• Am Reset-Pin kann ein ICE angeschlossen werden<br />
(debug-wire).<br />
Die neuen Prozessoren sind hardware-kompatibel zu ihren<br />
Vorgängern. Programme müssen neu übersetzt werden, da der<br />
Bereich der I/O-Adressen verändert und erweitert wurde. Das<br />
RAM beginnt ab Adresse 0x100.
Kapitel 13<br />
Aufbau des Systems<br />
Unser Experimentiersystem besteht aus mehreren Teilen:<br />
• Software<br />
• Programmier-Interface<br />
• Verbindungskabel<br />
• Mikrocontroller-Board <strong>mit</strong> Oszillator<br />
• Stromversorgung<br />
Der Ausdruck der Layouts erfolgt auf einem Postscript-<br />
Drucker. Falls keiner vorhanden ist, muss die Emulationssoftware<br />
Ghostscript verwendet werden. Beim Ausdruck von graphischen<br />
Dateien hilft das hervorragende Programm gimp, für<br />
das verschiedene Bücher erschienen sind.<br />
129
KAPITEL 13. AUFBAU DES SYSTEMS 130<br />
Das Anfertigen der Platinen wurde bereits im Kapitel 10.3<br />
beschrieben. Erste Bauerfahrungen können <strong>mit</strong> der Schaltung<br />
des Programmier-Interfaces erlangt werden. Da es zentrale<br />
Komponente des Systems ist, werden wir da<strong>mit</strong> anfangen.<br />
13.1 Software<br />
Für Windows bietet die Firma Atmel eine kostenfreie Programmierumgebung<br />
an. Die Programmquellen sind jedoch<br />
nicht offengelegt. Ein relativ hoher Aufwand wurde in das<br />
graphische Benutzerinterface gelegt.<br />
Nutzer anderer Systeme, die <strong>mit</strong>tlerweile weitgehend irgendwie<br />
auf Unix aufbauen, werden von GNU gut bedient. In diesem<br />
Buch wird nur auf diese Programme eingegangen, die<br />
aber auch für Windows [winavr] erhältlich und gebräuchlich<br />
sind.<br />
Mindestens vier spezielle Programmpakete werden benötigt:<br />
avr-gcc C - Crosscompiler<br />
avr-binutils Assembler, Linker etc.<br />
avr-libc C - Runtime für AVR<br />
avrdude Programmiertool<br />
Benutzer von Debian [debian], einer bedeutenden Linux-<br />
Distribution, bekommen die notwendigen Programmpakete<br />
bereits <strong>mit</strong>geliefert. Allerdings gibt es auch für Debian-Nutzer
KAPITEL 13. AUFBAU DES SYSTEMS 131<br />
einen Wermutstropfen. Selbst die neueste Debian-Distribution<br />
hinkt der schnellen Entwicklung auf AVR-Seite hinterher. So<br />
kann man <strong>mit</strong> der aktuellen Software von Debian 3.1 für<br />
den ATmega8 gut entwickeln. Dieser ist jedoch bereits abgekündigt<br />
und wird durch den ATmega88 ersetzt. So sind<br />
auch Debian-Nutzer gezwungen, sich die aktuellen Versionen<br />
aus dem Internet zu besorgen. Auch die neueren Versionen<br />
auf http://packages.debian.org/testing sind gut gepflegt.<br />
Nutzer anderer Systeme müssen sich durch das Internet selber<br />
helfen. Nach meiner Beobachtung wird die hier beschriebene<br />
Software auch auf Apple- Freebsd- und Windowssystemen<br />
häufig benutzt.<br />
Noch einige Bemerkungen zum Programmiertool. Derartige<br />
Programme wurden für die verschiedensten Hardwareanschlüsse<br />
entwickelt. In den letzten Jahren war das Programm<br />
uisp recht beliebt, da es viele Anschlüsse gut bediente. Die<br />
Pflege von uisp wurde jedoch immer schwieriger, so dass inzwischen<br />
das Programm avrdude bevorzugt wird. Das Verhalten<br />
von avrdude kann über eine Konfigurationsdatei in gewissen<br />
Grenzen sogar erweitert werden.<br />
Die Ur-Version von avrdude hieß noch avrprog und wurde für<br />
die hier verwendete bsd-Schnittstelle entwickelt. Mit dieser<br />
Hardware funktioniert das Programm auch heute noch problemlos.<br />
Für die serielle Schnittstelle und usbasp wird mindestens<br />
die Version 5.2 benötigt.
KAPITEL 13. AUFBAU DES SYSTEMS 132<br />
13.2 Programmier-Interface<br />
Dies ist die Schicht, die das fertig übersetzte Programm von<br />
der Festplatte des PCs in den Speicher des Mikrocontrollers<br />
bringt. Die Hardware wird oft ISP genannt. Die Abkürzung<br />
für ,,In System Programmer” soll darauf hinweisen, das der<br />
Mikrocontroller nicht in einem eigenen Programmiergerät,<br />
sondern in der endgültigen Schaltung programmiert werden<br />
kann. Als Software verwenden wir das Programm avrdude.<br />
das eine Menge physikalischer Möglichkeiten unterstüzt.<br />
Drei Möglichkeiten, ponyser, bsd und usbasp genannt, werden<br />
hier beschrieben. Ponyser verwendet RS232, die bsd-Variante<br />
nutzt die Centronics-Schnittstelle, und usbasp wird am USB<br />
angeschlossen.<br />
13.2.1 Centronics Variante<br />
Diese Schnittstelle wird vom Programmiertool ,,bsd” genannt,<br />
da sie ursprünglich unter dem Betriebssystem Freebsd entwickelt<br />
wurde.<br />
Die vom Programm pcb.kit erzeugte Stückliste wird kein zu<br />
großes Loch in die Kasse reißen:<br />
1:1/9 Lochrasterplatine 13*15 :527777<br />
1:Stecker DB-25 :741671<br />
1:Pfostenstecker 10polig :742465<br />
4:Zehnerdioden BAT43 :153010<br />
1:Leuchtdiode gelb 3mm 2mA :145998<br />
1:Widerstand 2k2 Ohm :408212<br />
1:Widerstand 100K Ohm :408409<br />
1:IC 74HC367 :151165
KAPITEL 13. AUFBAU DES SYSTEMS 133<br />
Abbildung 13.1: Schaltplan der Centronics Variante des ISP-<br />
Interface
KAPITEL 13. AUFBAU DES SYSTEMS 134<br />
Der Bau der Platine ist deshalb auch für Anfänger im Löten<br />
noch zu bewerkstelligen.<br />
Abbildung 13.2: Layout der Centronics Variante des ISP-<br />
Interface<br />
( ) PCB :1/9 Lochrasterplatine 13*15 :herstellen<br />
( ) :Stecker DB-25 :anlöten, dass B5 fluchtet<br />
( ) :Pfostenstecker 10polig :anlöten (e14)<br />
( ) B1 :Drahtschlinge (optional) :einlöten (a12) (a14)<br />
( ) B2 :Draht :einlöten (c12) (j12)<br />
( ) B3 :Draht :nach Pin10 einlöten (c3)<br />
( ) B4 :Draht :nach Pin9 einlöten (d6)<br />
( ) B5 :Draht :nach Pin8 einlöten (e10)<br />
( ) B6 :Draht :nach Pin7 einlöten (g8)<br />
( ) B7 :Draht :nach Pin6 einlöten (i10)<br />
( ) B8 :Draht :nach Pin9 einlöten (e13)<br />
( ) B9 :Draht :nach Pin7 einlöten (f13)<br />
( ) B10 :Draht :nach Pin5 einlöten (g13)<br />
( ) B11 :Draht :nach Pin3 einlöten (h13)<br />
( ) B12 :Draht :nach Pin1 einlöten (i13)<br />
( ) D1 :Zehnerdioden BAT43 :Anode an Pin5 löten (i4)<br />
( ) D2 :Zehnerdiode BAT43 :Anode an Pin4 löten (j4)<br />
( ) D3 :Zehnerdiode BAT43 :Anode an Pin3 löten (k4)<br />
( ) D4 :Zehnerdiode BAT43 :Anode an Pin2 löten (l4)<br />
( ) LED1:Leuchtdiode gelb 3mm 2mA :Anode in j5 einlöten (j5) (j6)<br />
( ) R1 :Widerstand 2k2 Ohm :einlöten (j7) (j11)<br />
( ) R2 :Widerstand 100K Ohm :einlöten (k7) (k11)<br />
( ) IC1 :IC 74HC367 :Pin1 in Richtung DB25 einlöten (f4)
KAPITEL 13. AUFBAU DES SYSTEMS 135<br />
Abbildung 13.3: ISP-Interface in der Centronics Variante.<br />
Als Bestückungshilfe wird in der Abbildung 13.3 das fertige<br />
Interface gezeigt.<br />
Wird <strong>mit</strong> Lochrasterplatine gearbeitet, die auf beiden Seiten<br />
Lötaugen hat, so müssen diese im Bereich des DB-25 Steckers<br />
auf der Bestückungsseite entfernt werden, sonst wären Kurzschlüsse<br />
die Folge. DB-25 Stecker haben ein Rastermaß von<br />
2,5 mm, während Lochrasterplatinen <strong>mit</strong> einem Rastermaß<br />
von 2,54 mm ausgestattet sind. Bei der Montage des Steckers<br />
ist darauf zu achten, dass zwischen Pin14 bis Pin18 keine<br />
Kurzschlüsse entstehen. Pin18 bis Pin25 dagegen sind durchverbundene<br />
Masseanschlüsse.<br />
Die Kodieröffnung des Pfostensteckers muss, wie in der Abbildung<br />
13.3 ersichtlich, zur Bestückungsseite zeigen!
KAPITEL 13. AUFBAU DES SYSTEMS 136<br />
13.2.2 RS232 Variante<br />
Das Programmiertool uisp nannte diese Schnittstelle ,,dasa2”.<br />
Da die Schnittstellenbelegung auf ein Programmiertool <strong>mit</strong><br />
Namen PonyProg zurückgeht, nennt avrdude die Schnittstelle<br />
,,ponyser”.<br />
Falls die Druckerschnittstelle nicht verfügbar ist, kann auf diese<br />
Variante umgestiegen werden. Sie ist etwas schwieriger in<br />
der Handhabung.<br />
1:1/15 Lochrasterplatine 7*15 :527777<br />
1:Buchse Sub-D9 :742066<br />
1:Pfostenstecker 10polig :742465<br />
4:Widerstände 10K Ohm :408280<br />
5:Zehnerdioden BAT43 :153010<br />
1:BC 547 B :155012<br />
Die Montageanleitung fällt ebenfalls kleiner aus:<br />
( ) PCB :1/15 Lochrasterplatine 7*15 :herstellen<br />
( ) :Buchse Sub-D9 :Pin1..5 anlöten (b1)<br />
( ) :Pfostenstecker 10polig :Pin1,3,5,7,9 anlöten (b13)<br />
( ) R1 :Widerstände 10K Ohm :an Pin3 anlöten (c4)<br />
( ) R2 :Widerstand 10K Ohm :an Pin4 anlöten (d4)<br />
( ) R3 :Widerstand 10K Ohm :an Pin7 unten anlöten (f4)<br />
( ) R4 :Widerstand 10K Ohm :einlöten (d12) (g12)<br />
( ) B1 :Draht :an Pin8 unten anlöten (e4)<br />
( ) B2 :Draht :an Pin4,6,8,10 anlöten (a12)<br />
( ) B3 :Draht :von Pin2 über a14 nach g14 führen (a13) (g13)<br />
( ) B4 :0.2mm Trafodraht :verbinden (g4) (f13)<br />
( ) D1 :Zehnerdioden BAT43 :Anode in (c5) einlöten (c5) (g5)<br />
( ) D2 :Zehnerdiode BAT43 :Anode in (a6) einlöten (a6) (c6)<br />
( ) D3 :Zehnerdiode BAT43 :Anode in (b7) einlöten (b7) (e7)<br />
( ) D4 :Zehnerdiode BAT43 :Anode in (a8) einlöten (a8) (d8)<br />
( ) D5 :Zehnerdiode BAT43 :Anode in (e8) einlöten (e8) (g8)<br />
( ) T1 :BC 547 B :flache Seite Richtung (d1) einlöten<br />
Die Kodieröffnung des Pfostensteckers muss zur Lötseite der<br />
Platine zeigen! Das Einsetzen der Drahtbrücken erfordert etwas<br />
Sorgfalt. In der Abbildung 13.6 kann die Montage nachvollzogen<br />
werden. In der pdf-Version des Dokuments kann<br />
man die Fotos vergrößern.
KAPITEL 13. AUFBAU DES SYSTEMS 137<br />
Abbildung 13.4: Schaltplan der RS232 Variante des ISP-<br />
Interface
KAPITEL 13. AUFBAU DES SYSTEMS 138<br />
Abbildung 13.5: Layout der RS232 Variante des ISP-Interface<br />
Abbildung 13.6: ISP-Interface in der RS232 Variante.
KAPITEL 13. AUFBAU DES SYSTEMS 139<br />
Die abgebildete Version <strong>mit</strong> Lochrasterplatine hat ein etwas<br />
großzügigeres Layout. Wird <strong>mit</strong> Lochrasterplatine gearbeitet,<br />
die auf beiden Seiten Lötaugen hat, so müssen diese im Bereich<br />
des DB-9 Steckers auf der Bestückungsseite entfernt werden.<br />
13.2.3 USB Variante<br />
usbasp<br />
Der Entwickler dieser Schnittstelle Thomas Fischl nannte sie<br />
,,usbasp”. Die von ihm gelieferten Änderungen für avrdude<br />
erweitern das Programm um die Möglichkeit des Parameters.<br />
Moderne Notebooks sind <strong>mit</strong>tlerweile ohne RS232- und<br />
Centronics-Schnittstelle ausgestattet. Nahezu alles wird über<br />
USB angeschlossen. Wie zuvor im Kapitel über diese Schnittstelle<br />
angedeutet, gibt es eine ISP-Variante zum Selberbau<br />
<strong>mit</strong> USB. Die Quelle der Schaltung liegt auf Thomas Fischls<br />
Homepage www.fischl.de [fischl]. Leider existiert hier das<br />
Henne-Ei-Problem. Wer keinen Weg sieht, den notwendigen<br />
USB-Controller zu programmieren, ist wohl auf das fertige<br />
Angebot von Atmel, den AVRISP MKII, angewiesen.<br />
Der Selberbau ist durchaus lohnend, da nicht viele Bauteile<br />
notwendig sind:<br />
1:board 43mm x 71mm :BEL 160x100-1<br />
1:isolated bridge :<br />
1:10k resistor :1/4W 10k<br />
1:1k5 resistor :1/4W 1k5
KAPITEL 13. AUFBAU DES SYSTEMS 140<br />
Abbildung 13.7: Schaltplan der USB Variante des ISP-<br />
Interface
KAPITEL 13. AUFBAU DES SYSTEMS 141<br />
1:270 resistor :1/4W 270<br />
2:2k2 resistor :1/4W 2k2<br />
2: 68 resistor :1/4W 68<br />
2: 22pF capacitor :Kerko 22p<br />
1:100nF capacitor :Z5U-2,5 100n<br />
1: 10uF capacitor :AX 10/35<br />
1: 10uF capacitor :RAD 10/35<br />
1:12Mhz quartz :12-HC49U-S<br />
1: red led 2mA :LED 3mm 2MA rt<br />
1:green led 2mA :LED 3mm 2MA gr<br />
1:BAT43 schottky diode:BAT 43<br />
1:ATmega48-20PU :ATMEGA48-20 DIP<br />
1:jumper SCK :LU 2,5 MS2<br />
1:plug :WSL 10W<br />
1:USB-B-plug :USB BW<br />
Die Montageanleitung:<br />
( ) PCB:board 43mm x 71mm :saw<br />
( ) B1 :bridge :solder (h15) (i14)<br />
( ) B2 :bridge :solder (a22) (e22)<br />
( ) B3 :bridge :solder (d13) (d11)<br />
( ) B4 :bridge :solder (k19) (k22)<br />
( ) B5 :bridge :solder (h19) (h22)<br />
( ) B6 :bridge :solder (j7) (l7)<br />
( ) B7 :isolated bridge :solder if needed (h8) (i21)<br />
( ) R1 :10k resistor :solder (b8) (f8)<br />
( ) R2 :1k5 resistor :solder (a6) (e6)<br />
( ) R3 :270 resistor :solder (b10) (f10)<br />
( ) R4 :2k2 resistor :solder (l6) (l10)<br />
( ) R5 :2k2 resistor :solder (n6) (n10)<br />
( ) R6 : 68 resistor :solder (a4) (e4)<br />
( ) R7 : 68 resistor :solder (l4) (p4)<br />
( ) C1 : 22pF capacitor :solder (d15) (e15)<br />
( ) C2 : 22pF capacitor :solder (d21) (e21)<br />
( ) C3 :100nF capacitor :solder (f14) (f15)<br />
( ) C4 : 10uF capacitor :solder + in (n20) (n14) (n20)<br />
( ) C4a: 10uF capacitor :alternatively (n15) (n16)<br />
( ) Q1 :12Mhz quartz :solder (e17) (e19)<br />
( ) D1 : red led 2mA :solder anode in (l11) (l11) (l12)<br />
( ) D2 :green led 2mA :solder anode in (n11) (n11) (n12)<br />
( ) D3 :BAT43 schottky diode:solder anode in (n21) (n21) (n24)<br />
( ) IC1:ATmega48-20PU :solder Pin 1 in (g8)<br />
( ) J3 :jumper SCK :solder (k8) (k9)<br />
( ) K1 :plug :solder<br />
( ) K4 :USB-B-plug :solder<br />
Der Prozessor kann über den ISP-Stecker programmiert werden.<br />
Hierzu sind eine Brücke über die Diode und eine Brücke<br />
zwischen den beiden SMD-Pads zu löten. Nach dem Programmieren<br />
müssen auch die L- und H-Fuse neu gesetzt werden!
KAPITEL 13. AUFBAU DES SYSTEMS 142<br />
Abbildung 13.8: Layout der USB Variante des ISP-Interface
KAPITEL 13. AUFBAU DES SYSTEMS 143<br />
Abbildung 13.9: ISP-Interface in der USB Variante.
KAPITEL 13. AUFBAU DES SYSTEMS 144<br />
Der Jumper muss gesteckt werden, wenn die am ISP angeschlossene<br />
MCU <strong>mit</strong> weniger als 1,5 Mhz getaktet wird. Dies<br />
ist z.B. bei unseren MCUs im Auslieferungszustand der Fall.<br />
Um diese Lösung zum Arbeiten zu bekommen müsste man<br />
diesen Kurs bereits teilweise durchlaufen haben. Deshalb rate<br />
ich Einzelkämpfern, besser die etwas teurere Lösung von Atmel<br />
zu kaufen. In Gruppen sind die Einsparungen durch die<br />
Eigenleistung durchaus lohnend, vom Einblick in die Interna<br />
von USB ganz zu schweigen.<br />
Zuletzt ist zu beachten, dass das Programm avrdude die<br />
Schnittstelle usbasp kennt. Zur Zeit von avrdude Version 5.1<br />
muss hierzu noch eine Spezialversion aus den Programmquellen<br />
erzeugt werden.<br />
Innerhalb einer Diskussion im Internet wurde erwähnt, dass<br />
die Spezifikation der USB-Schnittstelle für die Signale D+ und<br />
D- nur 3,3 V +/- 10 % vorsieht. Die hier vorgestellte einfache<br />
Lösung verwendet jedoch 5 V. Sollte das Probleme machen,<br />
so kann man einfach <strong>mit</strong> zwei Dioden die Versorgungsspannung<br />
der Schaltung reduzieren. Der verwendete ATmega48-<br />
20 kann auch bei 3,3 V noch <strong>mit</strong> den notwendigen 12 Mhz<br />
getaktet werden. Die reduzierte Spannung kann natürlich zu<br />
Problemen auf der ISP-Seite führen.<br />
usbisp<br />
Mattias Weißer bietet auf seiner Homepage www.matwei.de<br />
[matwei] eine weitere interessante Lösung an. Er verwendet
KAPITEL 13. AUFBAU DES SYSTEMS 145<br />
den FTDI-Chip FT245BM, der vom Betriebssystem als serieller<br />
Schnittstellenkonverter erkannt wird. Softwaremäßig wird<br />
das STK500 von Atmel emuliert. Daraus ergeben sich Vorund<br />
Nachteile:<br />
- Den FTDI-Chip gibt es nur als SMD-Bauteil.<br />
- Die Schaltung ist aufwändiger als usbasp.<br />
+ Für den FTDI-Chip gibt es fertige Treiber.<br />
+ Für das STK500 gibt es fertige ISP-Software.<br />
+ Die Lösung ist relativ schnell.<br />
Auch wer diese Lösung verfolgt steht vor dem Henne-Ei-<br />
Problem. Zumindest eine (ebenfalls zum STK500 kompatible)<br />
Boot-Software muss <strong>mit</strong> einem vorhandenen Programmiergerät<br />
in die MCU geladen werden.<br />
Die Firmware von usbisp ist aber auch ohne den FTDI-<br />
Chip <strong>mit</strong> einer RS232-Schnittstelle verwendbar. Bei dieser<br />
Lösung, sie wurde RS232isp genannt, entfallen obige Nachteile.<br />
Für den Anschluss an USB reicht ein einfacher RS232-<br />
USB-Konverter. Im Anhang E wird auf diese Lösung nochmal<br />
eingegangen.<br />
13.3 Kabel<br />
Ein ein bis zwei Meter langes 10-adriges Flachbandkabel wird<br />
an beiden Seiten <strong>mit</strong> Pfostensteckern versehen. Meist haben<br />
Flachbandkabel eine farbige Ader. Diese wird <strong>mit</strong> Pin1 verbunden.<br />
Pin1 der Pfostenstecker ist <strong>mit</strong> einem kleinen Pfeil
KAPITEL 13. AUFBAU DES SYSTEMS 146<br />
gekennzeichnet. Zusammendrücken kann man die Stecker in<br />
einem Schraubstock, gefühlvolles Drehen am Knebel vorausgesetzt!<br />
13.4 Mikrocontroller-Board<br />
Je unbekannter das Terrain, desto langsamer sollte man fortschreiten.<br />
Der Aufbau des Experimentiersystems wird deshalb<br />
in sechs Baustufen unterteilt. Die erste Stufe ist auf dem<br />
Schaltplan in Abbildung 13.10 nicht grau hinterlegt und wird<br />
hier nochmal in zwei Stufen geteilt.<br />
13.4.1 Programmierschnittstelle<br />
Im zur Hardware gehörigen Verzeichnis befindet sich<br />
ein Platinenlayout, bei dem die Kupferlackdrähte Kl1<br />
und Kl2 im Layout integriert wurden in der Datei<br />
hardware/layout mainboard.png.<br />
( ) PCB :1/1 Lochrasterplatine 39*63:herstellen<br />
( ) Mon1:4 Platinenfüße :befestigen (K61)<br />
( ) B3 :Draht :einlöten (v6) (v12)<br />
( ) B4 :Draht :einlöten (c56) (a56)<br />
( ) B5 :Draht :einlöten (c16) (a16)<br />
( ) B6 :Draht :einlöten (M16) (J16)<br />
( ) B7 :Draht :einlöten (J15) (C15)<br />
( ) B8 :Draht :einlöten (a7) (h7)<br />
( ) B9 :Draht :einlöten (f8) (f13)<br />
( ) B10 :Draht :einlöten (g8) (g13)<br />
( ) B11 :Draht :einlöten (D1) (D3)<br />
( ) B12 :Draht :einlöten (c19) (a19)<br />
( ) B13 :Draht :verbinden (F6) (H9)<br />
( ) Pfo1:Steckerliste 2x5 90Grad :einlöten (F6)<br />
( ) So1 :DIL-28S Präzisions-Sockel :einlöten (w12)
KAPITEL 13. AUFBAU DES SYSTEMS 147<br />
Abbildung 13.10: Schaltplan der ersten sechs Baustufen
KAPITEL 13. AUFBAU DES SYSTEMS 148<br />
Abbildung 13.11: Layout der Hauptplatine
KAPITEL 13. AUFBAU DES SYSTEMS 149<br />
( ) Kl1 :Kupferlackdraht 0.2mm :einlöten (J6) (p5)<br />
( ) Kl2 :Kupferlackdraht 0.2mm :einlöten (H6) (w6)<br />
( ) IC1 :Mikrocontroller ATmega..8 :Pin1 in w12 einsetzen<br />
Der Draht B12 wird VOR dem Einsetzen des Sockels am Pin<br />
17 festgelötet. Nach dem Einlöten in die Platine wird der<br />
Draht <strong>mit</strong> der Steckerleiste verbunden. Ist alles montiert, kann<br />
ein Test eingeschoben werden.<br />
13.4.2 Erster Dialog<br />
Nachdem das Programmierinterface fertig ist und eine letzte<br />
optische Kontrolle keine Fehler mehr erkennen läßt, soll ein<br />
erstes Experiment die Funktionstüchtigkeit beweisen.<br />
Dieses Experiment funktioniert nicht <strong>mit</strong> der RS232-Variante<br />
der ISP-Schnittstelle, da diese keine Stromversorgung beinhaltet.<br />
Bei ausschließlicher Verwendung der Variante muss der<br />
Aufbau der Stromversorgung, im Kapitel 13.4.4 beschrieben,<br />
vorgezogen werden.<br />
Für die Verbindung zwischen dem Mikrocontroller und der<br />
ISP-Schnittstelle wurde die Experimentierplatine <strong>mit</strong> Drahtbrücken,<br />
CPU-Sockel und ISP-Stecker bestückt. Der Mikrocontroller<br />
sollte fabrikneu sein, da er sonst eventuell auf einen<br />
externen Oszillator eingestellt wurde. In diesem Fall kann man<br />
ohne Oszillator den Mikrocontroller nicht mehr ansprechen.<br />
Das Programm avrdude wird aufgerufen. Der erste Testaufruf<br />
heißt
KAPITEL 13. AUFBAU DES SYSTEMS 150<br />
oder<br />
oder<br />
avrdude -c bsd -p atmega48 -P /dev/parport0<br />
avrdude -c ponyser -p atmega48 -P /dev/ttyS0<br />
avrdude -c usbasp -p atmega48<br />
je nach verwendeter Schnittstelle. parport0, ttyS0 und atmega48<br />
sind Parameter, die natürlich stimmen müssen. Eine<br />
entsprechende Freigabe der Schnittstellen vom PC-Bios muss<br />
beim Urladen (BIOS-Setup) erfolgt sein. Die Treiberschichten<br />
des Betriebssystems müssen vorhanden sein.<br />
Da die libusb in avrdude <strong>mit</strong> dem Verzeichnis /proc arbeitet,<br />
dies aber nur <strong>mit</strong> Superuser-Rechten erlaubt ist, müssen diese<br />
Rechte dem Programm während der Ausführung <strong>mit</strong> folgendem<br />
Befehl eingeräumt werden:<br />
chmod 4755 /usr/local/bin/avrdude<br />
Solche Rechte kann natürlich nur der Superuser vergeben.<br />
Wird eine Schnittstelle im Verzeichnis /dev verwendet, so<br />
braucht der User ausreichend Rechte für den Zugriff auf die<br />
entsprechende Schnittstelle. Der Superuser muss also zum<br />
Beispiel folgenden Befehl eingeben:
KAPITEL 13. AUFBAU DES SYSTEMS 151<br />
chmod 666 /dev/ttyS0<br />
Fehler können in vier Bereichen liegen, fehlende Dateien, fehlende<br />
Rechte, fehlende Systemtreiber, falsche Verdrahtung.<br />
Diese Hürde muss erklommen werden.<br />
Erkennt das Programm avrdude endlich den Prozessortyp,<br />
zum Beispiel <strong>mit</strong> der Meldung<br />
...<br />
avrdude: Device signature = 0x1e9205<br />
...<br />
so ist die erste Stufe geschafft, unser System ist bereit, das<br />
erste Experiment kann starten:<br />
Eeprom <strong>mit</strong> Hello World! beschreiben und auslesen.<br />
Die binutils-avr sind hoffentlich installiert.<br />
Als erstes wird eine Quelldatei <strong>mit</strong> dem Editor erstellt:<br />
vi eeprom.s<br />
In diese Datei schreiben wir eine Assembler-Anweisung, die<br />
unseren Text erzeugt:<br />
.string ”Hello World!”
KAPITEL 13. AUFBAU DES SYSTEMS 152<br />
Anschließend wird die Datei dem Assembler zum Übersetzen<br />
gegeben.<br />
avr-as eeprom.s<br />
Die Datei <strong>mit</strong> dem default-Namen a.out muss nun für das<br />
Programmierprogramm avrdude vorbereitet werden:<br />
avr-ld -o eeprom --oformat srec a.out<br />
Es entsteht eine kleine Datei im Motorola S-records Format,<br />
die man <strong>mit</strong> dem Befehl<br />
ansehen kann.<br />
cat eeprom<br />
S0090000656570726F6D6E<br />
S110000048656C6C6F20576F726C642100B2<br />
S104000D00EE<br />
S9030000FC<br />
Jede Zeile bildet eine S-record bestehend aus folgenden Feldern:<br />
S, Satztyp, Datenlänge, Ladeadresse, Daten, Prüfbyte.<br />
Diese Datei kann vom Programmierprogramm ins Speicherwerk<br />
des Mikrocontrollers geladen werden:
KAPITEL 13. AUFBAU DES SYSTEMS 153<br />
avrdude -c usbasp -p atmega48 -U eeprom:w:eeprom:s<br />
Zur Kontrolle liest der Befehl<br />
avrdude -c usbasp -p atmega48 -U eeprom:r:-:s<br />
unsere Daten aus dem Mikrocontroller wieder aus.<br />
Mit diesem einfachen Versuch ist bewiesen, dass sich unser<br />
Mikrocontroller programmieren lässt. Den nächsten Experimenten<br />
steht nichts mehr im Weg.<br />
Vertiefung: Die vier Zeilen der Datei eeprom lassen sich <strong>mit</strong><br />
den Tabellen aus dem Kapitel 2 decodieren.<br />
13.4.3 Erste Baustufe<br />
Nun wird die Schaltung um Oszillator und Leuchtdioden erweitert:<br />
( ) B1 :Drahtschlinge für -Messp. :einlöten (L6) (L7)<br />
( ) B2 :Drahtschlinge für +Messp. :einlöten (a6) (a8)<br />
( ) So3 :DIL-14 Präzisions-Sockel :einlöten (D17)<br />
( ) Stl3:Stiftleiste 1polig :einlöten (y8)<br />
( ) Stl4:Stiftleiste 2polig (option):bei ISP-Betrieb einlöten (v13)<br />
( ) :Jumper (option) :bei ISP-Betrieb einlöten<br />
( ) LED1:Leuchtdioden grün 3mm 2mA :Anode in y3 einlöten (y2) (y3)<br />
( ) LED2:Leuchtdioden gelb 3mm 2mA :Anode in t3 einlöten (t2) (t3)<br />
( ) LED3:Leuchtdioden rot 3mm 2mA :Anode in o3 einlöten (o2) (o3)<br />
( ) C1 :Kondensator 100 nF :einlöten (B10) (B11)<br />
( ) C2 :Kondensator 100 nF :einlöten (E10) (E11)<br />
( ) C13 :Kondensator 33 nF (option):bei ISP-Betrieb zwischen Pin1 und GND<br />
( ) L1 :Festinduktivität 10uH :liegend einlöten (D4) (D8)<br />
( ) R7 :Widerstand 2k7 Ohm :stehend einlöten (y4) (y5)<br />
( ) R8 :Widerstand 2k7 Ohm :stehend einlöten (t4) (t5)<br />
( ) R9 :Widerstand 2k7 Ohm :stehend einlöten (o4) (o5)<br />
( ) R11 :Widerstand 47k Ohm :liegend einlöten (L8) (I8)<br />
( ) R12 :Widerstand 47k Ohm :liegend einlöten (C13) (w13)<br />
( ) IC2 :Oszillator 7.3728 Mhz :Pin1 in J14 einsetzen<br />
( ) Stl1:Stiftleiste 3polig :einlöten (c13)<br />
( ) D1 :Diode BAT 43 :Anode in d14 einlöten (d14) (d16)
KAPITEL 13. AUFBAU DES SYSTEMS 154<br />
Abbildung 13.12: Erste Baustufe<br />
Obige Tests können wiederholt werden. Bereits beim up- und<br />
download müssen die Leuchtdioden heftig blinken, da sie<br />
auch als Kontrollleuchten für die Programmierleitungen MO-<br />
SI, SCK and MISO gedacht sind. Im Fehlerfall muss man<br />
Leiterbahnen und Polung der LEDs kontrollieren.<br />
Funktioniert die Platine so weit, sind wir bereit für das erste<br />
Programmierprojekt. Zur Einführung programmieren wir in<br />
Assembler.<br />
Blinkende LED<br />
Für die Ausgabe von ,,Hello World!” sind schon viele Voraussetzungen<br />
auf Hard- und Softwareseite zu erfüllen. Un-
KAPITEL 13. AUFBAU DES SYSTEMS 155<br />
ser System ist noch zu einfach und muss für diese Aufgabe<br />
noch wachsen. Mikrocontroller begrüßen die Welt oft <strong>mit</strong> einer<br />
Leuchtdiode, die einfach an und aus geht. Das ließe sich<br />
auch einfacher lösen, dann würde man aber nichts über Mikrocontroller<br />
lernen.<br />
Reine Assembler Version<br />
Das einfache Programm besteht aus vier Teilen:<br />
• Vorbereiten des Programmspeichers auf alle Interrupts,<br />
auf die der Mikrocontroller reagieren würde.<br />
• Vorbereiten des RAMs durch Initialisieren des Stackpointers.<br />
• Vorbereiten des Ausgabewerkes.<br />
• Programmschleife zum Schalten der LED.<br />
Die genaue Beschreibung aller AVR-Befehle befindet sich in<br />
der von Atmel erhältlichen Beschreibung ,,AVR Instruction<br />
Set”.<br />
Einige Regeln des Programms:<br />
• Kommentare starten <strong>mit</strong> einem Semikolon und erstrecken<br />
sich bis zum Zeilenende.
KAPITEL 13. AUFBAU DES SYSTEMS 156<br />
• Die Section .text liegt im Programmspeicher (im Gegensatz<br />
zu .eeprom).<br />
• Programmmarken wie Sprungadressen enden <strong>mit</strong> Doppelpunkt.<br />
• Worte, die der Assembler kennt, sind in der Regel klein<br />
geschrieben.<br />
• Es empfiehlt sich, eingeführte Worte wie Sprungmarken<br />
am Anfang groß, dann klein zu schreiben.<br />
• Die von Atmel eingeführten Registeradressen etc. sind<br />
in der Regel komplett groß geschrieben.<br />
Das gezeigte Beispiel verwendet noch keine Namen für die<br />
Register des Ein-/Ausgabewerkes. Diese sind als Kommentar<br />
angefügt. Das Programm funktioniert deshalb nur für die<br />
vorgesehene Version des AVR-Prozessors. Es kann <strong>mit</strong> einem<br />
einfachen Befehl übersetzt werden:<br />
avr-as fastled.as<br />
Die entstandene Datei a.out kann zur Kontrolle wieder<br />
rückübersetzt werden.<br />
avr-objdump -d a.out<br />
Diesen Vorgang nennt man Disassemblieren.
KAPITEL 13. AUFBAU DES SYSTEMS 157<br />
../software/led.assembler/a.out: file format elf32-avr<br />
Disassembly of section .text:<br />
00000000 :<br />
0: 19 c0 rjmp .+50 ; 0x34<br />
2: 17 c0 rjmp .+46 ; 0x32<br />
4: 16 c0 rjmp .+44 ; 0x32<br />
6: 15 c0 rjmp .+42 ; 0x32<br />
8: 14 c0 rjmp .+40 ; 0x32<br />
a: 13 c0 rjmp .+38 ; 0x32<br />
c: 12 c0 rjmp .+36 ; 0x32<br />
e: 11 c0 rjmp .+34 ; 0x32<br />
10: 10 c0 rjmp .+32 ; 0x32<br />
12: 0f c0 rjmp .+30 ; 0x32<br />
14: 0e c0 rjmp .+28 ; 0x32<br />
16: 0d c0 rjmp .+26 ; 0x32<br />
18: 0c c0 rjmp .+24 ; 0x32<br />
1a: 0b c0 rjmp .+22 ; 0x32<br />
1c: 0a c0 rjmp .+20 ; 0x32<br />
1e: 09 c0 rjmp .+18 ; 0x32<br />
20: 08 c0 rjmp .+16 ; 0x32<br />
22: 07 c0 rjmp .+14 ; 0x32<br />
24: 06 c0 rjmp .+12 ; 0x32<br />
26: 05 c0 rjmp .+10 ; 0x32<br />
28: 04 c0 rjmp .+8 ; 0x32<br />
2a: 03 c0 rjmp .+6 ; 0x32<br />
2c: 02 c0 rjmp .+4 ; 0x32<br />
2e: 01 c0 rjmp .+2 ; 0x32<br />
30: 00 c0 rjmp .+0 ; 0x32<br />
00000032 :<br />
32: e6 cf rjmp .-52 ; 0x0<br />
00000034 :<br />
34: 02 e0 ldi r16, 0x02 ; 2<br />
36: 0e bf out 0x3e, r16 ; 62<br />
38: 0f ef ldi r16, 0xFF ; 255<br />
3a: 0d bf out 0x3d, r16 ; 61<br />
0000003c :<br />
3c: 25 9a sbi 0x04, 5 ; 4<br />
0000003e :<br />
3e: 2d 9a sbi 0x05, 5 ; 5<br />
40: 2d 98 cbi 0x05, 5 ; 5<br />
42: fd cf rjmp .-6 ; 0x3e<br />
Den Zusammenhang zwischen Befehlen des Assemblers und<br />
Befehlscodes kann man in der Rückübersetzung gut erkennen.<br />
Das Disassemblieren ist auch später interessant, wenn nicht<br />
klar ist, wie der Compiler ein Programm verstanden hat.
KAPITEL 13. AUFBAU DES SYSTEMS 158<br />
Wie das Programm in den Flash-Speicher des Mikrocontrollers<br />
kommt, wissen wir schon: <strong>mit</strong> den Werkzeugen avr-ld und<br />
avrdude.<br />
Sofort nachdem das Programm geladen wird, wird der Mikrocontroller<br />
<strong>mit</strong> einem Reset aktiviert. Er springt auf die Adresse<br />
0 und beginnt <strong>mit</strong> der Programmbearbeitung. In diesem<br />
Punkt unterscheiden sich viele CPUs. Dieses Verhalten ist ein<br />
wichtiger Aspekt des Datenblattes.<br />
Die Leuchtdiode leuchtet zwar, aber scheint nicht zu blinken.<br />
Untersucht man den Pin 5 des Port B <strong>mit</strong> dem Oszilliskop, wie<br />
es die Abbildung 13.13 zeigt, so blinkt er doch. Die horizon-<br />
tale Ablenkung des Oszilloskops ist auf 1 µsec<br />
cm<br />
eingestellt. Der<br />
Mikrocontroller arbeitet <strong>mit</strong> dem internen Takt von 1 Mhz.<br />
Ein Takt des Mikrocontrollers entspricht also 1 cm horizontaler<br />
Ablenkung. Im Oszillogramm kann man gut die zwei Takte<br />
des Befehls sbi, gefolgt von den jeweils zwei Takten der Befehle<br />
cbi und rjmp erkennen. Dannach folgt der nächste Schleifendurchlauf.<br />
Der Befehl rjmp liegt jetzt außerhalb der Breite der<br />
Kathodenstrahlröhre. Der nächste Schleifendurchlauf triggert<br />
wieder die Synchronisation und der Kathodenstrahl läuft auf<br />
der gleichen Bahn wie 12 µsec zuvor.<br />
Vertiefung: Mit welcher Frequenz blinkt die Leuchtdiode?<br />
Assembler Version <strong>mit</strong> Präprozessor<br />
In obigem Programm sind typabhängige Werte wie RAMEND<br />
und PORTB als Konstante ins Programm eingetragen. Das
KAPITEL 13. AUFBAU DES SYSTEMS 159<br />
Abbildung 13.13: Schnell blinkende Leuchtdiode
KAPITEL 13. AUFBAU DES SYSTEMS 160<br />
ist nicht nur schlecht zu lesen, sondern macht auch Probleme,<br />
wenn das Programm auf ein anderes Mikrocontrollermodell<br />
portiert werden soll. Deshalb wird normalerweise eine<br />
Datei <strong>mit</strong> dem Befehl .include eingeführt, die die Werte für<br />
das entsprechende Modell definiert. Das avr-binutils-Paket ist<br />
primär auf die Programmiersprache C ausgerichtet. So ist es<br />
verständlich, dass die vom Prozessor abhängigen Includefiles<br />
nur für C und nicht für Assembler vorhanden sind. Mit einem<br />
(nicht ganz sauberen) Trick kann man die C Includefiles auch<br />
für Assembler nutzen. Es wird der C Präprozessor eingesetzt.<br />
avr-cpp -mmcu=atmega48 fastled.s | sed ”s/ + 0x20//g” |<br />
avr-as<br />
Leider muss ein kleines Problem <strong>mit</strong> dem Streameditor sed<br />
ausgebügelt werden. Dies ist natürlich bei der Programmierung<br />
zu berücksichtigen. Statt ” + 0x20” verwende man<br />
”+32”, falls die Konstante gebraucht wird.<br />
An den Anfang der Datei stellt der zusätzliche cpp-Befehl<br />
#include <br />
zusammen <strong>mit</strong> der -mmcu Option die Konstanten als Namen<br />
entsprechend dem Datenblatt von Atmel zur Verfügung. Die<br />
Kommentare der Befehle des obigen Hauptprogramms können<br />
jetzt in die Befehle integriert werden.
KAPITEL 13. AUFBAU DES SYSTEMS 161<br />
Nachdem das Problem der Portabilität gelöst ist, betrachten<br />
wir ein praktisches Problem des Programms: Der Mikrocontroller<br />
ist so schnell, dass das Blinken nicht sichtbar wird. Zwei<br />
Lösungsmöglichkeiten bieten sich an:<br />
• Der Takt des Prozessors wird gebremst, zum Beispiel<br />
auf zwei Hertz.<br />
• Das Programm wird um Warteschleifen erweitert.<br />
Die erste Möglichkeit wird hier nicht vertieft. Der Sockel des<br />
Oszillators lässt Raum für eigene Experimente wie das Takten<br />
<strong>mit</strong> einer prellfreien Taste. Die AVR-Mikrocontroller sind statisch<br />
aufgebaut und funktionieren bis zur oberen Grenze <strong>mit</strong><br />
jeder Taktfrequenz. Diese Eigenschaft ist nicht selbstverständlich!<br />
Langsamer Takt verbraucht weniger Strom. Es ist zu<br />
beachten, dass die Fuses der MCU auf die jeweilige Taktart<br />
eingestellt werden müssen. Das Datenblatt gibt auch hierzu<br />
detaillierte Auskunft. Dies ist eine der Möglichkeiten, den<br />
Mikrocontroller an ein konkretes Projekt anzupassen, auch<br />
skalieren genannt.<br />
Assembler Version <strong>mit</strong> Warteschleifen<br />
Die zweite Möglichkeit, die Blinkfrequenz zu verkleinern, besteht<br />
darin, zwischen dem Umschalten eine Pause einzulegen.<br />
Die Programmschleife zum Schalten der LED wird um Warte-<br />
Aufrufe erweitert:
KAPITEL 13. AUFBAU DES SYSTEMS 162<br />
;// Wait()<br />
Wait:<br />
;// register Cnt1, Cnt2, Cnt3<br />
#define Cnt1 r16<br />
#define Cnt2 r17<br />
#define Cnt3 r18<br />
;// for (Cnt1=100;Cnt1;Cnt1--)<br />
ldi Cnt1, 100<br />
Loop2:<br />
tst Cnt1<br />
breq Endloop2<br />
dec Cnt1<br />
;// for (Cnt2=100;Cnt2;Cnt2--)<br />
ldi Cnt2, 100<br />
Loop3:<br />
tst Cnt2<br />
breq Endloop3<br />
dec Cnt2<br />
;// for (Cnt3=100;Cnt3;Cnt3--)<br />
ldi Cnt3, 100<br />
Loop4:<br />
tst Cnt3<br />
breq Endloop4<br />
dec Cnt3<br />
;// end for<br />
rjmp Loop4<br />
Endloop4:<br />
;// end for<br />
rjmp Loop3<br />
Endloop3:<br />
;// end for<br />
rjmp Loop2<br />
Endloop2:<br />
;// end Wait<br />
ret<br />
;// Main()<br />
Main:<br />
;// DDRB5 becomes output<br />
sbi DDRB,5<br />
;// loop<br />
Loop1:<br />
;// switch on PORTB5<br />
sbi PORTB,5<br />
;// Wait ()<br />
rcall Wait<br />
;// switch off PORTB5<br />
cbi PORTB,5<br />
;// Wait ()<br />
rcall Wait<br />
;// end loop<br />
rjmp Loop1<br />
Endloop1:<br />
Die Warte-Funktion besteht aus einer geschachtelten Zählschleife,<br />
die 100 ∗ 100 ∗ 100 also eine Million mal durchlaufen
KAPITEL 13. AUFBAU DES SYSTEMS 163<br />
wird. Ein so verzögertes Umschalten ist <strong>mit</strong> blosem Auge erkennbar.<br />
Das Assembler-Programm wurde erst in einer zu C ähnlichen<br />
Pseudosprache formuliert, die als Kommentar zwischen<br />
den Befehlen steht. Ein derart strukturiertes Assembler-<br />
Programm kann man schnell entwickeln. Eine lästige Arbeit,<br />
das Erfinden von Sprungmarken wird auf die Verwaltung von<br />
Nummern reduziert. Der Rest ist fast mechanische Übersetzungsarbeit.<br />
Eine Arbeit für die es eigentlich Compiler gibt.<br />
Die Hauptgründe beim heutigen Einsatz von Assembler sind,<br />
die Programmgröße zu minimieren oder die Programmgeschwindigkeit<br />
zu maximieren. Diese beiden Ziele können aber<br />
nur <strong>mit</strong> hohem Aufwand erreicht werden. Vergleicht man die<br />
obige Assembler-Version <strong>mit</strong> der folgenden C-Version der blinkenden<br />
Leuchtdiode, so wird das klar. Hier war der Einsatz<br />
des Assemblers wichtig, um eine Vorstellung von der Arbeitsweise<br />
des Computers zu bekommen.<br />
C Version<br />
Für die folgenden Programmbeispiele ist die Kenntnis der<br />
wichtigsten Eigenschaften der Programmiersprache C Voraussetzung.<br />
//<br />
// Program: led.c<br />
// Funktion: program-sample for c: blinking led<br />
// History: 20031203 HKU creation<br />
//<br />
#include
KAPITEL 13. AUFBAU DES SYSTEMS 164<br />
void wait ()<br />
{<br />
// unsigned char cnt1,cnt2,cnt3; // does not work with -O2 and -O3<br />
// volatile unsigned char cnt1,cnt2,cnt3;<br />
register cnt1,cnt2,cnt3;<br />
for (cnt1=100;cnt1;cnt1--)<br />
for (cnt2=100;cnt2;cnt2--)<br />
for (cnt3=100;cnt3;cnt3--);<br />
}<br />
#define led_DDR DDRB // LED<br />
#define led_PORT PORTB<br />
#define led_PIN PINB<br />
#define led_PB PB5<br />
main()<br />
{<br />
led_DDR |= 1
KAPITEL 13. AUFBAU DES SYSTEMS 165<br />
An dieser Stelle sei erwähnt, daß der Aufruf des gcc eigentlich<br />
mehrere Programme aktiviert:<br />
cpp Der C-Preprozessor bearbeitet alle Zeilen, die <strong>mit</strong> dem<br />
Zeichen # beginnen.<br />
cc Der C-Compiler übersetzt die Sprache C in Assembler.<br />
as Der Assembler übersetzt in relokativen Maschinencode.<br />
Relokativer Code kennt noch keine feste Adresse.<br />
ld Der Linker verbindet eine oder mehrere Objektdateien<br />
(Ausgaben des Assemblers) <strong>mit</strong> den Programmen des<br />
Runtimes zu einem fertigen Maschinenprogramm.<br />
Mit dem Disassembler kann man sehr gut die Erweiterungen<br />
des Programmes durch Teile des Runtime-Pakets erkennen.<br />
In diesem Fall entspricht das der Initialisierung der Interrupt-<br />
Vektoren und der Initalisierung des Arbeitsspeichers.<br />
Interessant sind auch die Optimierungsstufen des Compilers.<br />
Werden die drei Variablen der Funktion wait nicht als register<br />
bzw volatile deklariert, so werden die Schleifen in den<br />
Optimierungsstufen -O2 und -O3 wegoptimiert. Der Compiler<br />
erkennt, dass <strong>mit</strong> den Variablen nichts mehr passiert und<br />
die Schleifen nur Zeit verschwenden und entfernt diese! Aus<br />
diesem Grund sollte man Optimierung erst am Ende der Programmentwicklung<br />
einsetzen.
KAPITEL 13. AUFBAU DES SYSTEMS 166<br />
C Version <strong>mit</strong> Interrupt<br />
Nachdem bisher sehr einfache Programmversionen betrachtet<br />
wurden, um verschiedene Programmiertechniken zu demonstrieren,<br />
soll hier eine Lösung gezeigt werden, die die Möglichkeiten<br />
des Ein-/Ausgabewerks des Mikrocontrollers mehr ausnutzt<br />
und so dem Programm Vorteile verschafft.<br />
//<br />
// Program: led.c<br />
// Funktion: program-sample for c: blinking led, interrupt version<br />
// History: 20031204 HKU creation<br />
//<br />
#include <br />
#include <br />
#define CLOCK 1000000 //7372800 // Hz<br />
#define TIMERCLK 50 // Hz<br />
#define CLOCKSRC0 5 /* CK1024 */<br />
#define CLOCKCNT0 -(CLOCK/1024/TIMERCLK-256)<br />
/* 1024
KAPITEL 13. AUFBAU DES SYSTEMS 167<br />
sei();<br />
for (;;) {<br />
led_PORT |= 1
KAPITEL 13. AUFBAU DES SYSTEMS 168<br />
Ein Nachteil des Verfahrens sei nicht verschwiegen. Die Fehlersuche<br />
in Programmen <strong>mit</strong> Interrupts kann sehr aufwändig<br />
sein, da das Programm nicht mehr Schritt für Schritt abläuft.<br />
Das Prinzip des early testings ist unbedingt anzuwenden. Als<br />
Anfänger sollte man sich Interrupts sehr vorsichtig zuwenden.<br />
Vertiefung: Frequenz des internen RC-Oszillator des Mikrocontrollers<br />
<strong>mit</strong> der Spannungsversorgung des Centronics-<br />
Interfaces (ca. 3 V) ausmessen.<br />
13.4.4 Netzteil<br />
Die Stromversorgung über die Centronics-Schnittstelle schafft<br />
nur wenige Milliampere und wenig mehr als 3 Volt. Schon der<br />
Pegelwandler der RS232-Schnittstelle fordert mehr. Eine externe<br />
Stromversorgung ist deshalb die nächste Baustufe. Besitzer<br />
eines Labornetzteils können darauf natürlich verzichten.<br />
( ) Stl2:Stiftleiste 1polig :einlöten (j56)<br />
( ) :Printbuchse 2.1mm :einlöten<br />
( ) R13 :Widerstand 10k Ohm :liegend einlöten (r56) (n56)<br />
( ) R14 :Widerstand 100kOhm :liegend einlöten (l57) (h57)<br />
( ) D2 :Diode 1N4001 :Anode in r58 einlöten (r58) (o58)<br />
( ) D3 :Diode 1N4001 :Anode in o59 einlöten (r59) (o59)<br />
( ) D4 :Diode 1N4001 :Anode in o60 einlöten (r60) (o60)<br />
( ) D5 :Diode 1N4001 :Anode in r61 einlöten (r61) (o61)<br />
( ) D6 :Diode BAT 43 :Anode in g58 einlöten (g56) (g58)<br />
( ) D7 :Diode BAT 43 :Anode in j60 einlöten (j60) (j62)<br />
( ) Tr1 :BC 547 B :flache Seite n. innen einlöten (m56) (m57)<br />
( ) IC1 :Spannungregler 78L05 :flache Seite n. aussen einlöten (j59) (i59)<br />
( ) C10 :Kondensator 10 uF :+ in g59 einlöten (g59) (g60)<br />
( ) C11 :Kondensator 100 uF 25V :+ in m59 einlöten (m59) (m60)<br />
( ) C12 :Kondensator 10 nF :einlöten (s55) (s56)<br />
Vor dem Einsetzen der Printbuchse werden die äußeren Anschlussfahnen<br />
verkürzt, da<strong>mit</strong> sie als Lötflächen für Anschlußdrähte<br />
dienen können. Für die innere Anschlußfahne muss <strong>mit</strong>
KAPITEL 13. AUFBAU DES SYSTEMS 169<br />
der Laubsäge ein 2,54 mm langer Schlitz in die Platine gesägt<br />
werden.<br />
Das Netzteil ist so ausgelegt, dass es <strong>mit</strong> vielen Steckernetzteilen<br />
zusammen funktioniert. Passt der Stecker, ist nur der<br />
unwahrscheinliche Fall, dass die Spannung zu niedrig oder zu<br />
hoch ist, an den Daten im Anhang B zu prüfen.<br />
Vor der ersten Inbetriebnahme entfernt man den Mikrocontroller.<br />
Vor dem erneuten Einsetzen wird die Funktion des<br />
Netzteils <strong>mit</strong> dem Multimeter geprüft. Die Gleichspannung<br />
muss nahe 5 Volt, die Wechselspannung nahe 0 Volt liegen.<br />
Andernfalls ist die Polung und Funktion aller Bauteile zu kontrollieren.<br />
Vertiefung: Frequenz des RC-Oszillator bei 5 V bestimmen.<br />
13.4.5 Oszillator<br />
Der Prozessor kann auf mehrere Möglichkeiten getaktet werden.<br />
Die internen Register und Speicher benötigen keinen<br />
Takt, um ihren Inhalt zu erhalten. Man nennt derartige Speicher<br />
statisch, im Gegensatz zu dynamisch. Statische Speicher<br />
sind ungefähr um das vierfache aufwändiger als dynamische<br />
Speicher! Aus diesem Grund kann der Prozessor unterhalb der<br />
oberen Grenze <strong>mit</strong> jeder Taktfrequenz versorgt werden. Das<br />
Experimentiersystem wurde <strong>mit</strong> einem Sockel für den Oszillator<br />
ausgestattet, um alle Möglichkeiten offen zu lassen.<br />
Zusätzlich kann der Prozesser durch eine von vier verschiedenen<br />
Techniken <strong>mit</strong> Takt versorgt werden. Die jeweilige Be-
KAPITEL 13. AUFBAU DES SYSTEMS 170<br />
triebsart wird durch Einstellen der Fuses <strong>mit</strong> dem Programm<br />
avrdude ausgewählt.<br />
Interner RC-Oszillator<br />
Der interne RC-Oszillator kann auf 1, 2, 4 oder 8 Mhz eingestellt<br />
werden. Fabrikneue ICs sind auf 1 Mhz voreingestellt.<br />
Diese Variante benötigt keine weiteren Bauteile. Die beiden<br />
freien Anschlüsse können als zusätzliche I/O-Ports genutzt<br />
werden. Leider schwingen RC-Oszillatoren recht ungenau, so<br />
dass zeitkritische Anwendungen, wie z.B. asynchrone serielle<br />
Datenübertragungen einen stabileren Takt erfordern.<br />
Externer RC-Oszillator<br />
Diese Variante macht dann Sinn, wenn die verfügbaren internen<br />
Frequenzen nicht passen.<br />
Externer Quarz<br />
Die gebräuchlichste Variante für zeitlich genaue Anwendungen.<br />
Im Abschnitt 10.2 wurde der Aufbau des Quarzmoduls<br />
als Beispiel vorweggenommen.<br />
Externes Oszillator-IC<br />
Die Lösung besteht aus nur einem Bauteil. Es ist aber teuerer<br />
als die Summe der Teile des selbst gelöteten Quarz-Moduls.<br />
Dafür sind Quarzoszillatoren präzise abgestimmt.
KAPITEL 13. AUFBAU DES SYSTEMS 171<br />
13.4.6 RS232 Schnittstelle<br />
Die relativ einfache Erweiterung unseres Mikrocontrollers um<br />
eine RS232 Schnittstelle schafft neue Möglichkeiten. Nicht nur<br />
für Anwendungen, auch beim Testen und bei der Fehlersuche<br />
gibt es Einsatzgebiete.<br />
( ) Pfo1:Steckerlisten 2x5 90Grad :einlöten (d6)<br />
( ) So4 :DIL-16 Präzisions-Sockel :einlöten (e8)<br />
( ) C4 :Kondensator 100 nF :einlöten (i8) (i9)<br />
( ) C5 :Tantal-Kondensator 1 uF :+ in j12 einlöten (j11) (j12)<br />
( ) C6 :Tantal-Kondensator 1 uF :+ in j13 einlöten (j13) (j14)<br />
( ) C7 :Tantal-Kondensator 1 uF :+ in c9 einlöten (c9) (c10)<br />
( ) C8 :Tantal-Kondensator 1 uF :+ in c11 einlöten (c11) (c12)<br />
( ) Kl3 :Kupferlackdraht 0.2mm :einlöten (e5) (f7)<br />
( ) Kl4 :Kupferlackdraht 0.2mm :einlöten (f5) (g7)<br />
( ) Kl5 :Kupferlackdraht 0.2mm :einlöten (j12) (f9)<br />
( ) Kl6 :Kupferlackdraht 0.2mm :einlöten (i14) (e13)<br />
( ) IC3 :MAX (3)232 N :Pin1 in e8 einsetzen<br />
Abbildung 13.14: Adapter
KAPITEL 13. AUFBAU DES SYSTEMS 172<br />
Als Kabel wird das gleiche 10-adrige Flachbandkabel wie für<br />
die ISP-Schnittstelle verwendet. Zwischen Pfostenbuchse und<br />
RS232-Stecker des PC muss ein selbst gelöteter Adapter eingesetzt<br />
werden: Pin 1 eines Pfostensteckers wird <strong>mit</strong> der Zange<br />
entfernt. Auf der Lötseite des Pfostensteckers werden die restlichen<br />
4 Pins der Reihe etwas in die Richtung des ehemaligen<br />
Pin 1 gebogen. Pin 1 bis Pin 5 einer DB9-Buchse werden <strong>mit</strong><br />
der fünf Pin Reihe des Pfostensteckers verlötet. Die gebogene<br />
vier Pin Reihe wird <strong>mit</strong> den restlichen Pins 6 bis 9 verlötet.<br />
Das Foto der Abbildung 13.14 macht das deutlich.<br />
Falls der Mikrocontroller noch <strong>mit</strong> internem RC-Oszillator arbeitet,<br />
muss ein <strong>mit</strong> Quarz stabilisierter Oszillator eingesetzt<br />
werden. Falls ein IC eingesetzt wird, muss man darauf achten,<br />
dass der Pin 1 anders ausgerichtet ist als bei der CPU! Für<br />
den Betrieb <strong>mit</strong> RS232 eignet sich die Frequenz 7372800 Hz<br />
am besten. Mit dem Programm avrdude werden die Fuses des<br />
Mikrocontrollers so eingestellt, dass er ohne internen Oszillator<br />
arbeitet:<br />
avrdude -c usbasp -p atmega48 -U lfuse:w:0xdc:m<br />
Vertiefung: Man analysiere den Befehl <strong>mit</strong> Hilfe des Datenblatts.<br />
Mit dieser Erweiterung ist das System so weit, Texte auszugeben.<br />
Als Anzeige verwenden wir ein Terminal. Terminals<br />
sind Ein-/Ausgabegeräte für Großrechner. Sie bestehen<br />
aus einer Tastatur, einem Textbildschirm und einer RS232-<br />
Schnittstelle. Eingaben auf der Tastatur gehen zur RS232.
KAPITEL 13. AUFBAU DES SYSTEMS 173<br />
Werden von der RS232 Daten empfangen, werden sie auf<br />
dem Bildschirm angezeigt. Schon lange sind PCs wegen ihrer<br />
großen Verbreitung preiswerter als reine Terminals. Die<br />
Programme, die Terminals simulieren, nennt man Terminalemulationen.<br />
Eine verbreitete Terminalemulation für Linux ist<br />
minicom.<br />
Die Einstellungen des Terminals können im Programm per<br />
Dialog durchgeführt werden. Die Datei $HOME/.minirc.dfl<br />
speichert die Werte für weitere Programmaufrufe:<br />
# Machine-generated file - use setup menu in minicom to change parameters.<br />
pu port /dev/ttyS1<br />
pu baudrate 2400<br />
pu bits 8<br />
pu parity N<br />
pu stopbits 1<br />
Natürlich muss auch der Treiber für serielle Schnittstellen im<br />
Kernel eingebunden sein.<br />
Ein Programm zur Ausgabe eines Textes ist schnell geschrieben:<br />
/*<br />
** Name: software/hello/hello_uart.c<br />
** Funktion: display "hello, world"<br />
** History: 20060405 Hanns-Konrad Unger creation<br />
*/<br />
#include <br />
#define putbyte_clock Clock<br />
#define putbyte_baud 2400<br />
#define putbyte_DDR DDRD<br />
#define putbyte_PORT PORTD<br />
#define putbyte_PIN PIND<br />
#define putbyte_PB PD1<br />
#include "../include/mainboard.h"<br />
#include "../include/putbyte_uart.c" // uses uart
KAPITEL 13. AUFBAU DES SYSTEMS 174<br />
void putstring (unsigned char * ptr) {while (*ptr) putbyte (*ptr++);}<br />
main () {<br />
putbyte_init();<br />
putstring ("\f* Hello World! *\r\n");<br />
putstring ("================\r\n");<br />
}<br />
Die Funktion putstring() ruft die Funktion putbyte() solange<br />
auf, bis der String durch eine Null beendet wird. Diese elegante<br />
C-Lösung eignet sich nur für Fälle, bei denen man sicher<br />
ist, keine Null ausgeben zu müssen. Terminals verwenden die<br />
binäre Null in der Regel nicht. Für die Funktion putbyte()<br />
<strong>mit</strong> der zugehörigen Funktion putbyte init() sollen jetzt drei<br />
Lösungsvarianten gezeigt werden:<br />
RS232 Ausgabe <strong>mit</strong> UART<br />
//<br />
// Name: software/include/putbyte_uart.c<br />
// Function: AVR serial putbyte over UART<br />
// History: 20030213 Hanns-Konrad Unger creation<br />
// Usage: #define putbyte_clock 6553600 /* frequence of system-clock */<br />
// #define putbyte_baud 38400 /* baud-rate */<br />
//<br />
// #include "putbyte_uart.c"<br />
// putbyte_init();<br />
// putbyte (’\n’);<br />
//<br />
#ifndef putbyte_uart_c<br />
#define putbyte_uart_c<br />
#include <br />
#include "mainboard.h"<br />
// at90s4433: UBRR=(putbyte_clock/putbyte_baud/16-1);<br />
#ifdef __AVR_ATmega8__<br />
#define putbyte_T 16<br />
#else // ATmega48 ...<br />
#define putbyte_T 16<br />
#endif<br />
#define putbyte_init()\
KAPITEL 13. AUFBAU DES SYSTEMS 175<br />
UBRR0H = (putbyte_clock/putbyte_baud/putbyte_T-1)>>8;\<br />
UBRR0L = (putbyte_clock/putbyte_baud/putbyte_T-1);\<br />
sbi (UCSR0B,TXEN0);<br />
// UCSRC = (1
KAPITEL 13. AUFBAU DES SYSTEMS 176<br />
#ifndef putbyte_port_c<br />
#define putbyte_port_c<br />
#include "mainboard.h"<br />
#define putbyte_init() sbi (putbyte_DDR, putbyte_PB);\<br />
sbi (putbyte_PORT,putbyte_PB)<br />
void putbyte (unsigned char txbyte)<br />
{<br />
char len = 1+8+1; /* startbit+databits+stopbit */<br />
char carry = 1; /* startbit */<br />
int cnt;<br />
txbyte = ~txbyte;<br />
for (;;)<br />
{<br />
if (carry) // (!carry)<br />
cbi (putbyte_PORT,putbyte_PB);<br />
else<br />
sbi (putbyte_PORT,putbyte_PB);<br />
cnt=putbyte_clock/putbyte_baud/4-4;<br />
#ifdef O0<br />
asm ("loop4cycl: subi r24,1"); /* subtract constant 1 */<br />
asm (" sbci r25,0"); /* compute carrybit */<br />
asm (" brne loop4cycl");<br />
#else<br />
#ifdef O1<br />
while (--cnt);<br />
#else<br />
#error Use "gcc -O1 -DO1 ..." to compile while (--cnt);<br />
#endif<br />
#endif<br />
if (! --len) break;<br />
carry = txbyte % 2;<br />
txbyte /= 2;<br />
}<br />
}<br />
#endif<br />
Die Geschwindigkeit der Übertragung, Baudrate 2 genannt,<br />
wird durch eine Zählschleife beeinflußt. Wie wir schon gesehen<br />
haben, sind Zählschleifen vom Grad der Optimierung<br />
abhängig. Deshalb muss für verschiedene Optimierungsstufen<br />
ein unterschiedlicher Code erzeugt werden.<br />
2 Die Einheit Baud für Impulse pro Sekunde erinnert an den französi-<br />
chen Erfinder Baudot.
KAPITEL 13. AUFBAU DES SYSTEMS 177<br />
Nebenbei kann man das Programm als Definition der Bit-<br />
Übertragungs-Schicht von RS232 ansehen. Sinnvoll einsetzen<br />
kann man das Programm auf den kleineren AVR <strong>Mikrocontrollern</strong>,<br />
die noch keinen UART besitzen.<br />
RS232 Ausgabe <strong>mit</strong> UART und Interrupt<br />
//<br />
// Name: software/include/putbyte_buff.c<br />
// Function: AVR serial putbyte over UART using interrupt<br />
// History: 20031208 Hanns-Konrad Unger creation<br />
// Usage: #define putbyte_clock 6553600 /* frequence of system-clock */<br />
// #define putbyte_baud 38400 /* baud-rate */<br />
//<br />
// #include "putbyte_buff.c"<br />
// putbyte_init();<br />
// putbyte (’\n’);<br />
//<br />
#ifndef putbyte_buff_c<br />
#define putbyte_buff_c<br />
#include "mainboard.h"<br />
#include <br />
#include <br />
// AT90s4433: UBRR = (putbyte_clock/putbyte_baud/16-1);<br />
#define putbyte_init()\<br />
UBRRH = (putbyte_clock/putbyte_baud/16-1)>>8;\<br />
UBRRL = (putbyte_clock/putbyte_baud/16-1);\<br />
sbi (UCSRB,TXEN);\<br />
sei();<br />
// UCSRC = (1
KAPITEL 13. AUFBAU DES SYSTEMS 178<br />
cbi (UCSRB,UDRIE);<br />
}<br />
void putbyte (unsigned char txbyte)<br />
{<br />
while (putbyte_buffil >= putbyte_buflen) asm ("sleep");<br />
cbi (UCSRB,UDRIE);<br />
putbyte_buffer[putbyte_bufput]=txbyte;<br />
putbyte_bufinc(putbyte_bufput);<br />
putbyte_buffil++;<br />
sbi (UCSRB,UDRIE);<br />
}<br />
#endif<br />
Diese Version nutzt die Hardware in vollem Umfang aus.<br />
Zwar werden nicht wenig Programmworte verbraucht, zusätzlich<br />
benötigt das Programm auch noch einen Ringpuffer im<br />
wertvollen Schreib-/Lesespeicher, dafür ist der Bedarf an Rechenzeit<br />
minimal. Beim Aufruf von putbyte init() muss man<br />
berücksichtigen, dass der Interrupt frei geschaltet wird! So<br />
lange der Ringpuffer belegt ist, legt sich die CPU schlafen.<br />
Nachdem das Senden über die RS232-Schnittstelle funktioniert,<br />
ist das Empfangen nicht mehr schwer. Als Hauptprogramm<br />
erstellen wir ein Echo, das empfangene Zeichen einfach<br />
wieder zurückschickt:<br />
/*<br />
** Name: software/rs232/rs232.c<br />
** Funktion: echos keyboard<br />
** History: 20031223 Hanns-Konrad Unger creation<br />
*/<br />
#include <br />
#define putbyte_clock Clock<br />
#define putbyte_baud 2400<br />
#include "../include/putbyte_uart.c" // uses uart<br />
//#include "../include/putbyte_buff.c" // uses uart with interrupt<br />
//#include "../include/putbyte_disp.c" // uses lcd-display<br />
#define getbyte_clock putbyte_clock
KAPITEL 13. AUFBAU DES SYSTEMS 179<br />
#define getbyte_baud putbyte_baud<br />
#include "../include/getbyte_uart.c" // uses uart<br />
//#include "../include/getbyte_buff.c" // uses uart with interrupt<br />
main ()<br />
{<br />
putbyte_init();<br />
getbyte_init();<br />
for (;;)<br />
if (getbyte_ready()) // verhindert, dass getbyte() blockiert<br />
putbyte(getbyte());<br />
}<br />
Wird dies Programm im Mikrocontroller aktiviert und <strong>mit</strong> der<br />
Terminalemulation auf dem PC verbunden, so werden Tastatureingaben<br />
am PC über den Mikrocontroller auf den Bildschirm<br />
der Emulation gebracht.<br />
Die Abfrage von getbyte ready() ist eigentlich nicht notwendig.<br />
In aufwändigeren Programmen wird so verhindert, dass<br />
die Funktion getbyte() blockiert.<br />
Wie beim Hallo-Beispiel gibt es verschiedene Möglichkeiten,<br />
die Funtion des UART zu realisieren:<br />
RS232 Eingabe <strong>mit</strong> UART<br />
//<br />
// Name: software/include/getbyte_uart.c<br />
// Function: AVR serial getbyte over UART<br />
// History: 20031223 Hanns-Konrad Unger creation<br />
// Usage: #define getbyte_clock 6553600 /* frequence of system-clock */<br />
// #define getbyte_baud 38400 /* baud-rate */<br />
//<br />
// #include "getbyte_uart.c"<br />
// getbyte_init();<br />
// if (getbyte_ready()) c=getbyte ();<br />
//<br />
#ifndef getbyte_uart_c<br />
#define getbyte_uart_c<br />
#ifdef __AVR_ATmega8__
KAPITEL 13. AUFBAU DES SYSTEMS 180<br />
#define getbyte_T 16<br />
#else // ATmega48 ...<br />
#define getbyte_T 16<br />
#endif<br />
#define getbyte_init()\<br />
UBRR0H = (getbyte_clock/getbyte_baud/getbyte_T-1)>>8;\<br />
UBRR0L = (getbyte_clock/getbyte_baud/getbyte_T-1);\<br />
sbi (UCSR0B,RXEN0);<br />
#define getbyte_ready() bit_is_set(UCSR0A,RXC0)<br />
unsigned char getbyte () {<br />
loop_until_bit_is_set (UCSR0A,RXC0);<br />
return UDR0;<br />
}<br />
#endif<br />
Auf die Initilisierung von UBRR kann eventuell verzichtet<br />
werden, da sie ja auch von putbyte init() erledigt wird. Dann<br />
bleiben nur sechs Worte Programmcode übrig.<br />
RS232 Eingabe <strong>mit</strong> UART und Interrupt<br />
//<br />
// Name: software/include/getbyte_buff.c<br />
// Function: AVR serial getbyte over UART using interrupt<br />
// History: 20031223 Hanns-Konrad Unger creation<br />
// Usage: #define getbyte_clock 6553600 /* frequence of system-clock */<br />
// #define getbyte_baud 38400 /* baud-rate */<br />
//<br />
// #include "getbyte_buff.c"<br />
// getbyte_init();<br />
// if (getbyte_ready()) c=getbyte();<br />
//<br />
#ifndef getbyte_buff_c<br />
#define getbyte_buff_c<br />
#include <br />
#include <br />
#define getbyte_init()\<br />
UBRRH = (getbyte_clock/getbyte_baud/16-1)>>8;\<br />
UBRRL = (getbyte_clock/getbyte_baud/16-1);\<br />
sbi (UCSRB,RXEN);\<br />
sbi (UCSRB,RXCIE);\<br />
sei();<br />
#define getbyte_bufinc(x) (((x)==getbyte_buflen-1)?((x)=0):((x)+=1))
KAPITEL 13. AUFBAU DES SYSTEMS 181<br />
#define getbyte_buflen 2<br />
static unsigned char getbyte_buffer[getbyte_buflen];<br />
static volatile unsigned char getbyte_bufget = 0;<br />
static volatile unsigned char getbyte_bufput = 0;<br />
volatile unsigned char getbyte_buffil = 0;<br />
#define getbyte_ready() getbyte_buffil<br />
SIGNAL (SIG_UART_RECV)<br />
{<br />
getbyte_buffer[getbyte_bufget]=UDR;<br />
getbyte_bufinc(getbyte_bufget);<br />
if ((++getbyte_buffil)>getbyte_buflen)<br />
getbyte_buffil=getbyte_buflen; // buffer-overrun<br />
}<br />
unsigned char getbyte ()<br />
{<br />
unsigned char c;<br />
while (!getbyte_buffil) asm ("sleep");<br />
cbi (UCSRB,RXCIE); //disabel interrupt SIG_UART_RECV<br />
c=getbyte_buffer[getbyte_bufput];<br />
getbyte_bufinc(getbyte_bufput);<br />
getbyte_buffil--;<br />
sbi (UCSRB,RXCIE);<br />
return c;<br />
}<br />
#endif<br />
Auch diese Version ist aufwändiger als die ohne Interrupt.<br />
Ob sie überhaupt Vorteile bringt, hängt von einer Analyse<br />
der gesamten Anwendung ab. Werden ohne Interrupt Zeichen<br />
verloren, kann diese Version <strong>mit</strong> ausreichend großem Puffer<br />
Abhilfe schaffen. Letztendlich sollte aber auch die Implementierung<br />
eines Hardware-Handshake <strong>mit</strong> CTS und RTS in Betracht<br />
gezogen werden.<br />
RS232 Eingabe ohne UART<br />
Diese Möglichkeit macht dann Sinn, wenn keine UART-<br />
Hardware vorhanden ist. Die Funktion getbyte ready() ist<br />
nicht verfügbar. Nach Entdecken der Flanke des Startbits wird
KAPITEL 13. AUFBAU DES SYSTEMS 182<br />
der halbe Sendezeitraum eines Bits abgewartet. Dann wird die<br />
empfangende Leitung Bit für Bit gelesen und in ein Ergebnisbyte<br />
geschoben. Das Prinzip entspricht dem Sendeprogramm.<br />
Bei der Zeitschleife muss wieder auf die Art der Optimierung<br />
geachtet werden!<br />
Vertiefung: Implementierung des Programms.<br />
Fehler und Fehlersuche<br />
Die Erfahrung zeigt, dass neu geschriebene Programme fehlerhaft<br />
sind. Sehr grob gesagt, besteht ein Programm zu je einem<br />
Viertel aus Planung, Programmierung, Fehlersuche und<br />
Wartung. Die effektivste Methode gegen Fehler heißt ,,early<br />
testing.” Man strebt möglichst kleine Zwischenschritte an,<br />
nach deren Erreichen der neue Programmcode getestet wird.<br />
Da der Fehler <strong>mit</strong> hoher Wahrscheinlichkeit in dem neuen<br />
Programmstück ist, dieses aber klein gehalten wurde, kann er<br />
auch leicht gefunden werden.<br />
Für die Fehlersuche gibt es Werkzeuge verschiedener Art und<br />
Komplexität:<br />
Eine beliebte, da einfache Methode, ist das Verändern des Programms<br />
durch zusätzliche Ausgaben. Leuchtdioden, RS2332<br />
und Display sind geeignet, zusätzliche Meldungen oder Inhalte<br />
von Variablen anzuzeigen, um Soll- und Ist-Werte zu<br />
vergleichen.<br />
Zum Beispiel zeigt das Ein- und Ausschalten einer Leuchtdiode<br />
vor und nach jedem sleep-Befehl, wie beschäftigt der
KAPITEL 13. AUFBAU DES SYSTEMS 183<br />
Mikrocontroller ist. Bewegt man die Platine hin und her,<br />
kann man an Hand der Länge der Striche sogar prozentuale<br />
Schätzungen machen.<br />
Eine etwas aufwändigere Methode ist ein Software-Debugger.<br />
Dies ist ein Programm, welches zusätzlich in den Speicher<br />
geladen wird und eine Dialogschnittstelle bietet, die Befehle<br />
zum Schreiben und Lesen der Speicher und zur Steuerung des<br />
Programmablaufs enthält. Der Vorteil gegenüber der einfachen<br />
Methode ist, dass <strong>mit</strong> einer Programmänderung mehrere<br />
Messungen durchgeführt werden können.<br />
Zuletzt sei noch das aufwändigste Verfahren, der Hardware-<br />
Debugger, erwähnt. Dieses Werkzeug bietet auch ohne Programmänderungen<br />
die Möglichkeit, Messungen vorzunehmen,<br />
idealer Weise sogar unter Echtzeitbedingungen. Früher waren<br />
dafür teure Laborinstrumente notwendig. Die neueren<br />
Prozessoren von Atmel enthalten auf dem Chip Möglichkeiten,<br />
auch <strong>mit</strong> preiswerten Einrichtungen Messungen durchzuführen<br />
(JTEG-Interface, one wire debugging interface).<br />
Hierzu wird ein ICE (in circuit emulator) angeboten.<br />
Software Debugger<br />
Die typische Fehlersuche in einem Programm durchläuft folgende<br />
Schleife:<br />
• Verdächtige Stelle des Programms suchen.
KAPITEL 13. AUFBAU DES SYSTEMS 184<br />
• Sollwert der Variablen an der Stelle des Programms berechnen.<br />
• Programm an der Stelle anhalten.<br />
• Istwert der Variablen bestimmen.<br />
• Differenz von Soll- und Istwert interpretieren.<br />
Der Vergleich von Soll- und Istwert bestätigt oder widerlegt<br />
die Überlegungen, was die Fehlersuche in die Richtung<br />
des Fehlers bewegt. Eine schwierige Situation kann entstehen,<br />
wenn ein Fehlersymptom tatsächlich zwei Ursachen hat. An<br />
diesen Fall sollte man sich erinnern, wenn die Fehlersuche irgendwie<br />
absonderlich wird.<br />
Unser bekanntes Programm dient wieder als Beispiel. Die Pfeile<br />
deuten auf die notwendigen Ergänzungen hin.<br />
/*<br />
** Name: software/debug/main.c<br />
** Funktion: test-main for software-debugger<br />
** History: 20040124 Hanns-Konrad Unger creation<br />
*/<br />
#include "putbyte_uart.c"<br />
#include "../include/debug.c"<br />
char * help_debug_ptr;<br />
static void putstring (unsigned char * ptr) {<br />
help_debug_ptr=ptr;<br />
debug();<br />
while (*ptr) putbyte (*ptr++);}<br />
main() {<br />
debug_init();<br />
for (;;) {<br />
putstring ("* Hello World! *\r\n");<br />
putstring ("================\r\n");<br />
}<br />
}
KAPITEL 13. AUFBAU DES SYSTEMS 185<br />
Vor der Ausgabe des Strings kann der Zustand des Speichers<br />
<strong>mit</strong> der Funktion debug(); begutachtet werden. Die<br />
Zeile #include ’’debug.c’’ stellt den notwendigen Programmcode<br />
zur Verfügung. Etwas mehr als 0.5 KB werden<br />
gebraucht. Für die Initialisierung der seriellen Schnittstelle<br />
sorgt sich das Makro debug init();. Prinzipell wären diese<br />
drei zusätzlichen Zeilen ausreichend. Da die lokale Variable ptr<br />
auf dem Stack steht, debug() jedoch selbst den Stack erweitert,<br />
ist ein Suchen von ptr kompliziert. Die statische Variable<br />
help debug ptr vereinfacht das Verfahren.<br />
Bedienung der Funktion debug()<br />
Befehl Syntax Semantik<br />
read memory rm addr [leng] display leng bytes<br />
write memory wm addr byte *addr = byte<br />
read eeprom re addr [leng] display leng bytes<br />
write eeprom we addr byte *addr = byte<br />
read program rp addr [leng] display leng bytes<br />
continue c return from debug()<br />
Mit dem Befehl make disasm wird der Programmcode untersucht:<br />
00000202 :<br />
202: cf 93 push r28<br />
204: df 93 push r29<br />
206: ec 01 movw r28, r24<br />
208: 90 93 88 00 sts 0x0088, r25<br />
20c: 80 93 87 00 sts 0x0087, r24<br />
210: 8b df rcall .-234 ; 0x128<br />
212: 88 81 ld r24, Y<br />
214: 88 23 and r24, r24<br />
216: 29 f0 breq .+10 ; 0x222<br />
218: 89 91 ld r24, Y+
KAPITEL 13. AUFBAU DES SYSTEMS 186<br />
21a: 20 df rcall .-448 ; 0x5c<br />
21c: 88 81 ld r24, Y<br />
21e: 88 23 and r24, r24<br />
220: d9 f7 brne .-10 ; 0x218<br />
222: df 91 pop r29<br />
224: cf 91 pop r28<br />
226: 08 95 ret<br />
Als Beispiel dient folgende debugging-Sitzung:<br />
c<br />
* Hello World! *<br />
c<br />
================<br />
rm 87 2=60 00<br />
rm 060 10=2A 20 48 65 6C 6C 6F 20 57 6F 72 6C 64 21 20 2A<br />
rm 070 10=0D 0A 00 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D<br />
rm 080 10=3D 3D 3D 0D 0A 00 0D 60 00 8E 2D 0A EF 0F 82 80<br />
rm 5d 2=54 04<br />
rm 450 10=6C 8D 51 00 C8 00 60 00 08 81 01 09 04 5F 01 22<br />
Die Variable help debug ptr (0x87) zeigt erwartungsgemäß<br />
auf den auszugebenden String. Leider sind die auf dem Stack<br />
gespeicherten Rücksprungadressen schwer erkennbar, da sie<br />
um ein Bit nach rechts verschoben sind (0122 ist 0244 kommt<br />
von main, 0109 ist 0212 kommt von putstring). Der letzte auf<br />
dem Stack gespeicherte Wert ist die Variable ptr.<br />
Eine weitere Variante bei der Fehlersuche ist das Ausschalten<br />
der Optimierung des Compilers. Dadurch wird der erzeugte<br />
Code verständlicher.<br />
Mit dem Befehl spm könnte man den Programmspeicher<br />
ändern, um weitere Aufrufe der Funktion debug() an variablen<br />
Stellen zu hinterlegen. Der Befehl funktioniert aber nur<br />
im oberen Bereich des Programmspeichers, der sogenannten<br />
boot-section, was weitergehende Maßnahmen erfordert.
KAPITEL 13. AUFBAU DES SYSTEMS 187<br />
Vertiefung: Die Register des Ein-/Ausgabewerks werden<br />
zusätzlich in den Datenspeicher zwischen die Adressen 0x20<br />
.. 0x5F gespiegelt. Mit dem wm-Befehl des Debuggers kann<br />
man die Leuchtdioden schalten usw...<br />
Uhr<br />
Das nächste Projekt soll eine Uhr sein. Die Quelle des Programms<br />
kann folgendermaßen aussehen:<br />
/*<br />
** Name: software/clock/clock.c<br />
** Funktion: simple clock<br />
** History: 20040112 Hanns-Konrad Unger creation<br />
** 20061010 Hanns-Konrad Unger 32.768KHz<br />
*/<br />
#include <br />
#include <br />
#if Clock > 13107200<br />
#error Clock zu groß<br />
#endif<br />
#if Clock == 32768<br />
#define Timerclk 8<br />
#define PRECISION 64<br />
#define CLOCKSRC0 3<br />
#define CLOCKPERI 64<br />
#else<br />
#define Timerclk 50<br />
#define PRECISION 100<br />
#define CLOCKSRC0 5<br />
#define CLOCKPERI 1024<br />
#endif<br />
#define putbyte_clock Clock<br />
#define putbyte_baud 19200<br />
#define putbyte_DDR DDRD<br />
#define putbyte_PORT PORTD<br />
#define putbyte_PIN PIND<br />
#define putbyte_PB PD1<br />
//#include "putbyte_port.c" // uses I/O-port<br />
//#include "putbyte_uart.c" // uses uart<br />
//#include "putbyte_buff.c" // uses uart with interrupt
KAPITEL 13. AUFBAU DES SYSTEMS 188<br />
#define putbyte_drsDDR DDRB<br />
#define putbyte_drsPORT PORTB<br />
#define putbyte_drsPB PB0<br />
#define putbyte_drwDDR DDRD<br />
#define putbyte_drwPORT PORTD<br />
#define putbyte_drwPB PD7<br />
#define putbyte_deDDR DDRD<br />
#define putbyte_dePORT PORTD<br />
#define putbyte_dePB PD6<br />
#define putbyte_dd4DDR DDRD<br />
#define putbyte_dd4PORT PORTD<br />
#define putbyte_dd4PB PD5<br />
#define putbyte_dd5DDR DDRD<br />
#define putbyte_dd5PORT PORTD<br />
#define putbyte_dd5PB PD4<br />
#define putbyte_dd6DDR DDRD<br />
#define putbyte_dd6PORT PORTD<br />
#define putbyte_dd6PB PD3<br />
#define putbyte_dd7DDR DDRD<br />
#define putbyte_dd7PORT PORTD<br />
#define putbyte_dd7PB PD2<br />
#include "putbyte_disp.c" // uses lcd-display<br />
void putstring (unsigned char * ptr)<br />
{<br />
while (*ptr) putbyte (*ptr++);<br />
}<br />
#define CLOCKCNT0 -(Clock/CLOCKPERI/Timerclk-256)<br />
/* 1024
KAPITEL 13. AUFBAU DES SYSTEMS 189<br />
#define tas2_PB PC4<br />
#define tas3_DDR DDRC<br />
#define tas3_PORT PORTC<br />
#define tas3_PIN PINC<br />
#define tas3_PB PC3<br />
#define tas4_DDR DDRC<br />
#define tas4_PORT PORTC<br />
#define tas4_PIN PINC<br />
#define tas4_PB PC2<br />
#define taster_init() cbi (tas2_DDR,tas2_PB);\<br />
sbi (tas2_PORT,tas2_PB);\<br />
cbi (tas3_DDR,tas3_PB);\<br />
sbi (tas3_PORT,tas3_PB);\<br />
cbi (tas4_DDR,tas4_PB);\<br />
sbi (tas4_PORT,tas4_PB);<br />
void taster ()<br />
{<br />
if ( bit_is_clear(tas4_PIN, tas4_PB) ) uhr.second = uhr.nanosec = 0;;<br />
if ( bit_is_clear(tas3_PIN, tas3_PB) && ! uhr.nanosec ) uhr.minute++;<br />
if ( bit_is_clear(tas2_PIN, tas2_PB) && ! uhr.nanosec ) uhr.hour++;<br />
}<br />
#define Displen 16<br />
char Disp0[Displen+3] = { "\f** Clock **\n" };<br />
char Disp [Displen+2] = { "\r HH:MM:SS " };<br />
// 01234567890123456 78<br />
void displa (unsigned char i1, unsigned char i2)<br />
{Disp[i1++]=i2/10+’0’; Disp[i1]=i2%10+’0’;}<br />
void display()<br />
{<br />
static unsigned char lastval;<br />
if (uhr.nanosec < lastval ) // saves 1 mA<br />
{<br />
displa (5,uhr.hour);<br />
displa (8,uhr.minute);<br />
displa (11,uhr.second);<br />
putstring (Disp);<br />
}<br />
lastval = uhr.nanosec;<br />
}<br />
ISR ( SIG_OVERFLOW0 ) // timer0<br />
{<br />
sei();<br />
TCNT0=CLOCKCNT0;<br />
quarzuhr ();<br />
taster ();<br />
display ();<br />
}
KAPITEL 13. AUFBAU DES SYSTEMS 190<br />
main ()<br />
{<br />
TCCR0B=CLOCKSRC0;<br />
TCNT0=CLOCKCNT0;<br />
sbi (TIMSK0,TOIE0);<br />
taster_init();<br />
putbyte_init();<br />
putstring (Disp0);<br />
sei();<br />
sbi (MCUCR,SE); // enable sleep, sleepmode is default idle<br />
for (;;) {asm ("sleep");} //* 1mA sleep, will be kissed by interrupt */<br />
}<br />
Der timer0 des Ein-/Ausgabewerks wird auf 50 Hz eingestellt,<br />
kann aber auch anders eingestellt werden. Der Timer läuft<br />
synchron zum CPU-Takt. Im Programmteil, der den Interrupt<br />
des timer0 behandelt, werden die Funktionen quarzuhr() und<br />
display() aufgerufen. Die Funktion quarzuhr() führt die uhrentypische<br />
Modulo-Berechnung der Uhrzeit durch. Die Funktion<br />
display() zeigt die Uhrzeit an. Da die Uhrzeit noch nicht<br />
verstellt werden kann, ist unsere Uhr vorerst nur als Stoppuhr<br />
zu gebrauchen, es sei denn, sie wird zur Geisterstunde<br />
eingeschaltet.<br />
Wird das Netzteil <strong>mit</strong> Wechselspannung versorgt, so kann<br />
man an dem einzelnen Pfostenstecker im Netzteil ein Rechtecksignal<br />
abgreifen. Dieses Signal ist zur Netzfrequenz synchron.<br />
Man verbinde es <strong>mit</strong> der offenen Datenleitung 7 des<br />
Displays. Das Display wurde ja noch nicht eingebaut. Das<br />
Netzsignal ist so an den Eingang int0 des Mikrocontrollers<br />
angeschlossen. Die Quarzuhr kann als Netzsynchronuhr betrieben<br />
werden.<br />
Vertiefung: Programm zur Netzsynchronuhr umbauen.
KAPITEL 13. AUFBAU DES SYSTEMS 191<br />
13.4.7 Taster<br />
Um die Uhrzeit verstellen zu können, bauen wir jetzt Taster<br />
ein:<br />
( ) R3 :Widerstand 470 Ohm :liegend einlöten (z5) (z8)<br />
( ) R4 :Widerstand 470 Ohm :liegend einlöten (x5) (x8)<br />
( ) R5 :Widerstand 470 Ohm :liegend einlöten (s5) (s8)<br />
( ) R6 :Widerstand 470 Ohm :liegend einlöten (n5) (n8)<br />
( ) Tas1:Drucktaster :einlöten (C4) (z4)<br />
( ) Tas2:Drucktaster :einlöten (x4) (u4)<br />
( ) Tas3:Drucktaster :einlöten (s4) (p4)<br />
( ) Tas4:Drucktaster :einlöten (n4) (k4)<br />
Zwischen den Aufrufen von quarzuhr() und display() wird<br />
der Aufruf der Funktion taster() eingefügt. Die Ports, an denen<br />
die Taster angeschlossen sind, werden im Hauptprogramm<br />
main() durch das Makro taster init() auf Eingabe und aktivierten<br />
Pullup-Widerstand eingestellt.<br />
#define tas2_DDR DDRC<br />
#define tas2_PORT PORTC<br />
#define tas2_PIN PINC<br />
#define tas2_PB PC4<br />
#define tas3_DDR DDRC<br />
#define tas3_PORT PORTC<br />
#define tas3_PIN PINC<br />
#define tas3_PB PC3<br />
#define tas4_DDR DDRC<br />
#define tas4_PORT PORTC<br />
#define tas4_PIN PINC<br />
#define tas4_PB PC2<br />
#define taster_init() cbi (tas2_DDR,tas2_PB);\<br />
sbi (tas2_PORT,tas2_PB);\<br />
cbi (tas3_DDR,tas3_PB);\<br />
sbi (tas3_PORT,tas3_PB);\<br />
cbi (tas4_DDR,tas4_PB);\<br />
sbi (tas4_PORT,tas4_PB);<br />
void taster ()<br />
{<br />
if ( bit_is_clear(tas4_PIN, tas4_PB) ) uhr.second = uhr.nanosec = 0;;<br />
if ( bit_is_clear(tas3_PIN, tas3_PB) && ! uhr.nanosec ) uhr.minute++;<br />
if ( bit_is_clear(tas2_PIN, tas2_PB) && ! uhr.nanosec ) uhr.hour++;<br />
}
KAPITEL 13. AUFBAU DES SYSTEMS 192<br />
Der Taster4 setzt die Sekunde auf 0. Solange Taster3 gedrückt<br />
wird, werden die Minuten im Sekundentakt hochgezählt. Analog<br />
verstellt Taster2 die Stunden.<br />
13.4.8 Buzzer<br />
Da<strong>mit</strong> sich unser Mikrocontroller auch Gehör verschaffen<br />
kann, bekommt er einen Buzzer. Dies ist ein moderner billiger<br />
Ersatz für Lautsprecher. Zwischen zwei Metallfolien liegt ein<br />
Piezokristall. Unter Spannung verformt sich der Kristall. Wegen<br />
der relativ großen Fläche kann man die Verformung hören.<br />
Die Beine des Bauteils können bei manchen Ausführungen<br />
leicht abbrechen.<br />
( ) R10 :Widerstand 2k7 Ohm :liegend einlöten (p11) (p8)<br />
( ) LED4:Leuchtdioden rot 3mm 2mA :Anode in q12 einlöten (p12) (p13)<br />
( ) R2 :Widerstand 1K Ohm :liegend einlöten (t14) (t11)<br />
( ) C9 :Tantal-Kondensator 1 uF :+ in s10 einlöten (s10) (s11)<br />
( ) Tr2 :BC 547 B :flache Seite n. innen einlöten (r12) (s12)<br />
( ) Beep:Piezobeeper 12 mm :+ in l11 einlöten (l11) (n11)<br />
Um die akustischen Qualitäten dieser vorletzten Baustufe kennen<br />
zu lernen, brauchen wir ein Testprogramm. Ein Frequenzgenerator<br />
auf Basis des timer0 im Mikrocontroller kann <strong>mit</strong><br />
den Tasten umprogrammiert werden. Die erzeugte Frequenz<br />
wird auf dem Buzzer ausgegeben.<br />
/*<br />
** Name: software/generator/generator.c<br />
** Funktion: frequency generator<br />
** History: 20040113 Hanns-Konrad Unger creation<br />
*/<br />
#include
KAPITEL 13. AUFBAU DES SYSTEMS 193<br />
#include <br />
// parameter for Timer0<br />
unsigned short prescaler[6]={ 0,1,8,64,256,1024 };<br />
unsigned char psindex = 5;<br />
unsigned char tim0cnt = 144; // => 25 Hz<br />
#include "mainboard.h"<br />
#include "putbyte_disp.c"<br />
void displa (unsigned long i2)<br />
{<br />
if (i2>=10) displa (i2/10);<br />
putbyte (i2%10+’0’);<br />
}<br />
void display()<br />
{<br />
putbyte (’\f’);<br />
displa (Clock);<br />
putbyte (’H’); putbyte (’z’);<br />
putbyte (’/’); putbyte (’2’); putbyte (’/’);<br />
putbyte (’\r’); putbyte (’\n’);<br />
displa (prescaler[psindex]);<br />
putbyte (’/’);<br />
displa (tim0cnt);<br />
putbyte (’=’);<br />
displa (Clock/2/prescaler[psindex]/tim0cnt);<br />
putbyte (’H’); putbyte (’z’);<br />
}<br />
unsigned char taster (unsigned char n)<br />
{<br />
static unsigned char state [4];<br />
switch (n) {<br />
case 1: if(!state[0] && bit_is_clear(tas1_PIN,tas1_PB)) return state[0]=1;<br />
else if (bit_is_set(tas1_PIN,tas1_PB)) state[0]=0; return 0;<br />
case 2: if(!state[1] && bit_is_clear(tas2_PIN,tas2_PB)) return state[1]=1;<br />
else if (bit_is_set(tas2_PIN,tas2_PB)) state[1]=0; return 0;<br />
case 3: if(!state[2] && bit_is_clear(tas3_PIN,tas3_PB)) return state[2]=1;<br />
else if (bit_is_set(tas3_PIN,tas3_PB)) state[2]=0; return 0;<br />
case 4: if(!state[3] && bit_is_clear(tas4_PIN,tas4_PB)) return state[3]=1;<br />
else if (bit_is_set(tas4_PIN,tas4_PB)) state[3]=0; return 0;<br />
}<br />
}<br />
ISR ( SIG_OVERFLOW0 ) // timer0<br />
{<br />
static unsigned char buzzer;<br />
sei();<br />
TCNT0 = ~tim0cnt;<br />
if (buzzer) {sbi(buzzer_PORT,buzzer_PB);buzzer=0;}<br />
else {cbi(buzzer_PORT,buzzer_PB);buzzer=1;}<br />
}<br />
main ()<br />
{<br />
TCCR0B = psindex;<br />
TCNT0 = ~tim0cnt;<br />
sbi (TIMSK0,TOIE0);
KAPITEL 13. AUFBAU DES SYSTEMS 194<br />
buzzer_init();<br />
putbyte_init();<br />
tas1_init(); tas2_init(); tas3_init(); tas4_init();<br />
display();<br />
sei();<br />
sbi (MCUCR,SE); // enable sleep, sleepmode is default idle<br />
for (;;) {<br />
asm ("sleep");<br />
if (taster(1)) {psindex=psindex>=5?1:psindex+1;<br />
TCCR0B = psindex; display();}<br />
if (taster(2)) {tim0cnt=tim0cnt>156?tim0cnt%100:tim0cnt+100;<br />
display();}<br />
if (taster(3)) {tim0cnt=tim0cnt%100>=90?tim0cnt-90:tim0cnt+10;<br />
display();}<br />
if (taster(4)) {tim0cnt=tim0cnt%10>=9?tim0cnt-9:tim0cnt+1;<br />
display();}<br />
}<br />
}<br />
Das Programm gibt auf der Ausgabe die aktuelle Einstellung<br />
des timer0 aus:<br />
7372800Hz/2/<br />
1024/144=25Hz<br />
Der erste Wert ist die Frequenz des Systemtakts. Die Division<br />
durch 2 ist notwendig, da das Programm bei jedem Ablauf des<br />
Timers den Ausgabeport umschaltet. Für eine ganze Schwingung<br />
sind also zwei Timer-Interrupts notwendig. Die Division<br />
durch 1024 vertritt die Einstellung des Vorteilers, im Datenblatt<br />
wird dieser Prescaler genannt. Der letzte Teiler ist der<br />
Wert des Counters. Prescaler und Counter können <strong>mit</strong> den<br />
Tasten verändert werden. So können alle Einstellungen des<br />
timer0 gehört, gesehen und berechnet werden.<br />
Wird die Einstellung so gewählt, dass das Produkt von Prescaler<br />
und Counter kleiner als 22 wird, stürzt das Programm<br />
ab. Warum?
KAPITEL 13. AUFBAU DES SYSTEMS 195<br />
Vertiefung: Das Programm wird auf den genaueren timer1 des<br />
Mikrocontrollers umgestellt. Der timer1 wird im Datenblatt<br />
ausführlich erklärt.<br />
Beobachtung der eigenen Sinne: Das Gehör eignet sich für<br />
Zeitmessungen weit besser als das Auge.<br />
13.4.9 Display<br />
Die letzte Baustufe des Systems wird am besten steckbar ausgeführt.<br />
So kann statt des Displays andere Hardware ohne<br />
Umstände angeschlossen werden.<br />
( ) R1 :Widerstand 33 Ohm :liegend einlöten (u14) (u18)<br />
( ) C3 :Kondensator 100 nF :einlöten (i18) (h18)<br />
( ) Pot :Potentiometer 10 KOhm lin :stehend einlöten<br />
( ) So5 :Präzisionskontakt-Buchsenl.:einlöten<br />
( ) Ada1:Adapternleiste :<strong>mit</strong> Display verlöten<br />
( ) Mon2:2 Distanzrollen 10mm :montieren<br />
( ) Mon3:2 Schrauben M3x16 :montieren<br />
( ) Mon4:4 Muttern M3 :montieren<br />
Das Display wird <strong>mit</strong> Buchsenleiste, Adapterleiste Distanzrollen<br />
(oder Muttern) und Schrauben auf der Hauptplatine<br />
montiert. Mit dem Potentiometer wird der Kontrast eingestellt.<br />
Bei falscher Einstellung des Potentiometers kann man<br />
auf dem Display nichts erkennen. Meist wird der Kontrasteingang<br />
auf 5 V eingestellt, so dass auf das Potentiometer verzichtet<br />
werden kann.<br />
Für den ersten schnellen Test eignet sich das Hello-Programm<br />
aus dem Abschnitt 13.4.6. Das Unterprogramm putbyte() soll<br />
hier nicht sehr vertieft werden. Es wurde entsprechend dem
KAPITEL 13. AUFBAU DES SYSTEMS 196<br />
Datenblatt HD44780U des Herstellers Hitachi 3 programmiert.<br />
Die im Datenbatt beschriebene Initialisierung muss wie ein<br />
Kochrezept durchgeführt werden:<br />
Power on<br />
Wait > 15ms<br />
Write 0011 function_set.high: 8 bits interface<br />
Wait > 41ms<br />
Write 0011 function_set.high: 8 bits interface<br />
Wait > 100ms<br />
Write 0011 function_set.high: 8 bits interface<br />
Write 0010 function_set.high: 4 bits interface<br />
Write 0010 function_set.high: 4 bits interface<br />
Write 1000 function_set.low : 2 line display, 5*7 dots<br />
Write 0000 display_onoff.high:<br />
Write 1000 display_onoff.low : display off, cursor off, blinking off<br />
Write 0000 display_clear.high:<br />
Write 0001 display_clear.low :<br />
Write 0000 entry_mode_set.high:<br />
Write 0110 entry_mode_set.low : increase cursor, display not shifted<br />
Im Anzeigeprogramm werden drei Steuerzeichen so interpretiert,<br />
dass sie zur Terminalemulation minicom kompatibel<br />
sind:<br />
\r carriage return Der Cursor wird an den Anfang der Zeile<br />
gesetzt.<br />
\n new line Der Cursor wird in die zweite Zeile gesetzt.<br />
\f form feed Die Anzeige wird gelöscht, der Cursor wird an<br />
den Anfang der ersten Zeile gesetzt.<br />
Das Display wird über eine vier Bit parallele Schnittstelle angeschlossen.<br />
Mit Steuersignalen werden sieben Leitungen gebraucht.<br />
Entsprechend umfangreich sind die Definitionen der<br />
Ports:<br />
3 Viele kleine LCD-Anzeigen sind hierzu kompatibel.
KAPITEL 13. AUFBAU DES SYSTEMS 197<br />
#define putbyte_drsDDR DDRB<br />
#define putbyte_drsPORT PORTB<br />
#define putbyte_drsPB PB0<br />
#define putbyte_drwDDR DDRD<br />
#define putbyte_drwPORT PORTD<br />
#define putbyte_drwPB PD7<br />
#define putbyte_deDDR DDRD<br />
#define putbyte_dePORT PORTD<br />
#define putbyte_dePB PD6<br />
#define putbyte_dd4DDR DDRD<br />
#define putbyte_dd4PORT PORTD<br />
#define putbyte_dd4PB PD5<br />
#define putbyte_dd5DDR DDRD<br />
#define putbyte_dd5PORT PORTD<br />
#define putbyte_dd5PB PD4<br />
#define putbyte_dd6DDR DDRD<br />
#define putbyte_dd6PORT PORTD<br />
#define putbyte_dd6PB PD3<br />
#define putbyte_dd7DDR DDRD<br />
#define putbyte_dd7PORT PORTD<br />
#define putbyte_dd7PB PD2<br />
#include "putbyte_disp.c"<br />
Um die Programme übersichtlich zu machen, wurden alle<br />
Definitionen, die das Mainboard betreffen, in der Datei<br />
include/mainboard.h gesammelt. Dieses Vorgehen entspricht<br />
auch dem Schichtenmodell. Änderungen an dem Board<br />
erfordern ausschließlich Änderungen in dieser Datei. Im Makefile<br />
wird dem Compiler das Verzeichnis <strong>mit</strong> der Option -I<br />
bekannt gemacht. So<strong>mit</strong> ist folgende Zeile für die Deklaration<br />
der Hardware ausreichend:<br />
#include "mainboard.h"<br />
Das Entwicklungsystem ist fertig. Im Laufe des Aufbaus wurden<br />
drei Programmierprojekte angefangen, um die Funktionsfähigkeit<br />
zu demonstrieren.<br />
Vertiefung: Ein Testprogramm für das Mainboard verwendet<br />
Leuchtdioden, Buzzer, Taster, RS232 und Display. Eine
KAPITEL 13. AUFBAU DES SYSTEMS 198<br />
Drahtbrücke zwischen TXD und RXD ermöglicht den einfachen<br />
Test der seriellen Schnittstelle, ohne dass Quarz und Gegenstation<br />
erforderlich sind.
Kapitel 14<br />
Erste Experimente<br />
Mit dem Display ist das Mikrocontroller Board zu einem<br />
nützlichen Werkzeug gewachsen. Es lohnt sich, die folgenden<br />
Geräte fertigzustellen, um sie bei Bedarf einzusetzen.<br />
14.1 RS232-Schnittstellen-Tester<br />
Für Arbeiten <strong>mit</strong> RS232-Schnittstellen gibt es billige Mini-<br />
Tester <strong>mit</strong> Leuchtdioden, ferner Wiring-Boxen zum Erstellen<br />
von Leitungskombinationen. Geräte, die die nächste Schicht<br />
<strong>mit</strong> Framelänge und Übertragungsgeschwindigkeit messen,<br />
sind teuer. Mittlerweile werden derartige Geräte durch PC-<br />
Programme verdrängt.<br />
199
KAPITEL 14. ERSTE EXPERIMENTE 200<br />
Unser Mikrocontroller soll eingehende Daten auf dem Display<br />
anzeigen und als Echo wieder senden.<br />
Das Display wird folgendermaßen eingesetzt:<br />
* RS232-Tester *<br />
Testdaten...Test<br />
Die Testdaten in der zweiten Zeile werden von rechts nach<br />
links durchgeschoben.<br />
Das Umschalten geschieht bei fallender Flanke der Taster. Solange<br />
ein Taster gedrückt ist, wird in der oberen Zeile des<br />
Displays die Einstellung des UART angezeigt:<br />
Funktion des Taster1<br />
115200B,8B,nP,2S<br />
Testdaten...Test<br />
Der Taster1 schaltet zwischen ASCII- und Hexadezimalmode<br />
um. Die Hexadezimalzeichen werden durch Leerzeichen getrennt:<br />
Funktion des Taster2<br />
* RS232-Tester *<br />
e 2e 54 65 73 74
KAPITEL 14. ERSTE EXPERIMENTE 201<br />
Der Taster2 ändert die Geschwindigkeit der Übertragung. Es<br />
wird zyklisch zwischen den Geschwindigkeiten 150 300 600<br />
1200 2400 4800 9600 19200 38400 57600 und 115200 Baud<br />
umgeschaltet.<br />
Funktion des Taster3<br />
Der Taster3 schaltet zwischen 5..8 Bit Wortlänge um.<br />
Funktion des Taster4<br />
Der Taster4 schaltet zwischen even odd und no Parity und ein<br />
und zwei Stopbits um.<br />
Funktion der Leuchtdioden<br />
Led1 zeigt Datenüberlauf an.<br />
Led2 zeigt Rahmenfehler an.<br />
Led3 zeigt Paritätsfehler an.<br />
14.2 Frequenzgenerator<br />
Das für den timer1 geänderte Programm wird modifiziert. Die<br />
auszugebende Frequenz wird angezeigt.<br />
* Hz-Generator *<br />
81920 Hertz<br />
Die Frequenz wird <strong>mit</strong> den Tastern folgendermaßen verstellt:
KAPITEL 14. ERSTE EXPERIMENTE 202<br />
Funktion des Taster1<br />
Der Eingabecursor, als blinkende Stelle in der unteren Zeile<br />
des Displays dargestellt, wird nach links verschoben.<br />
Funktion des Taster2<br />
Der Eingabecursor wird nach rechts verschoben.<br />
Funktion des Taster3<br />
Die blinkende Stelle der Frequenzanzeige wird inkrementiert.<br />
Freqenzen die zum Absturz führen würden, werden nicht akzeptiert.<br />
Funktion des Taster4<br />
Die blinkende Stelle der Frequenzanzeige wird dekrementiert.<br />
Frequenzen unter 1 Hz werden nicht eingestellt.<br />
Der Frequenzgenerator erweitert nicht nur das Elektroniklabor,<br />
sondern eignet sich auch für einfache Hörtests.<br />
14.3 Voltmeter<br />
Neben Bit-I/O, seriellem I/O, Timern und Countern verfügt<br />
unser Mikrocontroller über aufwändige analoge Eingangsschaltungen.<br />
Um Spannungen zwischen Masse und Vcc zu<br />
messen, ist keine weitere Hardware notwendig.<br />
Für dieses Experiment wurden Leuchtdioden in drei Farben<br />
eingebaut. An roten LEDs fällt die Spannung ca. 1,6 Volt ab,
KAPITEL 14. ERSTE EXPERIMENTE 203<br />
an gelben ca. 1,7 Volt und an grünen ca. 1,8 Volt. Mit einem<br />
Draht und Prüfspitzen läßt sich leicht zwischen Leuchtdiode<br />
und dem Pin an ADC3 eine Messverbindung herstellen.<br />
Das folgende Programm nutzt die interne Referenzspannung,<br />
die laut Datenblatt beim ATmega8 zwischen 2,45 und<br />
2,80 Volt liegen kann. Für genaue Messungen muss kalibriert<br />
werden.<br />
/*<br />
** Name: software/dvm/dvm.c<br />
** Funktion: Digital Voltage Meter, interrupt and polling version<br />
** History: 20041002 Hanns-Konrad Unger creation<br />
*/<br />
#include <br />
#include <br />
#include "putbyte_disp.c"<br />
#include "../include/adc.c"<br />
#ifdef __AVR_ATmega8__<br />
#define AREF 25575 // calibrate here, nice are 24552 25575 26598 27621<br />
#else // ATmega48 ...<br />
#define AREF 11000<br />
#endif<br />
static void putstring (unsigned char *p) {while (*p) putbyte (*p++);}<br />
unsigned char display_arr[18] = "\r 2.5600 Volt DC";<br />
// 0123456789012345678<br />
void display() {<br />
volatile unsigned short val; //!!!!!!!!!!!!!!!!!!!!!!!!!!!<br />
val=adc_result[3]*(AREF/0x3ff);<br />
unsigned char i;<br />
for (i=8;i>=5;) {display_arr[i--]=val%10+’0’; val/=10;}<br />
display_arr[3]=val+’0’;<br />
putstring (display_arr);<br />
}<br />
ISR (TIMER2_COMPB_vect) { // timer2<br />
sei();<br />
display();<br />
#if adc_FLAG == ADIF<br />
adc();<br />
#endif<br />
}<br />
main() {<br />
led_init();<br />
led1_on(); led2_on(); led3_on(); // Voltages to measure
KAPITEL 14. ERSTE EXPERIMENTE 204<br />
}<br />
putbyte_init();<br />
putstring ("\f* Volt-Meter *\n");<br />
adc_init();<br />
// Timer/Counter2 for 50Hz<br />
OCR2B=Clock/1024/50-1; // count<br />
TCCR2B=7; // prescaler<br />
TCCR2B|=(1
KAPITEL 14. ERSTE EXPERIMENTE 205<br />
Der Inhalt des Feldes function bestimmt die Bedeutung des<br />
zugehörigen Datensatzes.<br />
0x00 Fre Der Datensatz ist frei, darf verändert werden.<br />
0x01 Bu+ Den Buzzer <strong>mit</strong> 2,4 kHz summen lassen.<br />
0x02 Bu- Den Buzzer nicht summen lassen.<br />
0x03 Li+ Die Beleuchtung der LCD-Anzeige einschalten.<br />
0x04 Li- Die Beleuchtung der LCD-Anzeige ausschalten.<br />
0x05 L1+ Die Leuchtdiode LED1 einschalten.<br />
0x06 L1- Die Leuchtdiode LED1 ausschalten.<br />
0x07 L2+ Die Leuchtdiode LED2 einschalten.<br />
0x08 L2- Die Leuchtdiode LED2 ausschalten.<br />
0x09 L3+ Die Leuchtdiode LED3 einschalten.<br />
0x0a L3- Die Leuchtdiode LED3 ausschalten.<br />
0x0b Ch+ Das Stundensignal einschalten.<br />
0x0c Ch- Das Stundensignal ausschalten.<br />
0x0d Tx+ Den Anzeigentext wechseln.<br />
0x0e Tx- Den Anzeigentext wiederherstellen.<br />
0x0f Txt Die Daten des Anzeigetextes.<br />
0xff Der Datensatz darf nicht verändert werden.<br />
Da Datensätze der function 0xff nicht verändert werden<br />
dürfen, wird erst durch Initialisieren des EEPROMS festgelegt,<br />
wieviel der maximal 102 Speicherplätze editierbar sind.<br />
Für den Bediener der Uhr befinden sich vor den Datensätzen<br />
des EEPROMS zwei Datensätze <strong>mit</strong> den Werten von MEZ<br />
und MES. Obwohl diese Sätze nur im RAM gehalten werden,<br />
werden sie beim Editieren <strong>mit</strong> den Tasten <strong>mit</strong> angezeigt.<br />
Mit den Tasten können die Sätze auf folgende Art verändert<br />
werden:
KAPITEL 14. ERSTE EXPERIMENTE 206<br />
Funktion des Taster1<br />
Die untere Zeile der Anzeige schaltet auf den nächsten<br />
veränderbaren Datensatz um. Der erste Datensatz enthält<br />
MEZ. Der zweite Datensatz enthält MES. Dann folgen die<br />
veränderbaren Datensätze des EEPROM. Hinter dem letzten<br />
veränderbare Datensatz des EEPROM steht wieder MEZ.<br />
Funktion des Taster2<br />
Der Cursor der Anzeige wird um eine Position nach rechts verschoben.<br />
Der Cursor ist ein blinkendes Feld der unteren Zeile<br />
der Anzeige. Der Wochentag und die Anzeige der Funktion<br />
blinken komplett. Die Leerstellen und Doppelpunkte werden<br />
übersprungen. Zwischen erstem und letztem Feld befindet sich<br />
eine nicht blinkende Ruhezohne.<br />
Funktion des Taster3<br />
Der zum Cursor gehörige Wert wird um eins erhöht. Die<br />
Wochentage werden folgendermaßen durchgezählt: Mon, Die,<br />
Mit, Don, Fre, Sam, Son, any.<br />
Die Funktion des Speicherplatzes wird ab der aktuellen<br />
gültigen Funktion folgendermaßen zyklisch durchgezählt: Fre,<br />
Bu+, Bu-, Li+, Li-, L1+, L1-, L2+, L2-, L3+, L3-. Die Funktionen<br />
MEZ und MES können nicht verändert werden.<br />
Funktion des Taster4<br />
Analog zu Taster3 nur in anderer Richtung.
Kapitel 15<br />
Weiterführende<br />
Experimente<br />
Nun ist das Experimentiersystem in die Welt gesetzt. Bis auf<br />
die letzten Experimente war alles ziemlich Selbstzweck. War<br />
es wirklich? Das Buch neigt sich dem Ende zu. Für die Beschreibung<br />
weiterer Experimente hat der Autor im Moment<br />
keine Zeit, nur noch Ideen. Hat jemand etwas Zeit und sucht<br />
Vorschläge, um weitere Ideen zu entwickeln? Eine Liste weiterführender<br />
Experimente soll nicht unterschlagen werden.<br />
Über die Nachricht entsprechender Aktivitäten freut sich der<br />
Autor.<br />
207
KAPITEL 15. WEITERFÜHRENDE EXPERIMENTE 208<br />
15.1 Messen<br />
HW: Analog-Input<br />
SW: Voltmeter<br />
SW: Amperemeter<br />
SW: Ohmmeter<br />
SW: 2-Kanal Signaltracer <strong>mit</strong> Display<br />
SW: Frequenzgenerator (Elektor 1998/11 pX2)<br />
15.2 Steuern<br />
HW: SPS (Elektor 2002/11 p22 2002/06 p14)<br />
SW: Bytecode-Interpreter für SPS Elektor (1998/11 p76)<br />
HW: Lichtsensor LDR<br />
SW: Dämmerungsschalter<br />
HW: Näherungsschalter (Elektor 2004/01 p22)<br />
SW: Mit Schalter Led dimmen und schalten<br />
15.3 Regeln<br />
HW: Temperatursensor KTY10 HW: Temperatursensor NTC<br />
(Elektor 2003/10 p24)
KAPITEL 15. WEITERFÜHRENDE EXPERIMENTE 209<br />
SW: Zimmertemperatur auf Display anzeigen<br />
SW: PID-Regler (Elektor 1999/09 p28)<br />
15.4 Solartechnik<br />
HW: Akkus und Solarzelle<br />
SW: Solarladegerät <strong>mit</strong> Überwachung der Ladungsmenge<br />
15.5 Robotik<br />
HW: Modellbauservo<br />
SW: Ansteuern eines Servos<br />
HW: Motor schalten (Elektor 2001/05 p62)<br />
SW: Motor choppen<br />
HW: Spielzeugauto oder -schiff umrüsten<br />
SW: Interpreter für Bytecode<br />
SW: Verbindung zu NQC (not quite C)<br />
15.6 Fernwirken<br />
HW: DCF77 Empfänger
KAPITEL 15. WEITERFÜHRENDE EXPERIMENTE 210<br />
SW: Uhr <strong>mit</strong> DCF synchronisieren<br />
HW: IR-LED (Elektor 2001/04 p62)<br />
SW: Fernsteuern <strong>mit</strong> RC5-Codes (ct 2005/23 p225)<br />
SW: Terminalverbindung über Infrarot (Elektor 2003/10 p12)<br />
HW: RS485 (Elektor 2003/11 p70)<br />
SW: Point/Point Verbindung <strong>mit</strong> PC<br />
SW: Netzwerk<br />
HW: Chrystal CS8900<br />
SW: TCP/IP Stack<br />
HW: 2.4 GHz Funkmodul<br />
SW: Drahtlose Verbindung <strong>mit</strong> dem PC über V24<br />
SW: Gesicherte Verbindung<br />
HW: Mobilfunk (Elektor 2002/01 p14)<br />
SW: Senden/Empfangen von SMS-Nachrichten <strong>mit</strong> einem<br />
Mobilfunktelefon<br />
HW: RFID-Leser (Elektor 2006/09 p36)
Anhang A<br />
Stolpersteine<br />
Erfahrungen, vor denen gewarnt werden soll:<br />
A.1 Reset und Brown-out<br />
Entspricht die Spannungsversorgung nicht den technischen<br />
Daten, so kann es vorkommen, dass der Mikrocontroller unvorhersehbare<br />
Programmsequenzen ausführt. Dies passiert<br />
zum Beispiel auch, wenn ein <strong>mit</strong> Kondensatoren bestücktes<br />
Netzteil ein- oder abgeschaltet wird. Die unangenehme Folge<br />
ist, dass auch Flash oder EEPROM verändert werden können.<br />
Um diesen heimtückischen Effekt zu vermeiden, müssen entweder<br />
im Netzteil oder beim Reset Vorkehrungen getroffen<br />
werden.<br />
211
ANHANG A. STOLPERSTEINE 212<br />
Neuere Modelle der AVR Serie besitzen eine einstellbare<br />
brown-out detection. Diese versetzt den Prozessor bei gefährlichen<br />
Spannungszuständen in den Reset-Zustand.<br />
Auf der anderen Seite kann ein Aktivieren des brown-out bei<br />
mangelhafter Spannungsversorgung zu sporadischem reset des<br />
Programms führen.<br />
A.2 Stackfault<br />
Im RAM müssen sich statische Variable, lokale Variable und<br />
Rücksprungadressen den Platz teilen. Der Compiler füllt das<br />
RAM von unten <strong>mit</strong> statischen Variablen auf. Der Rest bleibt<br />
dem vom Runtime initialisierten Stack, der lokale Variable<br />
und Rücksprungadressen beherbergen muss. Leider ist der<br />
Aufruf von Unterprogrammen schwer, in vielen Fällen sogar<br />
grundsätzlich gar nicht, vorhersehbar. So kann es vorkommen,<br />
dass Stack und statische Variable sich überschreiben.<br />
Dies führt in der Regel zu sonderbarem Programmverhalten<br />
oder zum Programmabsturz. Ein Stackfault-Interrupt für eine<br />
kontrollierte Fehlerbehandlung wäre sehr wünschenswert.<br />
Als einfache Lösung kann man am Anfang jeder Funktion den<br />
Stackpointer überprüfen.
ANHANG A. STOLPERSTEINE 213<br />
A.3 volatile<br />
Der gcc erkennt Code, der Variable nicht verändert. Mit eingeschalteter<br />
Optimierung (default ist -O1!) werden derartige<br />
Programmstücke wegoptimiert. Zum Beispiel bei Warteschleifen<br />
führt das zu unerwartetem Verhalten des Programms.<br />
Wird der gcc <strong>mit</strong> der Option -O0 aufgerufen, so ist die Optimierung<br />
ausgeschaltet. Um trotz Warteschleifen <strong>mit</strong> Optimierung<br />
arbeiten zu können, gibt es für betroffene Variablen die<br />
C-Anweisung ,,volatile”. Die Ur-Version von C kannte diese<br />
Anweisung übrigens noch nicht.<br />
A.4 Interrupts<br />
Wird in einem Interrupt behandelnden Programm der Interrupt<br />
wieder eingeschaltet, so führt ein weiterer Interrupt zur<br />
Unterbrechung des Interrupts. Derartige Programme müssen<br />
reentrant programmiert worden sein. So muss der Zugriff auf<br />
statische bzw. externe Variable über Semaphore gesichert werden.<br />
Da der Compiler Interrupts nicht nachvollziehen kann, müssen<br />
statische Variable, die innerhalb und außerhalb von Interrupts<br />
verwendet werden, als volatile deklariert werden.
ANHANG A. STOLPERSTEINE 214<br />
A.5 PORTx<br />
Der Name PORT verführt dazu, nach dem Löschen des DDR-<br />
Bits daraus zu lesen. Ports müssen jedoch über die Adresse<br />
PINx gelesen werden.<br />
A.6 Watchdog<br />
Der Watchdog erzeugt einen Reset des Systems. Im Runtime<br />
werden alle statischen Variablen vor dem Aufruf von main()<br />
initalisiert. Nach der Definition von C werden im Programm<br />
nicht explizit initalisierte statische Variablen <strong>mit</strong> Null initialisiert.<br />
Dieses Verhalten des Watchdog und von C verhindert,<br />
dass man den sehr stromsparenden Sleepmodus <strong>mit</strong> aktiviertem<br />
Watchdog nicht bei Programmen verwenden kann, die<br />
auf externe oder statische Variable angewiesen sind.<br />
A.7 UCSRC<br />
Das Einstellregister des USARTS teilt sich die selbe Adresse<br />
<strong>mit</strong> UBRRH. Bit7 schaltet zwischen beiden Registern um. Der<br />
Befehl ,,sbi(UCSRC,7)” funktioniert nicht, um anschließend<br />
einzelne Bits umzustellen. Das Register UCSRC darf also nur<br />
komplett beschrieben werden.
ANHANG A. STOLPERSTEINE 215<br />
A.8 Besonderheiten einzelner Modelle<br />
A.8.1 AT90S1200<br />
Da dieses Modell über kein RAM und so<strong>mit</strong> keinen Stack<br />
verfügt, wird es vom gcc nicht unterstützt.<br />
A.8.2 AT90S2343<br />
Es wurden ICs verkauft, die <strong>mit</strong> aktiviertem internem Oszillator<br />
nicht richtig anlaufen. Der Fehler wurde ab Revision G<br />
beseitigt.<br />
A.8.3 Vom AT90S4433 zum ATmega8<br />
Ein Vorteil der AVR-Familie ist die Typenvielfalt. Zeigt sich<br />
im Zuge einer Entwicklung, dass Speicher oder I/O-Leitungen<br />
nicht ausreichen, wechselt man zum nächsten Modell. In der<br />
Regel geht der Umzug relativ einfach, da die Entwickler bei<br />
Atmel bei der Namensgebung von Registern etc. diszipliniert<br />
vorgehen.<br />
Bei gleichem Gehäuse sind viele interne Werte des ATmega8<br />
fast doppelt so gut wie bei seinem Vorgänger. Folgende Änderungen<br />
waren bei einem Umstieg notwendig:
ANHANG A. STOLPERSTEINE 216<br />
• Die Software der Debian 3.0 Distribution kennt den ATmega8<br />
noch nicht. Installation des neueren avr-gcc 3.3,<br />
lib-avr und binutils-avr werden notwendig. Leider bedingt<br />
das auch ein Erneuern der libc. Bis Debian 3.1<br />
hilft Knoppix.<br />
• Der Taktteiler für den USART ist von 8 auf 12 Bit gewachsen.<br />
Aus UBRR wird UBRRL und UBRRH. Der<br />
Compiler erkennt das fehlende Symbol.<br />
• Die Zahl der Sleep-modes hat sich erhöht. Aus SM wird<br />
SM0..2. Auch hier bemerkt der Compiler den Symbolwechsel.<br />
• Der ATmega8 wird <strong>mit</strong> aktiviertem internen 1Mhz Oszillator<br />
geliefert. Um z. B. auf externen Quarz umzustellen,<br />
müssen die Fuses des Prozessors umprogrammiert<br />
werden. Das Datenblatt gibt ausführlich Auskunft.<br />
Dieses ist eine ziemliche Falle, da die meisten Programme<br />
für Mikrocontroller <strong>mit</strong> der Taktfrequenz stark verknüpft<br />
sind. Andererseits garantiert diese Eigenschaft<br />
die Programmierbarkeit eines fabrikneuen Chips in einer<br />
Schaltung ohne externen Oszillator.<br />
Eine umfassende Beschreibung der Unterschiede befindet sich<br />
in der Technical Library von Atmel [atmel] als Application<br />
Note AVR081.
Anhang B<br />
Technische Daten<br />
Spannungen des Experimentiersystems:<br />
Steckernetzteil <strong>mit</strong> Geichspannung (DC) 9 .. 35 V<br />
Steckernetzteil <strong>mit</strong> Wechselspannung (AC) 6 .. 24 V<br />
Batterieversorgung 4.8 .. 6.0 V<br />
CPU 1.8 .. 5.5 V<br />
LED <strong>mit</strong> Vorwiderstand 2.7 .. 5.5 V<br />
Max 232 4.2 .. 5.0 V<br />
(Max 3232 3.0 .. 5.5 V)<br />
Displaytech 162 4.2 .. 5.0 V<br />
Displaybeleuchtung 4.2 .. 5.0 V<br />
217
ANHANG B. TECHNISCHE DATEN 218<br />
Stromverbrauch einzelner Teile des Experimentiersystems:<br />
CPU 3. mA<br />
Oszillator 1. mA<br />
LED 1. mA<br />
Buzzer 4. mA<br />
Max 232 4. mA<br />
Displaytech 162 3. mA<br />
Displaybeleuchtung 10. mA
Anhang C<br />
Nachschlagebereich<br />
C.1 Assembler<br />
Genaue Beschreibung der Befehle befindet sich im Datenblatt<br />
der Firma Atmel ,,8-bit AVR Instruction Set”.<br />
Rechenbefehle<br />
add Rd,Rr Add without Carry<br />
adc Rd,Rr Add with Carry<br />
adiw Rd,K Add Immediate to Word<br />
sub Rd,Rr Subtract without Carry<br />
subi Rd,K Subtract Immediate<br />
sbc Rd,Rr Subtract with Carry<br />
sbci Rd,K Subtract Immediate with Carry<br />
sbiw Rd,K Subtract Immediate from Word<br />
219
ANHANG C. NACHSCHLAGEBEREICH 220<br />
and Rd,Rr Logical And<br />
andi Rd,K Logical And with Immediate<br />
or Rd,Rr Logical Or<br />
ori Rd,K Logical Or with Immediate<br />
eor Rd,Rr Exclusive Or<br />
com Rd One’s Complement<br />
neg Rd Two’s Complement<br />
sbr Rd,K Set Bits in Register<br />
cbr Rd,K Clear Bits in Register<br />
inc Rd Increment<br />
dec Rd Decrement<br />
cp Rd,Rr Compare<br />
cpc Rd,Rr Compare with Carry<br />
cpi Rd,K Compare with Immediate<br />
tst Rd Test for Zero or Minus<br />
clr Rd Clear Register<br />
ser Rd Set Register<br />
mul Rd,Rr Multiply Unsigned<br />
muls Rd,Rr Multiply Signed<br />
mulsu Rd,Rr Multiply Signed with Unsigned<br />
fmul Rd,Rr Fractional Multiply Unsigned<br />
fmuls Rd,Rr Fractional Multiply Signed<br />
fmulsu Rd,Rr Fractional Multiply Signed with Uns.<br />
Jumps<br />
rjmp k Relative Jump<br />
ijmp Indirect Jump to (Z)<br />
eijmp Extended Indirect Jump to (Z)
ANHANG C. NACHSCHLAGEBEREICH 221<br />
jmp k Jump<br />
rcall k Relative Call Subroutine<br />
icall Indirect Call Subroutine to (Z)<br />
eicall Extended Indirect Call Subr. to (Z)<br />
call k Call Subroutine<br />
ret Subroutine Return<br />
iret Interrupt Return<br />
cpse Rd,Rr Compare, Skip if Equal<br />
sbrc Rr,b Skip if Bit in Register Cleared<br />
sbrs Rr,b Skip if Bit in Register Set<br />
sbic Rr,b Skip if Bit in I/O Register Cleared<br />
sbis Rr,b Skip if Bit in I/O Register Set<br />
brbs s,k Branch if Status Flag Set<br />
brbc s,k Branch if Status Flag Cleared<br />
breq k Branch if Equal<br />
brne k Branch if Not Equal<br />
brcs k Branch if Carry Set<br />
brcc k Branch if Carry Cleared<br />
brsh k Branch if Same of Higher<br />
brlo k Branch if Lower<br />
brmi k Branch if Minus<br />
brpl k Branch if Plus<br />
brge k Branch if Greater or Equal, Signed<br />
brlt k Branch if Less Than, Signed<br />
brhs k Branch if Half Carry Set<br />
brhc k Branch if Half Carry Cleared<br />
brts k Branch if T Flag Set<br />
brtc k Branch if T Flag Cleared<br />
brvs k Branch if Overflow Flag is Set
ANHANG C. NACHSCHLAGEBEREICH 222<br />
brvc k Branch if Overflow Flag is Cleared<br />
brie k Branch if Interrupt Enabled<br />
brid k Branch if Interrupt Disabled<br />
Moves<br />
mov Rd,Rr Copy Register<br />
movw Rd,Rr Copy Register Pair<br />
ldi Rd,k Load Immediate<br />
lds Rd,k Load Direct from Data Space<br />
ld Rd,xyz Load Indirect<br />
ld Rd,xyz+ Load Indirect and Post-Increment<br />
ld Rd,-xyz Load Indirect and Pre-Decrement<br />
ldd Rd,yz+q Load Indirect with Displacement<br />
sts k,Rr Store Direct to Data Space<br />
st xyz,Rr Store Indirect<br />
st xyz+,Rr Store Indirect and Post-Increment<br />
st -xyz,Rr Store Indirect and Pre-Decrement<br />
std yz+q,Rr Store Indirect with Displacement<br />
lpm Load Program Memory to R0<br />
lpm Rd,Z Load Program Memory to Register<br />
lpm Rd,Z+ LPM. and Post-Increment<br />
elpm Extended LPM. to R0<br />
elpm Rd,Z Extended LPM. to Register<br />
elpm Rd,Z+ Extended LPM. and Post-Increment<br />
spm Store Program Memory<br />
in Rd,A In from I/O Location<br />
out A,Rd Out to I/O Location<br />
push Rr Push Register to Stack
ANHANG C. NACHSCHLAGEBEREICH 223<br />
pop Rd Pop Register from Stack<br />
Bitbefehle<br />
lsl Rd Logical Shift Left<br />
lsr Rd Logical Shift Right<br />
rol Rd Rotate Left Through Carry<br />
ror Rd Rotate Right Through Carry<br />
asr Rd Arithmetic Shift Right<br />
swap Rd Swap Nibbles<br />
Bset s Flag Set<br />
Bclr s Flag Clear<br />
sbi A,b Set Bit in I/O Register<br />
cbi A,b Clear Bit in I/O Register<br />
bst Rr,b Bit Store from Register T<br />
bld Rd,b Bit Load from Register T<br />
sec Set Carry<br />
clc Clear Carry<br />
sen Set Negative Flag<br />
cln Clear Negative Flag<br />
sez Set Zero Flag<br />
clz Clear Zero Flag<br />
sei Global Interrupt Enable<br />
cli Global Interrupt Disable<br />
ses Set Signed Test Flag<br />
cls Clear Signed Test Flag<br />
sev Set Two’s Complement Overflow<br />
clv Clear Two’s Complement Overflow<br />
set Set T in SREG
ANHANG C. NACHSCHLAGEBEREICH 224<br />
clt Clear T in SREG<br />
seh Set Half Carry Flag in SREG<br />
clh Clear Half Carry Flag in SREG<br />
Control<br />
break Break<br />
nop No Operation<br />
sleep Sleep<br />
wdr Watchdog Reset<br />
Steueranweisungen<br />
.text .data .bss<br />
.string<br />
.word<br />
.byte<br />
C.2 Programmiersprache C<br />
Neben verschiedensten Büchern über C findet man die<br />
ursprüngliche Beschreibung der Sprache im Buch ,,Die<br />
Programmiersprache C” der Autoren der Sprache Kernighan/Ritchie<br />
[Kernighan].
ANHANG C. NACHSCHLAGEBEREICH 225<br />
Operatoren<br />
( ) [ ] -> .<br />
! ~ ++ -- + - * & (type) sizeof<br />
* / %<br />
+ -<br />
><br />
< >=<br />
== !=<br />
&<br />
^<br />
|<br />
&&<br />
||<br />
?:<br />
= += -= *= /= %= &= ^= |= =<br />
,<br />
Präprozessor<br />
define undef<br />
include<br />
line error pragma<br />
if elif else endif<br />
ifdef ifndef<br />
Sprachelemente<br />
static extern<br />
const volatile auto register
ANHANG C. NACHSCHLAGEBEREICH 226<br />
signed unsigned<br />
void char short int long float double<br />
struct union enum typedef<br />
sizeof<br />
if else<br />
do while for continue<br />
switch case break default<br />
goto return<br />
Erweiterungen<br />
asm<br />
C.3 Runtime<br />
Die Schnittstellen des Runtimes findet man im Verzeichnis<br />
/usr/avr/include.<br />
#include <br />
#define bit_is_set(port,bit) ...<br />
#define bit_is_clear(port,bit) ...<br />
#define loop_until_bit_is_set(port,bit) ...<br />
#define loop_until_bit_is_clear(port,bit) ...<br />
#define RAMEND 0x45F<br />
#define E2END 0x1FF<br />
#define FLASHEND 0x1FFF<br />
#define SIG_INTERRUPT0 _VECTOR(1)<br />
.<br />
.<br />
.
ANHANG C. NACHSCHLAGEBEREICH 227<br />
#include <br />
extern uint8_t eeprom_read_byte (uint8_t *addr);<br />
extern uint16_t eeprom_read_word (uint16_t *addr);<br />
extern void eeprom_read_block (void *buf, void *addr, size_t n);<br />
extern void eeprom_write_byte (uint8_t *addr, uint8_t val);<br />
extern void eeprom_read_block (void *buf, void *addr, size_t n);<br />
#include <br />
typedef void prog_void PROGMEM;<br />
typedef char prog_char PROGMEM;<br />
typedef unsigned char prog_uchar PROGMEM;<br />
typedef int prog_int PROGMEM;<br />
typedef long prog_long PROGMEM;<br />
typedef long long prog_long_long PROGMEM;<br />
extern void *memcpy_P(void *, PGM_VOID_P, size_t);<br />
extern char *strcat_P(char *, PGM_P);<br />
extern int strcmp_P(const char *, PGM_P) __ATTR_PURE__;<br />
extern char *strcpy_P(char *, PGM_P);<br />
extern int strcasecmp_P(const char *, PGM_P) __ATTR_PURE__;<br />
extern size_t strlen_P(PGM_P) __ATTR_CONST__;<br />
extern int strncmp_P(const char *, PGM_P, size_t) __ATTR_PURE__;<br />
extern int strncasecmp_P(const char *, PGM_P, size_t) __ATTR_PURE__;<br />
extern char *strncpy_P(char *, PGM_P, size_t);<br />
#include <br />
#define ISR (signame) ...<br />
#define sei() ...<br />
#define cli() ...
Anhang D<br />
Programm pcb<br />
#!/bin/bash<br />
#.#############################################################################<br />
#. Programheader<br />
#.#############################################################################<br />
Prognam="pcb"<br />
Version="0.1-20060322"<br />
Maintainer="Hanns-Konrad Unger "<br />
Description="tool for creating printed circuit boards (pcbs)"<br />
Architecture="all"<br />
Section="electronics"<br />
Priority="optional"<br />
Depends="bash (>= 2.05)"<br />
Location="/usr/bin"<br />
Programheader () { cat
ANHANG D. PROGRAMM PCB 229<br />
Myp=$0 # Patch here if next if exits<br />
if [ ! -x "$Myp" ]<br />
then echo Please use latest version of bash or ash.; exit -1; fi<br />
Myn=$(basename $Myp) # My Name<br />
Noa=$# # Number Of Args<br />
Dir=$(echo $Myp|sed -e s#$Myn\$## -e s#/\$## ) # Directory program comes from<br />
if [ "$Dir" = "" ]; then Dir=.; fi<br />
Nam=$(echo $Myn|sed s/\\..*//) # Name of programfile without dot<br />
Fun=$(echo $Myn|sed s/${Nam}.//) # Name of running method<br />
Edi=/bin/vi # prefered editor<br />
Lom="" # List Of Methods<br />
Lop="" # List OF temP. files 20020107<br />
Lot="basename sh echo sed type" # List Of Tools<br />
Loc="class" # List Of Classes<br />
#.Added:2005May07:class:new:pcb:Global Variables<br />
Loc="$Loc pcb"<br />
#.Added:2006Nov18:pcb:new:pcb:Global Variables<br />
Loc="$Loc pcb"<br />
#.#############################################################################<br />
#. Global Functions<br />
#.#############################################################################<br />
# Debug () { bash; } # 1st line MUST BE: #!/bin/bash -a<br />
# Debug () { set | less; } # see all variables<br />
# Debug () { set -x; } # activates bash -x<br />
# Debug () { set -v; } # activates bash -v<br />
# Debug () { echo $@; sleep 5; }<br />
# Debug () { logger $@; }<br />
# Debug () { export $@; bash; }<br />
Exit_onerror () # $1=programname; run very critical program<br />
{ if ! $1 ; then echo $Myn aborted: Error running $1 !; Quit -1; fi; }<br />
Testargs () { # testarguments num [file]<br />
if [ $Noa -lt $1 ]; then Met=man; $Nam.$Fun; Quit -1; fi<br />
if [ -z "$2" ]; then return; fi<br />
if [ "$2" = "-" ]; then return; fi # stdin<br />
if ! [ -f "$2" ]; then echo Cannot find $2!; Quit -1; fi; }<br />
Lot="$Lot mktemp"<br />
Mktmp_return="" # Mktmp() is string_function, $() does not change global $Lop<br />
Mktmp () { # make temporary File 20021118 HKU<br />
local n=$(mktemp Tmp$$XXXXXX); Lop="$(pwd)/$n $Lop"; Mktmp_return=$n; }<br />
Mktmpdir () { # make temporary Dir<br />
local n=$(mktemp -d Tmp$$XXXXXX); Lop="$(pwd)/$n $Lop"; Mktmp_return=$n; }<br />
Lot="$Lot ln"<br />
Install () { (cd $Dir;ln -sf $Myn $1 2>/dev/null); }<br />
Lot="$Lot rm"<br />
Deinstall () { rm $Dir/$1; }<br />
Quit () {<br />
local n<br />
for n in $Lop; do<br />
if [ -f $n ]; then rm $n;<br />
else if [ -d $n ]; then rmdir $n; fi; fi<br />
done; exit $1; }<br />
#.Added:2005May07:class:new:pcb:Global Functions<br />
#.Added:2006Nov18:pcb:new:pcb:Global Functions<br />
pslayout () {<br />
echo "%!PS-Adobe-1.0"<br />
echo "%%Title: $(echo $1|sed s/\\..*//).ps"<br />
echo "%%Creator: ${Myn} from www.hanns-konrad.de"<br />
echo -n "%%Date: "; date "+%Y%b%d %H:%M"<br />
cat
ANHANG D. PROGRAMM PCB 230<br />
/mm { 25.4 div 72 mul } def<br />
/inch { 72 mul } def<br />
/pt { 1 mul } def<br />
/white [ 1.0 1.0 1.0 ] def<br />
/black [ 0.0 0.0 0.0 ] def<br />
/setcolor { aload pop setrgbcolor } def<br />
/leftmargin 25.4 mm def<br />
/topmargin 10 mm def<br />
/pageheight 297 mm def /pagewidth 210 mm def % a4<br />
%%EndProlog<br />
/boardscale 1 def % 1 is normal scale, 2 is wide scale<br />
/psize 7.2 def % diameter of one pad (0.1 inch)<br />
% /xpos 0 def % xresult of cvpad<br />
% /ypos 0 def % yresult of cvpad<br />
/multpcb false def % Platine nur einfach ausgeben<br />
/multx 1 def % Kopien in x-Richtung<br />
/multy 1 def % Kopien in y-Richtung<br />
% /dx 0 def % x-size<br />
% /dy 0 def % y-size<br />
1 setlinejoin<br />
/cvpad % (a15) cvpad => xpos=1 ypos=15 ; works from (a1)..(z1),(A1)..(Z1)<br />
% to (Z113)<br />
{<br />
dup 0 get<br />
dup 64 le % A-1<br />
{ pop 0 }<br />
{ dup 90 le % Z<br />
{ 64 sub 26 add }<br />
{ dup 96 le % a-1<br />
{ pop 0 }<br />
{ dup 122 le % z<br />
{ 96 sub }<br />
{ pop 0<br />
} ifelse<br />
} ifelse<br />
} ifelse<br />
} ifelse<br />
/xpos exch def<br />
dup length 1 sub 1 exch getinterval cvi /ypos exch def<br />
} def<br />
/mboard { /multy exch def /multx exch def /multpcb true def } def<br />
/board2 { /boardscale 2 def /psize psize 2 div def board } def<br />
/board % (n15) board<br />
{<br />
cvpad /dy ypos 1 add def /dx xpos 1 add def<br />
/st ( ) def<br />
[ 1 0 0 -1 0 0 ] concat<br />
multpcb<br />
{<br />
leftmargin<br />
pageheight topmargin sub -1 mul<br />
translate
ANHANG D. PROGRAMM PCB 231<br />
psize psize scale<br />
0 setlinewidth<br />
1 1 multy<br />
{<br />
/y exch def<br />
1 1 multx<br />
{<br />
1 sub dx mul y 1 sub dy mul moveto<br />
dx 0 rlineto 0 dy rlineto dx -1 mul 0 rlineto closepath stroke<br />
} for<br />
} for<br />
}<br />
{<br />
pagewidth leftmargin sub dx psize mul sub 2 div leftmargin add<br />
pageheight dy psize mul add -2 div<br />
translate<br />
psize psize scale<br />
0 setlinewidth<br />
0 0 moveto dx 0 lineto dx dy lineto 0 dy lineto closepath stroke<br />
/Courier findfont .8 scalefont setfont<br />
1 1 dx 1 sub<br />
{<br />
dup -1 moveto<br />
dup 26 gt<br />
{ 64 add 26 sub } % A..Z<br />
{ 96 add } ifelse % a..z<br />
st exch 0 exch put st<br />
[ 1 0 0 -1 0 0 ] concat -.4 0 rmoveto show [ 1 0 0 -1 0 0 ] concat<br />
} for<br />
1 1 dy 1 sub<br />
{<br />
dup -1 exch moveto 10 (999) cvrs<br />
[ 1 0 0 -1 0 0 ] concat -1 -.4 rmoveto show [ 1 0 0 -1 0 0 ] concat<br />
} for<br />
} ifelse<br />
} def<br />
/iwire % (a1) (c3) iwire<br />
{<br />
exch<br />
cvpad<br />
/xlen xpos def /ylen ypos def<br />
cvpad<br />
/xlen xlen xpos sub def /ylen ylen ypos sub def<br />
0 1 multy 1 sub<br />
{<br />
dy mul ypos add /y exch def<br />
0 1 multx 1 sub<br />
{<br />
dx mul xpos add y moveto xlen ylen rlineto closepath stroke<br />
} for<br />
} for<br />
} def<br />
/wire % (a1) (c3) wire<br />
{<br />
0.2 setlinewidth<br />
iwire<br />
} def
ANHANG D. PROGRAMM PCB 232<br />
/wire2 % (a1) (c3) wire2<br />
{<br />
0.8 setlinewidth<br />
iwire<br />
} def<br />
/ipad<br />
{<br />
0 setlinewidth<br />
0 1 multy 1 sub<br />
{<br />
dy mul ypos add /argy exch def<br />
0 1 multx 1 sub<br />
{<br />
dx mul xpos add /argx exch def<br />
argx argy 0.3 boardscale mul 0 360 arc fill<br />
white setcolor argx argy 0.1 boardscale mul 0 360 arc fill black setcolor<br />
} for<br />
} for<br />
} def<br />
/pad % (a1) pad<br />
{ cvpad ipad } def<br />
/smd<br />
{<br />
cvpad<br />
0 setlinewidth<br />
0 1 multy 1 sub<br />
{<br />
dy mul ypos add /argy exch def<br />
0 1 multx 1 sub<br />
{<br />
dx mul xpos add .25 sub argy .25 sub moveto<br />
.5 0 rlineto 0 .5 rlineto -.5 0 rlineto closepath fill<br />
} for<br />
} for<br />
} def<br />
/xpad % (a1) 3 xpad => (a1) pad (b1) pad (c1) pad<br />
{ 1 sub boardscale mul exch cvpad xpos exch boardscale exch xpos add<br />
{ /xpos exch def ipad } for<br />
} def<br />
/ypad % (a1) 3 ypad => (a1) pad (a2) pad (a3) pad<br />
{ 1 sub boardscale mul exch cvpad ypos exch boardscale exch ypos add<br />
{ /ypos exch def ipad } for<br />
} def<br />
/mirror { pagewidth 0 translate -1 1 scale } def<br />
%(n15)board (n1)(n15)wire (a1)pad(n1)pad(n14)pad(n15)smd (c3)4 xpad(e3)4 ypad<br />
end_of_pslayout<br />
}<br />
#.#############################################################################<br />
#. Methods<br />
#.#############################################################################<br />
################################## info ###################################<br />
Lot="$Lot cat echo"
ANHANG D. PROGRAMM PCB 233<br />
Lom="$Lom info"; pcb.info () { funcname=$Nam.info # 20011207 HKU<br />
case $Met in<br />
help|man) echo "Usage: $funcname [tutorial]"<br />
if test "$Met" = "man"; then echo Informs about programs concepts.; fi;;<br />
doit) Testargs 0;<br />
case "$1" in<br />
"")<br />
cat
ANHANG D. PROGRAMM PCB 234<br />
Global Variables<br />
Global Functions<br />
Methods<br />
Main<br />
müssen in DIESER Reihenfolge vorhanden sein.<br />
#. bedeutet, daß der Kommentar von class verarbeitet wird.<br />
Solche Kommentare dürfen nicht entfernt werden!<br />
Globale Namen Beginnen Mit Einem Großbuchstaben.<br />
VOM SYSTEM ANGEBOTENE VARIABLE SIND I.D.R. KOMPLETT GROSS.<br />
lokale namen sollten klein geschrieben werden.<br />
Für die Anwendung dieses Programmiersystems sind grundlegende Kenntnisse der<br />
(b)ash notwendig (siehe "man bash").<br />
Es folgt eine Liste der Vorzüge des Konzeptes:<br />
Die Bildung von Programmfamilien fördert die Benutzerfreundlichkeit:<br />
Einziger Zugang über den Klassennamen.<br />
Einheitliche Benutzerschnittstelle.<br />
Einheitliche Hilfefunktionen.<br />
Integrierte Installation und Deinstallation.<br />
Integrierte Überprüfung der Systemvoraussetzungen.<br />
Vererbung bessert die Programmqualität:<br />
Fehlerminderung durch Verwendung bewährten Codes.<br />
Kompaktheit durch mehrfache Verwendung des Codes.<br />
Zentrale Haltung globaler Variablen.<br />
Klassenbildung fördert die Tiefe der Problemanalyse.<br />
Programmstruktur ist vorbestimmt.<br />
Kinder erben Funktionalität der Eltern<br />
(z.B. Dokumentation und Installation)<br />
Abgeschlossenheit erhöht die Verfügbarkeit des Programms:<br />
Programminstallation ist überschaubar.<br />
Programmverbreitung ist so einfach wie das Kopieren einer Datei.<br />
Verwendung üblicher Tools wie bash und textutils:<br />
Minimale Systemvoraussetzungen<br />
Portabel<br />
Sofortige Einsetzbarkeit<br />
Wartungsarm, da geringe Umgebungsänderungen zu erwarten.<br />
Programmcode ist eine einfache Text-Datei:<br />
Das Programm ist einsehbar.<br />
Das Programm ist änderbar.<br />
Reinkarnation erhöht die Verfügbarkeit des Konzepts:<br />
Jede Programmkopie verbreitet das Programmiersystem.<br />
Die Verbreitung des Systems erhöht die Benutzerfreundlichkeit.<br />
end_of_info<br />
;;<br />
"tutorial")<br />
cat
ANHANG D. PROGRAMM PCB 235<br />
if test "$Met" = "man"; then cat
ANHANG D. PROGRAMM PCB 236<br />
local m=./usr/share/man/man1<br />
if ! [ -d $c ]; then mkdir $c; chmod 755 ${c}; fi<br />
echo "Call $Nam for copyright-information." >${c}/copyright<br />
echo "Call $Nam for changelog-information." >${c}/changelog.Debian<br />
gzip -9 ${c}/changelog.Debian<br />
chmod 644 ${c}/*<br />
cat >${m}/$Nam.1<br />
(exec $Dir/$Nam.man $n|sed -e 2,\$d -e "s/[^\\.]*\\./.B /" >>${m}/$Nam.1)<br />
(exec $Dir/$Nam.man $n|sed 1d >>${m}/$Nam.1)<br />
done<br />
cat ${m}/$Nam.1<br />
.RE<br />
.SH INFO<br />
EOF<br />
(exec $Dir/$Nam.info >>${m}/$Nam.1)<br />
cat ${m}/$Nam.1<br />
.SH AUTHOR<br />
This manual page was written by $Nam.makedeb.<br />
EOF<br />
gzip -9 ${m}/$Nam.1<br />
chmod 644 ${m}/$Nam.1.gz<br />
tar -zcvf $d.tar.gz .${Location}/$Nam ${c} ${m}/$Nam.1.gz<br />
ar -r ${Nam}_${Version}_${Architecture}.deb \<br />
debian-binary control.tar.gz $d.tar.gz<br />
rm debian-binary control.tar.gz $d.tar.gz<br />
mv ${Nam}_${Version}_${Architecture}.deb $pwd # 20021105 HKU<br />
if [ $Dir != $Location ]; then # 20021121 HKU<br />
rm $Location/$Nam $Location/$Nam.include<br />
fi<br />
;; esac; } # end of method makedeb<br />
################################### new ###################################<br />
Lot="$Lot grep"<br />
Lom="$Lom new"; pcb.new () { funcname=$Nam.new<br />
case $Met in
ANHANG D. PROGRAMM PCB 237<br />
help|man) echo "Usage: $funcname CLASSNAME"<br />
if test "$Met" = "man"; then cat >$tmp<br />
cat $tmp<br />
Prognam="class"<br />
Version="0.4-20050506"<br />
Maintainer="Hanns-Konrad Unger "<br />
Description="Classes for ash and bash"<br />
Architecture="all"<br />
Section="devel"<br />
Priority="optional"<br />
Location="/usr/bin"<br />
Programheader () { cat $tmp;cutsection "$1" $Myp|sed "/^#.Added:/,\$d" >>$tmp;}<br />
gensection "Global Variables"<br />
gensection "Global Functions"<br />
gensection "Methods"<br />
genheader "Main" >>$tmp; cutsection "Main" $Myp >>$tmp<br />
else # new class, no reincarnation<br />
local i=$Dir/$Nam.include<br />
local c=$1<br />
gensection () { # sectionname<br />
genheader "$1" >>$tmp; cutsection "$1" $Myp >>$tmp<br />
echo "#.Added:$(date +%Y%b%d):$Nam:new:$c:$1" >>$tmp<br />
if test -f $i; then cutsection "$1" $i >>$tmp; fi; }<br />
echo ’#!’"/bin/bash" >$tmp<br />
genheader "Programheader" >>$tmp
ANHANG D. PROGRAMM PCB 238<br />
if test -f $i; then local h=$i; else local h=$Myp; fi<br />
cutsection "Programheader" $h|sed "/^#.Usage:/,\$d" >>$tmp<br />
history $1 >>$tmp<br />
cutsection "Programheader" $h|sed -n "/^#.Usage:/,\$p" >>$tmp<br />
gensection "Global Variables"<br />
echo "Loc=\"\$Loc $1\"" >>$tmp<br />
gensection "Global Functions"<br />
gensection "Methods"<br />
genheader "Main" >>$tmp; cutsection "Main" $Myp >>$tmp<br />
fi<br />
sed s/${Nam}\\./$1./g $tmp >$1 # (re)name new class<br />
mv $1 $tmp<br />
sed -n 1,4p $tmp >$1<br />
echo " Prognam=\"$1\"" >>$1<br />
sed -n 6,\$p $tmp >>$1<br />
chmod a+x,a+r $1<br />
### grep $1 $1<br />
if test -f $1.include -o $1 = class; then # create no include<br />
ls -l $1.include<br />
echo "----- No $1.include created. -----"<br />
else # create include for new class<br />
genheader "Programheader" >$1.include<br />
chmod a+r $1.include<br />
cutsection "Programheader" $1 >>$1.include<br />
genheader "Global Variables" >>$1.include<br />
genheader "Global Functions" >>$1.include<br />
genheader "Methods" >>$1.include<br />
cat $1.include<br />
################################ example #################################<br />
#Lot="\$Lot" # List Of Tools (to check installation)<br />
#Lom="\$Lom example"; $1.example () { funcname=$1.example # 20020424 HKU $1<br />
#case \$Met in<br />
# help|man) echo "Usage: \$funcname"<br />
# if test "\$Met" = "man"; then cat
ANHANG D. PROGRAMM PCB 239<br />
pcb.layout makes postscriptfile for layout<br />
pcb.mlayout makes multiple layouts (for schools..)<br />
pcb.list generate part-list<br />
** pcb.move dx dy move a circuit<br />
** pcb.rotate rotate a circuit 90 degree<br />
** pcb.parts make part-position-plan<br />
pcb.kit Heathkit-Style soldering instructions<br />
** Todo<br />
Example of a circuit-list for input:<br />
------------------------------------------------------------------------<br />
#<br />
# Name: ispbsd.pcb<br />
# Function: Atmel ISP interface for uisp -dprog=bsd<br />
# Centronics If. Atmel Progrport.<br />
# Pin02 Data0 --> Vcc Pin02<br />
# Pin03 Data1 --> Vcc Pin02<br />
# Pin04 Data2 --> Vcc Pin02<br />
# Pin05 Data3 --> Vcc Pin02<br />
# Pin06 Data4 --> /Enable<br />
# Pin07 Data5 --> /Reset Pin05<br />
# Pin08 Data6 --> SCK Pin07<br />
# Pin09 Data7 --> MOSI Pin01<br />
# Pin10 Ack
ANHANG D. PROGRAMM PCB 240<br />
(e10)pad :0:B5 :Draht : :nach Pin8 einlöten<br />
(g8)pad :0:B6 :Draht : :nach Pin7 einlöten<br />
(i10)pad :0:B7 :Draht : :nach Pin6 einlöten<br />
(e13)pad :0:B8 :Draht : :nach Pin9 einlöten<br />
(f13)pad :0:B9 :Draht : :nach Pin7 einlöten<br />
(g13)pad :0:B10 :Draht : :nach Pin5 einlöten<br />
(h13)pad :0:B11 :Draht : :nach Pin3 einlöten<br />
(i13)pad :0:B12 :Draht : :nach Pin1 einlöten<br />
(i4)pad :4:D1 :Schottkydioden BAT43 :153010:nach Pin5 einlöten<br />
(j4)pad :0:D2 :Schottkydiode BAT43 :153010:nach Pin4 einlöten<br />
(k4)pad :0:D3 :Schottkydiode BAT43 :153010:nach Pin3 einlöten<br />
(l4)pad :0:D4 :Schottkydiode BAT43 :153010:nach Pin2 einlöten<br />
(i5)pad(j5)pad :1:LED1:Leuchtdiode gelb 3mm 2mA :145998:Anode in i5 einlöten<br />
(c12)pad(j12)pad:1:R1 :Widerstand 2k2 Ohm :408212:einlöten<br />
(k7) 5 ypad\<br />
(l7) 5 ypad :1: :Schalter 2xUM :708216:Schlitze sägen und einlöten<br />
(c4) 8 ypad\<br />
(f4) 8 ypad :1:IC1 :IC 74HC367 :151165:einlöten<br />
-----------------------------------------------------------------------end_of_info<br />
;; esac ; } # end of method info<br />
################################## kit ###################################<br />
Lot="$Lot" # List Of Tools (to check installation)<br />
Lom="$Lom kit"; pcb.kit () { funcname=pcb.kit<br />
case $Met in<br />
help|man) echo "Usage: $funcname FILENAME"<br />
if test "$Met" = "man"; then cat
ANHANG D. PROGRAMM PCB 241<br />
pslayout $1<br />
sed -e "/^#/d" -e "/^$/d" -e "s/\\\//" $1| cut -d: -f1<br />
echo showpage<br />
;; esac ; } # end of method layout<br />
################################## mlayout ###################################<br />
Lot="$Lot" # List Of Tools (to check installation)<br />
Lom="$Lom mlayout"; pcb.mlayout () { funcname=pcb.mlayout<br />
case $Met in<br />
help|man) echo "Usage: $funcname FILENAME x y"<br />
if test "$Met" = "man"; then cat &1; then echo CANNOT FIND Program $n !; fi; done<br />
if test $Myn = $Prognam; then # basic Classname. called<br />
Programheader<br />
for n in help man deinstall $(echo $Lom); do Install $Nam.$n; done<br />
else # method Classname.Fun called<br />
if [ "$1" = "-h" -o "$1" = "--help" ]; then ${Dir}/${Nam}.help ; Quit -1; fi<br />
trap "Quit -1" SIGINT # ^C<br />
case $Fun in<br />
man)<br />
case $1 in<br />
"") echo Usage: ${Nam}.man METHODNAME;;<br />
deinstall) echo ${Nam}.$1 Unlinks all methods.;;<br />
help) echo ${Nam}.$1 Gives short help for all methods.;;<br />
man) echo ${Nam}.$1 Gives help for named method.;;<br />
*) Met=$Fun; ${Nam}.$1;;<br />
esac;;<br />
help)<br />
echo Usage: ${Nam}<br />
echo Usage: ${Nam}.deinstall<br />
echo Usage: ${Nam}.help<br />
echo Usage: ${Nam}.man METHODNAME<br />
for n in $(echo $Lom|tr " " "\n"|sort|uniq); do
ANHANG D. PROGRAMM PCB 242<br />
Met=help; ${Nam}.$n; done # calls function<br />
;;<br />
deinstall)<br />
for n in help man deinstall $(echo $Lom); do Deinstall ${Nam}.$n; done<br />
for n in ${Dir}/${Nam}*; do<br />
if [ "$n" != "${Dir}/${Nam}" ] &&\<br />
[ "$n" != "${Dir}/${Nam}.include" ]; then<br />
echo Ambiguous file $n found, please remove by hand:<br />
ls -l $n<br />
fi<br />
done;;<br />
*)<br />
for n in $Lom; do<br />
if test $n = $Fun<br />
then Met=doit; ${Nam}.$Fun "$@"; Quit 0; fi<br />
done<br />
echo $Dir/$Nam.$Fun is a unlisted method. Please remove it.<br />
Quit -1;;<br />
esac<br />
fi<br />
Quit 0
Anhang E<br />
Skalieren des Systems<br />
Abbildung E.1: Kleine Variante des Experimentiersystems<br />
243
ANHANG E. SKALIEREN DES SYSTEMS 244<br />
Die im Buch beschriebene Variante <strong>mit</strong> LCD-Display, Lochrasterfeld<br />
und Netzteil ist aufwändiger als ein für viele Experimente<br />
ausreichendes Minimum.<br />
Wird die ISP-Hardware der Centronics-Schnittstelle und ein<br />
teurerer MAX 3232 verwendet, so kann ohne zusätzliche<br />
Stromversorgung gearbeitet werden. Das System wird vom<br />
PC über die Programmierschnittstelle <strong>mit</strong>versorgt.<br />
Gegebenenfalls kann die Hardware so reduziert werden, dass<br />
für große Gruppen eine finanzielle Entlastung spürbar wird.<br />
Das in Abbildung E.1 gezeigte Experimentiersystem dürfte<br />
im Verhältnis Preis zu Leistung schwer zu unterbieten sein.<br />
Drei komplette Systeme können <strong>mit</strong> einer einseitigen Europaplatine<br />
aufgebaut werden. Die Kosten der Bauteile liegen im<br />
Bereich einer Audio-CD.<br />
Abbildung E.2: Layout des kleinen Experimentiersystems<br />
Nach der Durchführung der Experimente kann die MCU <strong>mit</strong><br />
der ISP-Software von Matthias Weisser [matwei] geladen wer-
ANHANG E. SKALIEREN DES SYSTEMS 245<br />
den. Durch dieses Programm verwandelt sich das Experimentierboard<br />
in ein Programmiergerät, das auch an der USB-<br />
Schnittstelle noch gut funktionert.<br />
Drei kleine Änderungen werden notwendig:<br />
Die Verbindung zwischen Pin1 (Reset) der MCU und der ISP-<br />
Schnittstelle wird am besten durch einen Jumper aufgetrennt.<br />
Stattdessen wird eine Brücke nach Pin16 (PB2/SS) gelegt, um<br />
einen Reset der externen MCU zu ermöglichen. Nach Setzen<br />
des BOOTRST-Flags benötigt unsere MCU einen 33 nF Kondensator<br />
zwischen Pin1 (Reset) und Masse, da<strong>mit</strong> der Boot-<br />
Loader nach dem Power-On aktiv wird.<br />
Der in der Firmware enthaltene, zum STK500 kompatible,<br />
Boot-Loader ermöglicht sogar den Verzicht auf das<br />
Programmierschnittstellen-Platinchen. Das 1 kByte große Ladeprogramm<br />
läd die Programme direkt von der seriellen<br />
Schnittstelle <strong>mit</strong> dem STK500 Protokoll in den Flash-Speicher<br />
der MCU. Allerdings muss in diesem Fall an eine externe<br />
Stromversorgung gedacht werden.
Anhang F<br />
Die Datei<br />
Mikrocontroller.tgz<br />
246
ANHANG F. DIE DATEI MIKROCONTROLLER.TGZ247<br />
autorun.bat Startdatei für Windows<br />
autorun.inf Startdatei für Windows<br />
Mikrocontroller.ico Icon für Windows<br />
index.html Startdatei für Internet-Browser<br />
Readme diese Datei<br />
hardware Verzeichnis <strong>mit</strong> Schaltplänen etc.<br />
software Verzeichnis <strong>mit</strong> Software zum Üben<br />
book Verzeichnis des Buches<br />
dokus Verzeichnis <strong>mit</strong> Datenblättern<br />
packets Verzeichnis <strong>mit</strong> Softwarepaketen<br />
bin Verzeichnis <strong>mit</strong> ausführbaren Programmen
Anhang G<br />
Rechtliches<br />
Dieses Buch <strong>mit</strong> den Beispielprogrammen ist Open Source.<br />
Es gelten sinngemäß die Bestimmungen der GPL [gnu] <strong>mit</strong><br />
folgender Einschränkung:<br />
Der Autor wünscht für das Anlegen jeder Kopie, die außerhalb<br />
seines Einflußbereiches erstellt wird, eine Spende von<br />
10,10 Euro an eine der folgenden Institutionen:<br />
• FSF — Free Software Foundation<br />
FSF Europe -Chapter Germany e.V.<br />
National-Bank Essen, BLZ 360 200 30, Konto 300 4724<br />
• Greenpeace e. V., Hamburg<br />
Postbank, BLZ 200 100 20, Konto 20 61-206<br />
248
ANHANG G. RECHTLICHES 249<br />
• UNICEF — United Nations Children’s Fund<br />
Stadtsparkasse Köln, BLZ 370 502 98, Konto 999 2959
Anhang H<br />
Helfer<br />
Ein Moment der Besinnung: Allein die Vorkehrungen für<br />
Strom aus der Steckdose sind unüberschaubar. — Daneben<br />
sind andere Hilfen natürlich besonders auffällig:<br />
Ohne Internet und Suchmaschinen wie www.google.de hätte<br />
der Autor weder die gesuchten Informationen noch Programme<br />
erhalten. Besonders hilfreich waren:<br />
• www.atmel.com — Datenblätter, Datenbücher und Applikationen<br />
zu den AVR-<strong>Mikrocontrollern</strong> gibt es direkt<br />
vom Hersteller.<br />
• www.avrfreaks.net — Ein Pool von Informationen zu<br />
den AVRs aus der Sicht der Praktiker.<br />
• www.debian.de — Hier fanden sich die aktuellen Versionen<br />
von avr-gcc, avr-binutils, avr-lib und uisp.<br />
250
ANHANG H. HELFER 251<br />
Dieses Buch wurde <strong>mit</strong> Programmen erstellt, die frei erhältlich<br />
sind. Ich möchte sie deshalb nicht unerwähnt lassen:<br />
Distribution Debian<br />
Betriebssystem Linux<br />
Shell bash<br />
Tools GNU<br />
Fenstersystem X11<br />
Editor vim<br />
Scannerprogramm sane<br />
Bildbearbeitungsprogramm gimp<br />
CAD-Programm qcad<br />
Schaltpläne electric<br />
Textsatzsystem pdfL ATEX<br />
Postscript-Emulation Ghostscript<br />
Auf dem Weg vom Manuskript zum Buch braucht man Lektoren.<br />
Der Mühe des Korrekturlesens haben sich unterzogen:<br />
• Frau Ruth Unger<br />
• Frau Helga Bruns<br />
• Herr Andreas Mull<br />
Einen herzlichen Dank an die Helfer.
Abbildungsverzeichnis<br />
2.1 Direkter Nachfahre des Abakus. . . . . . . . . 23<br />
4.1 DB9-Stecker des IBM-AT . . . . . . . . . . . 35<br />
8.1 Gute und schlechte Lötverbindungen. . . . . . 70<br />
8.2 Schaltung einer Spannungsmessung. . . . . . 73<br />
8.3 Schaltung einer Strommessung. . . . . . . . . 74<br />
8.4 Schaltung einer Widerstandsmessung. . . . . 75<br />
9.1 Stecker . . . . . . . . . . . . . . . . . . . . . . 78<br />
9.2 Amerikanisches und europäisches Widerstandssymbol<br />
. . . . . . . . . . . . . . . . . . . . . . 80<br />
9.3 Widerstände . . . . . . . . . . . . . . . . . . . 81<br />
9.4 Kondensator und Elektrolytkondensator . . . 83<br />
252
ABBILDUNGSVERZEICHNIS 253<br />
9.5 Kondensatoren . . . . . . . . . . . . . . . . . 84<br />
9.6 Schaltsymbol für einen Quarz . . . . . . . . . 85<br />
9.7 Quarze . . . . . . . . . . . . . . . . . . . . . . 86<br />
9.8 Schaltsymbole verschiedener Dioden . . . . . . 87<br />
9.9 Dioden . . . . . . . . . . . . . . . . . . . . . . 88<br />
9.10 Transistoren . . . . . . . . . . . . . . . . . . . 89<br />
9.11 Transistoren . . . . . . . . . . . . . . . . . . . 90<br />
9.12 Integrierte Schaltungen . . . . . . . . . . . . . 91<br />
10.1 Ätzmaske für 15 Platinen. . . . . . . . . . . . 101<br />
11.1 IC SN7400 <strong>mit</strong> 4 NAND-Gattern . . . . . . . 113<br />
11.2 Prellfreie Taste . . . . . . . . . . . . . . . . . 115<br />
12.1 KIM-1 Mikrocomputer der Firma MOS aus<br />
dem Jahr 1975. . . . . . . . . . . . . . . . . . 120<br />
12.2 Architektur des ATmega8 . . . . . . . . . . . 127<br />
13.1 Schaltplan der Centronics Variante des ISP-<br />
Interface . . . . . . . . . . . . . . . . . . . . . 133<br />
13.2 Layout der Centronics Variante des ISP-Interface134<br />
13.3 ISP-Interface in der Centronics Variante. . . . 135
ABBILDUNGSVERZEICHNIS 254<br />
13.4 Schaltplan der RS232 Variante des ISP-Interface137<br />
13.5 Layout der RS232 Variante des ISP-Interface . 138<br />
13.6 ISP-Interface in der RS232 Variante. . . . . . 138<br />
13.7 Schaltplan der USB Variante des ISP-Interface 140<br />
13.8 Layout der USB Variante des ISP-Interface . . 142<br />
13.9 ISP-Interface in der USB Variante. . . . . . . 143<br />
13.10Schaltplan der ersten sechs Baustufen . . . . . 147<br />
13.11Layout der Hauptplatine . . . . . . . . . . . . 148<br />
13.12Erste Baustufe . . . . . . . . . . . . . . . . . 154<br />
13.13Schnell blinkende Leuchtdiode . . . . . . . . . 159<br />
13.14Adapter . . . . . . . . . . . . . . . . . . . . . 171<br />
E.1 Kleine Variante des Experimentiersystems . . 243<br />
E.2 Layout des kleinen Experimentiersystems . . . 244
Literaturverzeichnis<br />
[Formeln] Bartsch, Hans-Jochen:<br />
Mathematische Formeln<br />
(1977, VEB Fachbuchverlag Leipzig)<br />
[Kernighan] Brian W. Kernighan/Dennis M. Ritchie:<br />
Programmieren in C.<br />
(1990, Carl Hanser Verlag, München Wien)<br />
[C] Kernighan/Ritchie:<br />
The C Programming Language.<br />
(1978, Printice-Hall Inc. Englewood Cliffs,<br />
New Jersey)<br />
[C++] Stroustrup, Bjarne:<br />
The C++ Programming Language.<br />
(1987, Addison-Wesley Publishing Company)<br />
[Linux] Hetze, Hohndel, Müller, Kirch:<br />
Linux Anwenderhandbuch<br />
(1993..., LunetIX Softfair)<br />
255
LITERATURVERZEICHNIS 256<br />
[Torvalds] Linus Torvalds und David Diamond:<br />
Just for Fun.<br />
(2002, DTV Deutscher Taschenbuch Verlag)<br />
[Elektor] Michael Möge:<br />
Tipps zur Platinenherstellung<br />
Elektor 2002-09p36<br />
[adobe] http://www.adobe.com<br />
Homepage der Postscript-Entwickler.<br />
[atmel] http://www.atmel.com<br />
Homepage des IC-Herstellers.<br />
[avrdude] http://www.savannah.nongnu.org/projects/avrdude<br />
CVS-Verzeichnis eines Programmes zur<br />
In-System-Programmierung von AVR-<br />
<strong>Mikrocontrollern</strong> unter Linux<br />
[debian] http://www.debian.de<br />
Debian ist eine umfassende freie GNU/Linux<br />
Distribution.<br />
[fischl] http://www.fischl.de<br />
Homepage eines ISP für den USB, der usbasp<br />
genannt wird.<br />
[gnu] http://www.gnu.org/licences<br />
GNU General Public Licence.
LITERATURVERZEICHNIS 257<br />
[knoppix] http://www.knoppix.de<br />
Debian basiertes Linux, läuft ohne Installation.<br />
[obdev] http://www.obdev.at<br />
Entwickeln USB-Lösungen <strong>mit</strong> <strong>Mikrocontrollern</strong>.<br />
[unger] http://www.hanns-konrad.de<br />
Homepage des Autors.<br />
[usb] http://www.usb.org<br />
Die Homepage des Universal Serial Bus.<br />
[matwei] http://www.matwei.de<br />
Homepage eines ISP für den USB, der usbisp<br />
genannt wird.<br />
[winavr] http://winavr.sourceforge.net<br />
Frei Entwicklungssoftware für AVRs.<br />
[wikipedia] http://de.wikipedia.org<br />
Eine Enzyklopädie im Internet, die Begriffe<br />
aus der <strong>Computertechnik</strong> gut abdeckt. Sie ist<br />
in verschiedenen Sprachen verfügbar.