Die Software

Den AVR kann man mit verschiedenen Programmiersprachen programmieren , jedoch wollen wir uns es nicht unnötig schwer
machen und benutzen hier ausschliesslich die Software : BASCOM der Firma MCS Electronics.

Warum BASCOM ?
BASCOM ist ein BASic-COMpiler und arbeitet mit den gängisten Befehlen.
Umsteiger von der Picaxe z.B. , müssen sich nur unwesentlich umstellen.
Einsteiger aus der PC-Programmierung fühlen sich schnell wie zu Hause.


Auf deren Homepage kann man den Editor als DEMO-Version kostenlos downloaden .
Die DEMO-Version hat den vollen Funktionsumfang und ist zeitlich nicht beschränkt .
Einzige Einschränkung ist , das nur 50% Code compiliert werden kann.
Das reicht aber zum Anfang für viele einfache Programme erst einmal völlig aus.



Wer es noch nicht hat , hier mal die Umstellung von English auf Deutsch :



Zunächst auf den MENU-Punkt [ Option ] gehen und dann auf Environment .





Es erscheint eine neue Maske .
Dort wählt man den Tabreiter [ IDE ] und sieht unten rechts das Feld für die Sprachauswahl ( Language )





Das Feld aufklappen und einfach Deutsch auswählen .
Danach auf  [ OK ]







Schon zeigt sich das ganze Programm in Deutsch  :-)





Die MENU-Leiste ist eigentlich trotz der umfangreichen Funktionen schnell erklärt.
Die Icon-Leiste unterhalb der MENU-Leiste enthält im Grunde das Gleiche , nur eben als Icon.
Der Aufbau der Icon-Leiste , sprich was diese enthalten soll , kann von jedem selber konfiguriert werden.



 
Unter [Datei] befinden sich die üblichen Funktionen wie : Laden , Speichern , Speichern unter , ect.

Unter [Editieren] befinden sich auch bekannte Funktionen wie : kopieren , aussschneiden , einfügen ,suchen, ect.
Also im Grunde all die Funktionen , welche man in jedem Texteditor auch wieder findet.
 

Unter [Anzeige] finden man



Hier wird das Editorfenster geteilt und man bekommt verschiedene zusätzliche Ansichten die man ausgewählt hat.



Pinlayout :



Dies ist eine recht praktische Funktion an Anzeige.
Fährt man mit der Maus über eines der Pins, wird einem sofort unterhalb eine Erklärung angezeigt,
was dieser Pin für Funktionen hat - leider in Englisch.

PDF Anzeigen :



Wie der Name es schon sagt , wird hier die PDF innerhalb des Editors angezeigt.





Programmer einstellen


Kommen wir doch jetzt erst einmal zum Einstellen des richtigen Programmers.
Wie gesagt , wird es in der Regel das Protokoll des STK500 sein , dies ist aber in der Anleitung des jeweiligen
Programmers noch einmal genau nachzulesen !



Wir gehen also im MENU auf OPTION und dann dort unter PROGRAMMIERER .
Nun erhalten wir eine neue Maske in der wir unseren STK500 einstellen .





Oben wählt man nun den STK500 native driver aus.
Dann wärennoch verschiedene Häckchen zu setzen :

Erase warning                 :  vor dem Löschen warnen
Auto Flash                        :  automatischen flashen
AutoVerify                         : automatisches Prüfen ob Syntax richtig geschrieben wurde
Upload Code and Data  :  es werden Programmcode und EEPROM programmiert
Program after compile   :  das muß ein jeder selber wissen , wie er es gerne hat.
                                                 ** dazu gleich mehr **

COM-Port ist klar, da für ein USB-Programmer ein COM-Port simuliert wird , muß jeder in der Systemsteuerung unter
System - Hardware - Gerätemanager - Anschlüsse(COM und LPT)  nachsehen , welcher COM-Port angelegt wurde
und diesen hier dann einstellen.

**
Um einen Code in den AVR programmieren , ( manche sagen auch "Brennen" dazu ... ) , kann man  dies über die
MENU Funktion oder eines der Icons machen .
Ich persönliche bevorzuge 2 Tasten !

