Hallo an alle Neueinsteiger,
da es einigen Leuten sicherlich nicht leicht fällt, ihre ersten Code-Zeilen für
einen Microcontroller zu schreiben und die dann auch noch auf den
Controller zu übertragen, werde ich einfach mal ein paar Hilfen geben.
===== Die Entwicklungsumgebung für welche die nicht viel ausgeben wollen =====
Was benötigen wir dafür ...
1. Einen PC mit Parallelport (kann also noch ein älteres Exemplar sein)
2. Einen Parallelport-Programmer (siehe http://s-huehn.de/elektronik/avr-prog/avr-prog.htm )
Den mit den 2 Widerständen habe ich auch am Anfang benutzt. Läuft gut.
Die Teile findet man in der Bastlerkiste (altes PC-Kabel und Widerstände)
3. Software ...
- AVR-Studio (gibts bei ATMEL auf der Seite : http://www.atmel.com/ )
- Pony-Prog (gibt es hier : http://www.lancos.com/prog.html )
4. Einen Microcontroller natürlich Ein ATmega8-16 ist dafür gut geeignet (ca 1,25eur)
Er ist günstig, überschaubar und mit 16MHz schnell genug für alles mögliche.
5. Ein Steckbrett wie z.B. das auf der Seite von s-huehn weiter unten. Oder auch
etwas größer ... (Das Bild ist mein Steckbrett)
So ein Teil kann man später auch sehr gut für Experimente verwenden. Also
kein rausgeschmissenes Geld (zwischen 5,- und 10,-eur)
6. Ein paar Bauteile aus der Bastelkiste, wie z.B. ...
- ein paar LEDs (Low-Current wären gut, es reichen aber auch andere)
- ein paar Vorwiderstände für die LEDs (so zwischen 820 Ohm und 2,2k Ohm)
- Ein paar alte Taster und Schalter für die Eingänge
- noch ein paar Keramik-Kondensatoren (1 oder mehrere 100nF für die Siebung der Betriebsspannung)
- Wenn man einen anderen Takt möchete ein Quarz und 2 Keramik-Kondensatoren mit 22pF. (Es geht aber auch mit internem Takt)
Es muß also nicht teuer sein, um mit einem Microcontroller etwas zu machen.
===== Und weiter gehts =====
Das erste Programm ...
Ich habe damals mit dem LED-Blinker auf der Seite von S-Huehn angefangen.
Aber mir waren einige Sachen darin doch etwas unklar. Also fangen wir unten an
Ich nehme mal an, die beiden Programme (AVR-Studio und Pony-Prog) sind installiert.
1. Wir bauen eine Programm-Grundstruktur ...
CodeBox ASM
Was sagt uns das nun alles ?
Die Zeile 1 ist eine Assembler-Direktive. Die sagt dem Assembler, er soll die Datei
mit dem Namen "m8def.inc" zu unserem selbstgeschriebenen Programmcode
dazuladen. In dieser Datei sind Definitionen für den ATmega8 enthalten.
In der Zeile 2 teilen wir dem Assembler den Anfang con einem Codesegment mit.
Ab hier beginnt Programm-Code (Auch eine Assembler-Direktive).
Und in der 3. Zeile teilen wir dem Assembler die Anfangsadresse mit, ab der er den
folgenden Programmcode im Speicher des Controllers unterbringen soll. Das ist hier
die erste Adresse des Flash.
Zeile 5 ist ein Label. Diese benannten Punkte kann man vielfältig verwenden.
Entweder als Ziele für Sprünge, als Markierungen für Daten-Tabellen, ...
Der Assembler merkt sich unter diesem Namen die Adresse des Controller-Speichers.
In unserem Fall ist das ein Sprungziel.
In Zeile 7 ist dann ein Sprungbefehl für den Controller. Er soll zur Adresse "mainloop:"
springen.
Wir haben also eine Endlosschleife programmiert die Strom verbraucht
===== Wir bringen was zum leuchten =====
Für die nächsten Experimente bietet sich der Port D an, da er alle 8 Bit an
Anschlüsse führt.
Wir schließen also einfach mal an die Pins PD0 bis PD7 Leuchtdioden mit
Vorwiderständen an und verbinden die Anoden mit +5V.
Also z.B. PD0---1,5k---|<|---- +5V
Nun der Code ...
CodeBox ASM
Und wieder die Erklärung ...
In Zeile 5 wird das Register 16 (haben wir jetzt mal einfach verwendet) mit dem
Wert 11111111 (Binär) geladen (also 255 dez oder FF hex).
In Zeile 6 wird das I/O-Register DDRD (DataDirectionRegisterD) damit geladen.
Mit einem 1 Bit wird der jeweilige Pin des Ports auf Ausgang geschaltet.
In Zeile 8 löschen wir das Register 16 (also auf 00000000 bin oder 0 dez oder 00 hex)
Und die Zeile 9 schreibt diesen Wert dann in das Ausgangsregister des Port D.
Damit gehen alle Pins des PortD auf Low und die LEDs leuchten, da sie mit ihrem
anderen Anschluß auf +5V liegen.
Es werde Licht
===== Es soll aber blinken =====
Also lassen wir es blinken
Zählen wir doch einfach mal. Dann blinken alle Bits mit verscheidener Geschwindigkeit.
CodeBox ASM
Die Änderungen ...
Die Zeile mit "out portd,r16" ist in die Schleife auf Zeile 12 gewandert.
Man will ja immer den aktuellen Wert des Registers ausgeben und nicht
nur einmal was auf den Port schreiben.
In der Zeile 13 wird das Register 16 jetzt incrementiert (also +1).
Mit jedem Durchlauf wird das Register also um eins hochgezählt.
Das sieht dann so aus ...
0, 1, 2, ... , 254, 255, 0, 1, 2, 3, 4, 5, 6, ... , 253, 254, 255, 0, 1, 2, .....
Das Register läuft also bei 255 über und fängt wieder bei 0 an.
Wir haben allerdings ein Problem. Die LEDs blinken doch sehr schnell.
- out benötigt 1 Takt-Zyklus
- inc auch
- rjmp benötigt 2 Taktzyklen
Das sind dann 4 Taktzyklen für einen Schleifendurchlauf.
Bei 1MHz Prozessortakt ist ein Taktzyklus logischerweise
1/1MHz = 1us
1MHz ist der interne Takt des Mega8 wenn man nicht an den Fuses rumdreht.
Das Register wird also alle 4us um eins erhöht und dann ausgegeben.
256*4us = 1024us = 1,024ms
Damit wird also auf PD7 eine Blinkfrequenz von
1/1,024ms = 977Hz erreicht. Das blinkt aber sehr schnell
Die Auflösung des Problems kommt im nächsten Text ... (to be continued)
da es einigen Leuten sicherlich nicht leicht fällt, ihre ersten Code-Zeilen für
einen Microcontroller zu schreiben und die dann auch noch auf den
Controller zu übertragen, werde ich einfach mal ein paar Hilfen geben.
===== Die Entwicklungsumgebung für welche die nicht viel ausgeben wollen =====
Was benötigen wir dafür ...
1. Einen PC mit Parallelport (kann also noch ein älteres Exemplar sein)
2. Einen Parallelport-Programmer (siehe http://s-huehn.de/elektronik/avr-prog/avr-prog.htm )
Den mit den 2 Widerständen habe ich auch am Anfang benutzt. Läuft gut.
Die Teile findet man in der Bastlerkiste (altes PC-Kabel und Widerstände)
3. Software ...
- AVR-Studio (gibts bei ATMEL auf der Seite : http://www.atmel.com/ )
- Pony-Prog (gibt es hier : http://www.lancos.com/prog.html )
4. Einen Microcontroller natürlich Ein ATmega8-16 ist dafür gut geeignet (ca 1,25eur)
Er ist günstig, überschaubar und mit 16MHz schnell genug für alles mögliche.
5. Ein Steckbrett wie z.B. das auf der Seite von s-huehn weiter unten. Oder auch
etwas größer ... (Das Bild ist mein Steckbrett)
So ein Teil kann man später auch sehr gut für Experimente verwenden. Also
kein rausgeschmissenes Geld (zwischen 5,- und 10,-eur)
6. Ein paar Bauteile aus der Bastelkiste, wie z.B. ...
- ein paar LEDs (Low-Current wären gut, es reichen aber auch andere)
- ein paar Vorwiderstände für die LEDs (so zwischen 820 Ohm und 2,2k Ohm)
- Ein paar alte Taster und Schalter für die Eingänge
- noch ein paar Keramik-Kondensatoren (1 oder mehrere 100nF für die Siebung der Betriebsspannung)
- Wenn man einen anderen Takt möchete ein Quarz und 2 Keramik-Kondensatoren mit 22pF. (Es geht aber auch mit internem Takt)
Es muß also nicht teuer sein, um mit einem Microcontroller etwas zu machen.
===== Und weiter gehts =====
Das erste Programm ...
Ich habe damals mit dem LED-Blinker auf der Seite von S-Huehn angefangen.
Aber mir waren einige Sachen darin doch etwas unklar. Also fangen wir unten an
Ich nehme mal an, die beiden Programme (AVR-Studio und Pony-Prog) sind installiert.
1. Wir bauen eine Programm-Grundstruktur ...
CodeBox ASM
.include "m8def.inc" ;Definitionsdatei fuer den ATmega8 dazuladen
.cseg ;Beginn eines Code-Segmentes
.org 0 ;Startadresse=0x0000 (Anfang des Flash)
mainloop: ;Ein Sprunglabel
rjmp mainloop ;Schleife neu beginnen (Eine Endlosschleife)
Was sagt uns das nun alles ?
Die Zeile 1 ist eine Assembler-Direktive. Die sagt dem Assembler, er soll die Datei
mit dem Namen "m8def.inc" zu unserem selbstgeschriebenen Programmcode
dazuladen. In dieser Datei sind Definitionen für den ATmega8 enthalten.
In der Zeile 2 teilen wir dem Assembler den Anfang con einem Codesegment mit.
Ab hier beginnt Programm-Code (Auch eine Assembler-Direktive).
Und in der 3. Zeile teilen wir dem Assembler die Anfangsadresse mit, ab der er den
folgenden Programmcode im Speicher des Controllers unterbringen soll. Das ist hier
die erste Adresse des Flash.
Zeile 5 ist ein Label. Diese benannten Punkte kann man vielfältig verwenden.
Entweder als Ziele für Sprünge, als Markierungen für Daten-Tabellen, ...
Der Assembler merkt sich unter diesem Namen die Adresse des Controller-Speichers.
In unserem Fall ist das ein Sprungziel.
In Zeile 7 ist dann ein Sprungbefehl für den Controller. Er soll zur Adresse "mainloop:"
springen.
Wir haben also eine Endlosschleife programmiert die Strom verbraucht
===== Wir bringen was zum leuchten =====
Für die nächsten Experimente bietet sich der Port D an, da er alle 8 Bit an
Anschlüsse führt.
Wir schließen also einfach mal an die Pins PD0 bis PD7 Leuchtdioden mit
Vorwiderständen an und verbinden die Anoden mit +5V.
Also z.B. PD0---1,5k---|<|---- +5V
Nun der Code ...
CodeBox ASM
.include "m8def.inc" ;Definitionsdatei fuer den ATmega8 dazuladen
.cseg ;Beginn eines Code-Segmentes
.org 0 ;Startadresse=0x0000 (Anfang des Flash)
ldi r16,0b11111111 ;PortD alle Bits auf Ausgang
out ddrd,r16 ;setzen
clr r16 ;Anfangswert setzen (alles Low)
out portd,r16 ;Daten an PortD ausgeben
mainloop: ;Ein Sprunglabel
rjmp mainloop ;Schleife neu beginnen (Eine Endlosschleife)
Und wieder die Erklärung ...
In Zeile 5 wird das Register 16 (haben wir jetzt mal einfach verwendet) mit dem
Wert 11111111 (Binär) geladen (also 255 dez oder FF hex).
In Zeile 6 wird das I/O-Register DDRD (DataDirectionRegisterD) damit geladen.
Mit einem 1 Bit wird der jeweilige Pin des Ports auf Ausgang geschaltet.
In Zeile 8 löschen wir das Register 16 (also auf 00000000 bin oder 0 dez oder 00 hex)
Und die Zeile 9 schreibt diesen Wert dann in das Ausgangsregister des Port D.
Damit gehen alle Pins des PortD auf Low und die LEDs leuchten, da sie mit ihrem
anderen Anschluß auf +5V liegen.
Es werde Licht
===== Es soll aber blinken =====
Also lassen wir es blinken
Zählen wir doch einfach mal. Dann blinken alle Bits mit verscheidener Geschwindigkeit.
CodeBox ASM
.include "m8def.inc" ;Definitionsdatei fuer den ATmega8 dazuladen
.cseg ;Beginn eines Code-Segmentes
.org 0 ;Startadresse=0x0000 (Anfang des Flash)
ldi r16,0b11111111 ;PortD alle Bits auf Ausgang
out ddrd,r16 ;setzen
clr r16 ;Anfangswert setzen (alles Low)
mainloop: ;Ein Sprunglabel
out portd,r16 ;Daten an PortD ausgeben
inc r16 ;Datenwert erhoehen
; === hier kommen die naechsten Teile rein
rjmp mainloop ;Schleife neu beginnen (Eine Endlosschleife)
Die Änderungen ...
Die Zeile mit "out portd,r16" ist in die Schleife auf Zeile 12 gewandert.
Man will ja immer den aktuellen Wert des Registers ausgeben und nicht
nur einmal was auf den Port schreiben.
In der Zeile 13 wird das Register 16 jetzt incrementiert (also +1).
Mit jedem Durchlauf wird das Register also um eins hochgezählt.
Das sieht dann so aus ...
0, 1, 2, ... , 254, 255, 0, 1, 2, 3, 4, 5, 6, ... , 253, 254, 255, 0, 1, 2, .....
Das Register läuft also bei 255 über und fängt wieder bei 0 an.
Wir haben allerdings ein Problem. Die LEDs blinken doch sehr schnell.
- out benötigt 1 Takt-Zyklus
- inc auch
- rjmp benötigt 2 Taktzyklen
Das sind dann 4 Taktzyklen für einen Schleifendurchlauf.
Bei 1MHz Prozessortakt ist ein Taktzyklus logischerweise
1/1MHz = 1us
1MHz ist der interne Takt des Mega8 wenn man nicht an den Fuses rumdreht.
Das Register wird also alle 4us um eins erhöht und dann ausgegeben.
256*4us = 1024us = 1,024ms
Damit wird also auf PD7 eine Blinkfrequenz von
1/1,024ms = 977Hz erreicht. Das blinkt aber sehr schnell
Die Auflösung des Problems kommt im nächsten Text ... (to be continued)