Fortsetzung:
Was passiert hier?
Zuerst sagen wir dem Compiler, dass wir den ATMega8(A) benutzen werden:
$regfile = "m8adef.dat"
Wer einen Atmega8 einsetzt, schreibt statt m8adef.dat m8def.dat
Die "alive"-LED: Dies ist ein sehr beliebtes Prinzip bei der Programm- und Schaltungsentwicklung, um zu testen, ob ein Programm noch läuft, ob
Unterprogramme auch angesprungen werden oder, oder, oder..
Das ist für dieses kurze Programm sicherlich übertrieben; dennoch wollten wir sie hier vorstellen. Wir definieren sie in den Zeilen 24 und 35:
Config Portb.1 = Output
Alive Alias Portb.1
und schalten sie in Zeile 43, also vor dem eigentlichen Programm, ein:
Alive = 1
Im Hauptprogramm schalten wir sie in Zeile 80 mit
Toggle Alive
um. Das bedeutet, war die Led vorher an, wird sie ausgeschaltet und umgekehrt. Wie ein Lichtschalter.
Im laufenden Programm wird die "alive"-LED also bei jedem Durchlauf der Hauptschleife umgeschaltet und blinkt damit regelmäßig.
Das Wichtige in diesem Programm ist die Nutzung des ADCs. Dazu sagen wir dem Compiler in Zeile 37 mit
Config Adc = Single , Prescaler = Auto , Reference = Avcc
dass wir den ADC mit der Referenzspannung = AVcc (= +5 V) nutzen wollen.
Das tun wir in erstmals in Zeile 59. Mit
Adcval = Getadc(0)
fordern wir den ADC-Wert von Kanal 0 (= Pin 23 -> Schleifer des Potis) an und schreiben ihn in die Variable Adcval.
Um nicht dauernd via Cls und das nachfolgende Neubeschreiben das Display flimmern zu lassen, ändern wir nur die Anzeigeelemente, die sich verändert haben.
Deshalb schreiben wir nach dem Begrüßungstext und anschließendem Cls in Zeile 53:
Lcd "ADC-Wert = " ; Adcval
Da beim Start des Programms oder einem Reset alle Variablen = 0 sind, steht dann in Zeile 1 des LDC
"ADC-Wert = 0"
So geben wir in Zeilen 63 und 64 an Position 1,
11 den aktuellen ADC-Wert aus, gefolgt von drei Leerzeichen:
Locate 1 , 11
Lcd Adcval ; Spc(3)
Der SPC(x)-Befehl gibt x Leerzeichen aus. Praktisch.
Damit bleibt "
ADC-Wert= " stehen und wir überschreiben den Rest der bisherigen Zeichen. Um sicherzugehen, dass da nicht noch ein Rest der maximal vierstelligen
Zahl steht, hängen wir einfach an die aktuelle Ausgabe, die ja mindestens ein Zeichen lang ist, drei Leerzeichen an.
Mit einem alten angezeigten Wert 1023 würde ohne diese Maßnahme bei einem aktuellen ADC-Wert von 35 3523 angezeigt werden.
Die "alten Zeichen" 23 werden aber von den Leerzeichen überschrieben und wir sehen den korrekten Wert:
35
Die zweite Zeile mit dem Bargraphen machen wir ähnlich platt.
Aber zuerst zur Berechnung: Wir haben einen Bereich von 0 - 1023 und 16 Zeichen Platz. Der Bargraph soll bei niedrigen Werten nichts und bei
hohen Werten 16 Zeichen anzeigen. Also 17 Zustände (max. 16 Zeichen und kein Zeichen). 1023 / 17 = 60,18.
Bei einer Ganzzahlendivision schneidet Bascom die Dezimalstellen einfach ab. Ergebnis von 1 / 2 wäre somit 0!
Um eine möglichst gleichmäßige Bargraph-Anzeige zu bekommen, benötigen wir
Werte zwischen 0 und 16. 1023 / 60 ergäbe 17 - zuviel; 1023 / 61 ergibt 16.
Wir teilen also unseren ADC-Wert durch 61 und haben die Anzahl der darzustellenden Zeichen.
Mit
Locate 2,1
LCD SPC(16)
Locate 2,1
In den Zeilen 69 und 70 setzten wir unseren unsichtbaren Cursor an den Anfang der zweiten Zeile und geben mit dem SPC(x)-Befehl 16 Leerzeichen
aus, um danach in den Zeilen 73 bis 75 mit einer Zählschleife die korrekte Anzahl von Zeichen auszugeben:
For I = 1 To Anzahl_blocks
Lcd Chr(255)
Next I
Ihr seht, dass wir anfangen, ab 1 bis zu unserem errechneten Wert zu zählen. Ist dieser Wert 0, so wird nichts ausgegeben, ansonsten das
Zeichen Nr. 255, das einem ausgefüllten Rechteck entspricht.
Dazu benutzen wir den CHR(xxx)-Befehl, den wir ja schon von unseren selbstdefinierten Sonderzeichen kennen.
Die "alive"-LED in Zeile 80 umschalten und schon geht es wieder von vorne los...
Um nicht zu häufig das LCD beschreiben zu müssen, schauen wir in Zeile 61, ob sich der ADC-Wert geändert hat:
If Adcval <> Adcval_old Then
Weicht der aktuelle Wert nicht vom alten Wert ab, so geht es direkt zur "alive"-LED in Zeile 80.
Ansonsten wird der neue ADC-Wert verarbeitet und wird mit
Adcval_old = Adcval
in Zeile 62 zum "neuen" alten Wert. Es folgt die Aktualisierung von Zeile 1 und die Neuberechnung der auzugebenden Zeichen für den Bargraphen in Zeile 2.
Auch hier prüfen wir mit
If Anzahl_blocks <> Anzahl_blocks_old Then
in Zeile 67, ob sich die Anzahl der Bargraph-Zeichen geändert hat.
Wenn ja wie oben: "neue" alte Anzahl und Zeile 2 aktualisieren.
Und weiter zur "alive"-LED in Zeile 80
Den Bargraphen könnte man eleganter aktualisieren, indem man nur die Änderungen zwischen Anzahl_blocks_old und Anzahl_blocks berücksichtigt
und mit dem Locate-Befehl entsprechend Leerzeichen oder Blocks neu schreibt.
Versucht es mal!
Viel Spaß!
Hausaufgaben:
- Ändert die kleine Pause in Zeile 82
- Entfernt die Kondensatoren auf der Analogseite (nach dem Test wieder einbauen!)
- Schaltet einen Festwiderstand vor oder/und nach das Potentiometer
- Testet die ADC-Schaltung mit Festwiderständen (nicht zu kleine Widerstände (< 1 kOhm) nehmen!)
- Schließt ein zweites Potentiometer an und wertet es aus
- Schwere Aufgabe: "Verfeinert" die Bargraph-Anzeige mit selbstdefinierten Zeichen
Tipp für selbstdefinierte Zeichen
Wir haben ja schon unseren selbstgebastelten Smiley vorgestellt.
Mit bis zu 8 (CHR(0) - CHR(7) selbstdefinierten Zeichen kann man aber auch etwas Sinnvolleres anstellen:
Verzeiht bitte die Darstellung in Code-Form; nur so können wir uns gewiss sein, dass die Zeichenabstände konstant sind.
|
Quellcode
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
Unser LCD stellt einzelne Zeichen in einer 5x8-Matrix dar. Die unterste Reihe ist normalerweise für den Cursor, den wir aber hier nicht benutzen, gedacht.
Mit dem LDC-Designer aus Bascom können wir beliebige Sonderzeichen erstellen. Unser Zeichen Chr(255) sieht so aus ("X" entspricht einem gesetzten,
"." einem nicht gesetzten Punkt, "_" dient als Abstandshalter):
_12345
1XXXXX
2XXXXX
3XXXXX
4XXXXX
5XXXXX
6XXXXX
7XXXXX
8XXXXX
Es liegt also nahe, für die "Verfeinerung" z. B. 4 oder 7 Sonderzeichen mit unterschiedlicher Spalten- oder Zeilenanzahl zu definieren:
_12345_______12345
1X....______1XX...
2X....______2XX...
3X....______3XX...
4X....______4XX...
5X....______5XX...
6X....______6XX...
7X....______7XX...
8X....______8XX... usw.
oder
_12345_______12345
1.....______1.....
2.....______2.....
3.....______3.....
4.....______4.....
5.....______5.....
6.....______6.....
7.....______7XXXXX
8XXXXX______8XXXXX usw.
|
Und noch ein Tipp:
Für die spätere Berechnung braucht Ihr den Modulo-Befehl mit folgender Syntax:
var1 = var2 MOD var3
Bei der Ganzzahlendivision verlieren wir ja die Nachkommastellen:
Variable = 54 / 5 -> Variable = 10
Mit dem Modulo-Befehl erhalten wir den nicht mehr teilbaren Rest einer Division:
Variable = 54 MOD 5 -> Variable = 4 (= 54 - 5*10)
Damit könnt Ihr berechnen, welches Sonderzeichen ausgegeben werden soll.
Nicht vegessen: Variablen müssen deklariert werden! (DIM-Befehl)
Das war jetzt viel Neues und auch Eure Hausaufgaben sind umfangreich.
Willie muss sich noch bis zum nächsten offiziellen Post gedulden. Sorry, Willie!
Schalten Sie auch nächstes Mal wieder ein, wenn sie die M&Ms sagen hören: "Dem Manne kann geholfen werden! Jetzt aber!"
Viele Grüße
Mathias & Micha
Inhaltsverzeichnis aller Projekt-Posts in Post 1