F7 = Code prüfen
F4 = Code schreiben

Wenn man also in der Maske eben den Haken ' Program after compile'  nicht gesetzt hat , muß man erst F7 drücken
um den Code auf Richtigkeit prüfen zu lassen und ansachliessend F4 um ihn dann zu senden.
Hat man aber den Haken ' Program after compile' gesetzt , genügt nur F7 zu drücken , nach der Prüfung wird sofort
der Code gesendet.

Wie gesagt , bevorzuge ich , den Haken nicht gesetzt zu haben.
Niemand ist perfekt , ich selber auch nicht .
So kommt es öfters vor , das auch meine Codes noch (Tip) - Fehler beinhalten .
Diese würde ich ja mitsenden , wenn der Haken gesetzt ist.
1. Funktioniert der Code nicht
2. Wartezeit die nicht nötig tut

Dies muß aber jeder für sich selber entscheiden .




FUSEBITS


Kommen wir jetzt einmal zu den FUSEBITS.

Für viele sind die Fusebits "ein Buch mit sieben Siegel ".
Es ist auch richtig , das man mit falsch eingestellten Fusebits den AVR leicht zerstören kann.


Der Atmega8 ( und nur um den wird es hier vorrangig auf dieser Seite gehen ) wird im Auslieferungszustand
auf 1Mhz Taktfrequenz eingestellt.

Viele lassen diese Einstellung stehen und "begnügen" sich damit.
Kann ich nicht wirklich verstehen , immerhin habe ich den Atmega8 ganz bezahlt , also will ich den auch voll nutzen.


Um die Fusebits einstellen zu können , gehen wir auf das Icon mit dem grünen IC :


Hier wählen wir jetzt  [ Manuell programmieren ]  und erhalten eine neue Seite  :




Wir sehen dort 3 Tabreiter : [ FlashROM]  [ EEPROM ]  [ Lock and Fuse Bits ]
Wir gehen jetzt auf den Tabreiter : Lock and FuseBits  und bekommen wieder eine neue Seite :




Wie man jetzt wunderbar sehen kann , steht der Systemtakt auf intern 1Mhz . ( default value )
Jetzt klappen wir diese Zeile auf und suchen uns diesen Satz raus ......




Wie man sehen kann , gibt es für die interne Takterzeugung 4 mögliche Einstellungen  :

1 Mhz  / 2 Mhz / 4 Mhz / 8 Mhz

natüüüüürlich wählen wir jetzt hier : 100100:Int.RC Osc. 8 Mhz;Start-up time: 6 CK + 64ms;[CKSEL=0100 SUT=10]


anschließend müssen diese Einstellung noch "gebrannt" werden .



Dazu drücken wir den Button [Write FS ]
Das wars schon mit den Fusebits einstellen.



Der 1. Code ...


Wenn man nun loslegen möchte einen Code zu schreiben , muß man dem Editor immer ein paar Definitionen mitteilen.
 



$regfile = "m8def.dat"

Damit wird dem Editor mitgeteilt , für welchen AVR man jetzt einen Code schreiben möchte.
Der Editor lädt sich dann die passende Konfigurationsdatei , und kann damit Syntax und Fehler im Editor kontrollieren.

$crystal = 8000000

Hiermit stellen wir softwareseitig ein , das wir mit einem Systemtakt von 8 Mhz arbeiten wollen.
Natürlich muß diese Angabe identisch mit den eingestellten Fusebits sein.
Wenn nicht , erhällt man ungewollte Effekte , wie z.B. das Pausen länger oder kürzer ausgeführt werden als programmiert wurde.
 
$hwstack    = 32
$swstack    = 32
$framesize = 32


Diese Einstellungen sind für Einsteiger ( aber auch manchmal für Fortgeschrittene ) etwas kompliziert.
Hiermit  stellt man Speicherbereiche für Variablen , Sprungadressen und Befehle ein.
Die Einstellung '32' ist ein gesundes Mittelmaß , mit dem man in der Regel ganz gut klar kommt.






Für die , die es gern genau wissen möchten  :

HWSTACK

