Inhalt
Unsere Entwicklungsumgebung |
Als Prozessor haben wir uns zunächst auf den ATtiny13 von ATMEL (R) festgelegt. Er ist klein, preiswert und hat 5 Port-Pins plus Reset. Die Ports können als Ausgang 20 mA bei <1 V Spannungsabfall treiben. Einige sind als A/D-Wandler einsetzbar, andere als PWM-Ausgänge nutzbar (PWM = puls-weiten-moduliert) und alle können Interrupts auslösen. Damit ist eine große Anwendungsbreite sichergestellt. |
Die Idee zu dieser Schaltung haben wir dem
Franzis (R) Lernpaket Mikrocontroller von
Burkhard Kainka zu verdanken.
Es enthält - neben vielen Anregungen und Programmbeispielen -
auch die zu dieser Schaltungskonfiguration passende einfach zu bedienende
Programmiersoftware. Eine
überarbeitete Version
der mit dem Lernpaket vertriebenen Software bietet der Autor als ZIP-Archiv
auf seine Homepage zum Download an. Wir benötigen aus dem ZIP-Archiv nur das
Programm LPmikroISP.exe und das File LPmikro.ini, in dem sich das
Programm die verwendete COM-Schnittstelle merkt. Für die Genehmigung zur Verwendung
des Programms in unserer Arbeitsgruppe danke ich Burkhard Kainka, DK6JD herzlich.
Wer sich mit den anderen Freien Programmierprogrammen befassen will, findet im
Artikel
Programmieren mit AVRDUDE von Ralf Beesner (im elo-web des Franzis Verlages)
wertvolle Hinweise. Diese Programme erlauben auch die Umprogrammierung aller "Fuses"
des ATtiny13, was bei Unkenntnis bewirken
kann, dass ein ATtiny13 nicht mehr ansprechbar ist. Bei DK6JD's LPmikroISP.exe
ist das ausgeschlossen - ein wichtiges Feature in den Händen der
experimentierfreudigen Kids!
Die Stromversorgung der Platine erfolgt bei beiden Methoden zur In-Circuit-Programmierung während der Programmierung aus der seriellen Schnittstelle des PC (oder Notebook). Falls die Versorgung "schwächelt", kann die LED mit der Steckbrücke abgeschaltet werden. Beide Methoden benötigen den ungestörten Zugang zu den Portanschlüssen PB0, PB1, PB2 und dem Reset-Pin.
Damit die Portanschlüsse PB0, PB1 und PB2 nach der Programmierung für die jeweilige Applikation verfügbar sind, sind sie mit drei DIL-Umschaltern zwischen der seriellen Schnittstelle (Programmiermodus) und dem Anschluss der Applikationsplatine umschaltbar. Mit einem weiteren Schalter (S1.1/2) lässt sich der RESET-Pin entweder mit Masse (Programmiermodus) oder mit dem RESET-Pin der zweiten IC-Fassung (St2) verbinden. Da dieser Anschluss die gleiche Belegung wie der ATtiny13 hat, genügt zur Verbindung mit dem ATtiny13-IC-Sockel auf der zu entwickelnden Schaltung eine einfache 8-polige Flachbandverbindung mit 8-poligen IC-Steckern.
Nach beendeter Arbeit muss der programmierte ATtiny13 nur noch in die "Zielhardware" gesteckt werden, die dann mit eigener Stromversorgung den staunenden Freunden vorgeführt werden kann.
Wenn statt des 4-poligen Umschalters ein besser beschaffbarer 8-poliger DIL-Schalter eingesetzt wird, müssen immer zwei Umschalter wechselweise betätigt werden. Im Programmiermodus stehen die Schalter mit den geraden Nummern 'links' (also auf 'on') und die anderen 'rechts' (off); im Betrieb ist es umgekehrt. Die Zuordnung der Schalter zu den Port-Pins ist wie folgt: Reset: S1+2, PB2: S3+4, PB1 S5+6, PB0 S7+8.
Zur Entwicklung der Programme verwenden wir das von ATMEL (www.atmel.com) kostenfrei erhältliche AVR Studio 4 in der Version 4.12. Es enthält außer dem AVR Assembler (Version 2) auch einen Debugger und eine ausführliche Hilfe, die auch alle Assembler-Befehle genau beschreibt. Leider ist alles in englischer Sprache, was für die jüngeren Kids problematisch ist. Deshalb sind alle Assembler-Befehle, die wir bisher benutzt haben, im folgenden Abschnitt möglichst einfach auf deutsch beschrieben.
Für diejenigen, die lieber im englischen Original des pdf-Datenblattes nachsehen, habe ich die Bedeutung der verwendeten Abkürzungen auf einem Blatt Infos zu ATtiny13-Befehlen zusammen gefasst. Und wer sich noch nie mit einem Assemblerprogramm befasst hat, wird in der Abhandlung über die Anleitung zur Struktur eines Progrmmes sicher Anregungen finden.
Befehl | Beispiel | Erläuterungen |
ldi Register,Wert | Lädt eine 8-bit-Zahl (Wert) ins Register. Als Register kommen nur r16 mit r31 in Frage! | |
mov Register1,Register2 | mov r00,r19 | kopiert den Inhalt von Register2 ins Register1. Der Inhalt von Register2 bleibt unverändert. |
out ddrb,r18 | kopiert den Inhalt von Register2 ins
I/O-Register. Der Inhalt von Register2 bleibt unverändert. I/O-Register sind z. B. PORTB, DDRB und gelegentlich auch PINB | |
dec Register | dec r17 | Verringert den Inhalt von Register um 1 und setzt Flags. Ist der Inhalt vor der Operation Null, wird daraus 255 (=-1) |
inc Register | inc r07 | Erhöht den Inhalt von Register um 1 und setzt Flags. Ist der Inhalt vor der Operation 255, wird daraus Null und das Carry-Flag wird gesetzt (Überlauf) |
rjmp Label | rjmp Weg2 | Verzweigt zu der mit Label: bezeichneten Stelle im Programm |
rcall Label | rcall Warten | Ruft das mit Label: bezeichnete Unterprogramm auf,
das mit dem Befehl ret enden muss. Danach wird das Programm mit dem auf rcall folgenden Befehl fortgesetzt. |
breq Label | breq Geschafft | Verzweigt (br=Branch=engl. Zweig, Ast) zu der mit Label:
bezeichneten Stelle im Programm, wenn die Bedingung "equal"
aus der letzten arithmetischen Operation (z. B. dec) erfüllt
ist, das Ergebnis also "Null" war. Der engl. Begriff "equal" rührt daher, dass bei vielen Vergleichen zwischen den Inhalten zweier Register eine Subtraktion ausgeführt wird. Und wenn beide gleich sind, ist das Ergebnis der Subtraktion Null. |
brne Label | brne Zurueck | Verzweigt (br=Branch=engl. Zweig, Ast) zu der mit Label: bezeichneten Stelle im Programm, wenn die Bedingung "not equal" aus der letzten arithmetischen Operation (z. B. dec) erfüllt ist, das Ergebnis also "nicht Null" war. |
brpl Label | brpl Positiv | Verzweigt (br=Branch=engl. Zweig, Ast) zu der mit Label: bezeichneten Stelle im Programm, wenn die Bedingung "plus" aus der letzten arithmetischen Operation (z. B. dec) erfüllt ist, das Ergebnis also "positiv (einschliesslich Null)" war. Alle Werte zwischen 0 und 127 (0x7f bzw. 0b01111111) sind positiv. |
brmi Label | brmi Negativ | Verzweigt (br=Branch=engl. Zweig, Ast) zu der mit Label: bezeichneten Stelle im Programm, wenn die Bedingung "negativ" aus der letzten arithmetischen Operation (z. B. dec) erfüllt ist, das Ergebnis also "negativ" war. In der Zweier-Komplementdarstellung sind das alle Werte, bei denen das MSB (Most significant bit, also bit 7) eine 1 hat. In der binären Darstellung also zwischen 0b10000000 (=-128) und 0b11111111 (=-1). |
sbic IOreg,Pin | sbic pinb,1 | Skip if Bit in I/O-register is Cleared: Liest den Pegel am Pin 1 (0..7) des I/O-Registers, hier das Input-Register von Port B (PINB) und prüft, ob das Bit "clear" (gelöscht bzw. "low") ist und überspringt den nächsten Befehl, wenn die Bedingung erfüllt ist. |
sbis IOreg,Pin | sbis pinb,0 | Skip if Bit in I/O-register is Set: Liest den Pegel am Pin 0 (0..7) des I/O-Registers, hier das Input-Register von Port B (PINB) und prüft, ob das Bit "set" (gesetzt bzw. "high") ist und überspringt den nächsten Befehl, wenn die Bedingung erfüllt ist. |
st Rd, [-]X|Y|Z[+] | ld r10, Y+ | STore (speichere) ein Byte ins Datensegment an der Stelle X, Y oder Z. Die Register r0..r31 sind erlaubt, allerdings ohne r26:r27 (=X), r28:r29 (=Y) bzw. r30:r31 (=Z) Folgt auf X, Y oder Z ein +, so wird das Indexregister nach dem Schreiben incrementiert. Steht vor dem Indexregister ein -, so wird es zuerst decrementiert und dann der Inhalt von Rd in die Stelle geschrieben, auf die es dann zeigt. |
sts Rd, k | lpm r18, $0123 | STore (speichere) ein Byte ins DatenSegment an der Stelle, auf die die Konstante k zeigt. |
ld Rd, [-]X|Y|Z[+] | ld r10, Y+ | Lade ein Byte aus dem Datensegment an der Stelle X, Y oder Z. Die Register r0..r31 sind erlaubt, allerdings ohne r26:r27 (=X), r28:r29 (=Y) bzw. r30:r31 (=Z) Folgt auf X, Y oder Z ein +, so wird das Indexregister nach dem Lesen incrementiert. Steht vor dem Indexregister ein -, so wird es zuerst decrementiert und dann der Inhalt gelesen, auf den es dann zeigt. |
lds Rd, k | lpm r18, $0123 | Lade ein Byte aus dem DatenSegment von der Stelle, auf die die Konstante k zeigt. |
lpm Rd, Z[+] | lpm r07, Z+ | Lade ein Byte aus dem ProgramMemory an der Stelle Z. Die Register = r0..r29 sind erlaubt, denn r30:r31 bilden ja das Z-Register. Folgt auf Z das +, so wird Z nach dem lesen es Bytes incrementiert. |
Der elektronische Würfel verwendet den ATtiny13, der 5 Portanschlüsse
und einen Reset-Pin besitzt. 3 Anschlüsse (PB2, PB3 und PB4)
steuern die 7 LEDs des Würfels, einer liefert die Tonsignale (PB0) und an
einem (PB1) hängt der Taster, der sowohl zum Einschalten der Baugruppe als
auch zum Würfeln dient. Den Ein/Aus-Schalter haben wir uns zu
Gunsten einer automatischen Abschaltung der Betriebsspannung gespart.
Da wir eine ausreichende Menge des p-Kanal-Enhancement-IG-FET BSS92 hatten,
der BS250 aber besser am Markt verfügbar ist, wurden beide Typen im Layout
vorgesehen. Die Zeitkonstante R7*C3 bestimmt die Zeit bis zur Abschaltung der
Betriebsspannung (ca. 2 Minuten). Eine 9-Volt-Alkali-Mangan-Batterie (Typ 6LR61)
versorgt die Schaltung für viele Stunden mit Strom. Bild links: Die bestückte Würfelbaugruppe mit Anschlusskabel zur Stromversorgung und das 8-polige Verbindungskabel zur Entwicklungsplatine. |
Mit Ausnahme der zentralen LED, die bei 1, 3 und 5 leuchtet, sind immer zwei
LEDs in Serie geschaltet. Die ersten beiden "Diagonal-LEDs" werden für die
Würfe 2 mit 6, die anderen beiden "Diagonal-LEDs" für 4 mit 6 und die
restlichen beiden nur bei der 6 benötigt. Die zuletzt genannten beiden LEDs
teilen sich einen Port-Pin mit der Einzel-LED, da immer nur entweder die
Einzel-LED oder bei der 6 die zwei LEDs leuchten. Schaltungstechnisch liegen
die beiden LEDs (wie auch die Diagonal-LEDs) über 100 Ohm gegen VCC und die
Einzel-LED über 120 Ohm und zwei normale Dioden gegen GND. Da die Summe der
Durchlassspannungen aller Dioden deutlich über 5 Volt liegt, leuchten sie
nicht, wenn der Port-Pin hochohmig ist, er also zum Eingang erklärt wird. Dieser Trick wird auch bei der Tonerzeugung am Pin PB0 angewendet, um die dritte Oberwelle zu minimieren und den Ein- und Ausschaltklick zu vermeiden. Der Pin ist also im Ruhezustand ein Eingang und die kalte Seite des Schallwandlers liegt auf halber Betriebsspannung. Dazu wird statt eines "dicken" Elkos und eines Spannungsteilers ein Gegentakt-Emitterfolger eingesetzt, der nur Strom zieht, wenn der Pin PB0 auf VCC oder GND liegt, was jeweils nur für 1/3 der Periode einer Schwingung der Fall ist. Dazwischen ist der Pin jeweils für 1/6 der Periode hochohmig. |
Die beiden Oszillogramme zeigen den Spannungsverlauf zwischen den Anschlüssen
des Schallwandlers ohne (links) und mit parallel geschaltetem 1uF-Kondensator
(rechts).
Ohne den Kondensator fangen die beiden Überspannungsschutzdioden D14 und D15
die Rückschlagströme bei +5,7 und -0,7 Volt ab. Die vorhandenen
Oberwellen sind deutlich hörbar. Mit Kondensator ist der Spannungsverlauf
einem Sinus schon recht ähnlich. |
Die erste Aufgabe
beschäftigt sich mit dem Schreiben und Lesen der
Port-Pins von PortB (dem einzigen Port, den der ATtiny13 hat). Lest Euch die
Aufgabe geau durch und druckt das File "aufgabe1.pdf" dazu am besten aus.
Lösungsvorschläge findet Ihr (mit vielen Kommentaren) im Dokument
aufgabe1-code.pdf, das Ihr Euch auch
ausdrucken könnt, wenn Ihr gar nicht weiter kommt - oder auch für
später zum Spicken, wenn wieder so etwas ähnliches gebraucht wird.
Viel Erfolg - oder wie die Funkamateure sagen: vy 55
Zurück zum Seitenanfang
Zurück/weiter zur Eingangsseite von DH2MIC
Zurück/weiter zur Eingangsseite des OV C01