Der Hardware-Stack ist der Bereich im Speicher, der dafür reserviert ist um Rücksprungadressen und,
bei einem Interrupt, eine Sicherung der Register abzulegen.

Springst du mit GOSUB irgendwo hin, dann wird zuvor die Adresse gespeichert,
zu der bei einem RETURN wieder zurück gekehrt werden soll.
Wenn du innerhalb dieser Unterroutine in die du gesprungen bist, noch einmal GOSUB verwendest,
dann wird diese zweite Rücksprungadresse ebenfalls auf den Hardware-Stack (=Stapel) abgelegt.

Bei einem RETURN wird dann von der zweiten Unterroutine in die erste Unterroutine zurück gesprungen.
Dann wird die Adresse vom Stack gelöscht. Wird die erste Unterroutine beendet (RETURN),
dann springt das Programm zur ersten Rücksprungadresse zurück.
Auch diese Adresse wird wieder vom Hardware-Stack gelöscht.

Wie viel Speicher für diese Springerei benötigt wird, hängt also nicht von der Anzahl an GOSUBs oder CALLs ab,
sondern davon, wie viele GOSUB oder CALLs ineinander verschachtelt sind.
Für ein GOSUB in eine Unterroutine und noch ein GOSUB innerhalb dieser ersten Unterroutine und
dann noch ein GOSUB innerhalb der zweiten Unterroutine brauchst du 3 x 2 Byte.

Wenn du also deine Programme nicht extrem verschachtelst, dann brauchst du selten mehr als 10 Byte
Hardware-Stack für diese Springerei.

Außer dieser Rücksprungadressen, legt Bascom auch die Werte der Register in diesen Stack,
sobald ein Interrupt auftritt und der zugehörige Interrupt-Handler (ISR) angesprungen wird.

Bevor also die Unterprozedur aufgerufen wird, die immer dann automatisch ausgeführt wird,
wenn ein Interrupt auftritt, werden die Register in den HWStack gesichert. Dafür werden 32 Byte benötigt.
Wenn du also Interrupts aktivierst, dann brauchst du mindestens 32 Byte HWStack.

Da man in einem Interrupt-Handler so wenig wie möglich macht und die Hauptarbeit normalerweise in der
MainLoop verrichten lässt, ist es unüblich, innerhalb eines Interrupt-Handlers Unterprozeduren anzuspringen.
Also wird selten mehr als 32 Byte HWStack benötigt.


Wenn du es aber doch machst, was ja kein Problem ist, dann musst du zu den benötigten 32 Byte noch
die Byte für die Springerei dazuzählen.

Ich würde mal sagen, dass du beim HWSTACK großzügig bist, wenn du diesen am Anfang auf 40 Byte festlegst.
Und falls du weißt, dass du nicht so viel brauchst, weil du z.B. keinen Interrupt aktiviert hast,
kannst du später den HWSTACK entsprechend verkleinern.





SWSTACK

So, und jetzt zum Software-Stack. Gleich wie beim Hardware-Stack gilt,
dass nicht die Anzahl an Unterprozeduren (SUB) dafür ausschlaggebend ist wie groß der Software-Stack sein muss.
Ausschlaggebend ist, wie verschachtelt die Aufrufe untereinander sind.

Wenn du zehn Unterprozeduren hast, aber immer nur eine dieser Unterprozeduren gleichzeitig aktiv wird,
brauchst du nur so viel Software-Stack-Speicher wie ihn diese eine Unterprozedur benötigt.
Wenn du innerhalb einer Unterprozedur eine andere Unterprozedur aufrufst,
dann brauchst du im Software-Stack für beide Unterprozeduren Platz. Gleiches gilt auch für Funktionen.


Wie viel Platz ist das überhaupt?

Du brauchst für jede Variable, die an die Unterprozedur als Parameter übergeben wird, 2 Byte im SWStack.
Hast du also eine Unterprozedur mit 2 Parametern, dann brauchst du dafür 4 Byte SWStack.
Rufst du innerhalb dieser Unterprozedur eine andere Unterprozedur auf, die z.B. 3 Parameter erwartet,
dann brauchst du zu den bereits verbrauchten 4 Byte noch (3 x 2) 6 Byte dazu. Das wären dann 10 Byte.

Jede innerhalb einer Unterprozedur mit dem Befehl LOCAL erstellte Variable braucht ebenfalls je 2 Byte im SWStack.

Nehmen wir also an, dass du im Normalfall bis zu 4 Parameter an eine Unterprozedur weitergibst und
innerhalb der Prozeduren maximal 3 Variablen mit LOCAL definierst. Weiters nehmen wir mal an,
dass du innerhalb einer solchen Unterprozedur maximal noch eine weitere Unterprozedur mit wiederum 4 Parametern aufrufst,
die auch wieder bis zu 3 lokale Variablen hat, dann braust du für die Parameter der ersten Prozedur (4 x 2) 8 Byte.
Und für die lokalen Variablen der ersten Prozedur (3 x 2) 6 Byte. Das sind für die erste Prozedur 14 Byte SWStack.
Und die gleiche Menge kommt noch für den verschachtelten Aufruf der zweiten Unterprozedur dazu.
Das wären dann 28 Byte die für den SWStack reserviert werden müsste.

Wenn man noch ein paar Reserverbytes dazu tut, dann bist du in solch einem Fall mit 32 Byte SWStack
gar nicht mal so schlecht dran.

Wenn du also schon am Anfang deines Programmes den SWSTACK auf 32 stellst,
dann sind solche (eher schon komplexe) Vorgänge recht gut abgedeckt.
Wenn du später erkennst, dass du nicht so viel SWSTACK-Speicher benötigst,
dann kannst du ihn ja immer noch verkleinern.





FRAME

Und weiter geht es mit dem FRAME. Im Frame werden Daten und keine Adressen gespeichert.
Wenn an eine Unterprozedur ein Parameter übergeben wird, dann wird die Adresse dieses Parameters im SWSTACK gespeichert.
Der Wert, also das was in dieser Variable drinnen steht, wird im FRAME gespeichert.
Allerdings nur, wenn der Parameter mit dem Schlüsselwort BYVAL an die Prozedur übergeben wurde.

Da es in den meisten fällen besser ist, Werte mit BYVAL zu übergeben, können wir davon ausgehen,
dass der Wert der Variable im Frame gespeichert wird.

Nehmen wir wieder unsere Unterprozedur -- die mit den vier Parametern.
Nehmen wir mal an, dass der erste und der zweite Parameter je eine BYTE-Variable sind.
Der dritte Parameter ist eine WORD-Variable. Und der vierte Paramter eine STRING-Variable für 10 Zeichen.
Weiters sind in der Unterprozedur 3 lokale BYTE-Variablen definiert.

Wird diese Unterprozedur aufgerufen, dann wird vorher in den HWSTACK die Rücksprungadresse abgelegt.
Dann werden im SWSTACK die Adressen der Parameter und der lokalen Variablen abgelegt. -- jetzt kommts --
Und im FRAME werden die Werte der Parameter und der lokalen Variablen abgelegt.
Wird die Unterprozedur wieder verlassen, dann werden die Daten im Frame wieder frei gegeben.
2 x BYTE = 2 Byte (erster und zweiter Parameter)
1 x WORD = 2 Byte (dritte Parameter)
1 x STRING * 10 = 11 Byte (inkl. Abschlussbyte; vierter Parameter)
3 x BYTE = 3 Byte (lokale Variablen)
Für diesen Aufruf werden im FRAME also 18 Byte benötigt.
Bascom braucht den FRAME aber auch für andere Sachen.
Unter Anderem für die Umwandlung von Variablen in andere Datentypen.
Du kannst also den FRAME recht groß dimensionieren.
Nur wenn dir der übrige Speicher ausgeht, dann musst du den FRAME auf das Nötigste verkleinern.

Wenn du den FRAME großzügig mit 60 Byte dimensionierst, dann sollten die meisten Anwendungsfälle des ATmega8 abgedeckt sein.
Wenn du weißt, dass du weniger brauchst, dann kannst du den FRAME ja kleiner machen.