AVR-Mikrocontroller

http://sites.prenninger.com/elektronik/avr-mikrocontroller

http://www.linksammlung.info/

http://www.schaltungen.at/

                                                                                            Wels, am 2014-05-20

BITTE nützen Sie doch rechts OBEN das Suchfeld  [                                                              ] [ Diese Site durchsuchen]

DIN A3 oder DIN A4 quer ausdrucken
**********************************************************************************
DIN A4  ausdrucken
*********************************************************
AVR-Mikrocontroller

AVR  http://www.mikrocontroller.net/articles/ARM
AVR-Tutorial  http://www.mikrocontroller.net/articles/AVR-Tutorial

                  Aufbau des Tutorials


*********************************************************
                      Über AVR-Mikrocontroller
http://www.rowalt.de/mc/index.htm

Atmel AVR
http://de.wikipedia.org/wiki/Atmel_AVR

RN-Wissen Tutorial  
www.roboternetz.de

AVR-Einstieg leicht gemacht

ATmega16 und ATmega32
http://www.rn-wissen.de/index.php/AVR-Einstieg_leicht_gemacht

*********************************************************

Dr. Claus Kühnel

Programmieren der AVR RISC Microcontroller mit BASCOM-AVR

3. bearbeitete und erweiterte Auflage,
ISBN: 3-907857-14-4, 444 Seiten, € 34,95
http://www.ckuehnel.ch/ckskript/PDF/Inhalt%20BASCOM-AVR%203.pdf

Mikrocontroller
AVR
ARDUINO 
http://de.wikipedia.org/wiki/Arduino-Plattform
http://www.arduino.cc/

Arduino mit BASCOM-AVR programmieren. Hinweise hierzu sind unter
http://bascom-forum.de/index.php?topic=4868.0 zu finden.


http://www.ckuehnel.ch/

*********************************************************
Arduino Kochbuch
Michael Magolis, O'REILLY-Verlag

in www.schaltungen.at
x704_d_O'REILLY-x_Leseprobe- Arduino Kochbuch – Michael Mangolis (117 Seiten)_2a.doc


*********************************************************

AVR Mikrocontroller-Kochbuch
Entwurf und Programmierung praktischer Anwendungen
Lukas Salzburger,  Irmtraut Meister

ISBN: 3-645-25126-6 , 6,3 MB
336 Seiten, Softcover

Rezept auswählen, Zutaten zusammenstellen - und genießen. Nach genau diesem Konzept finden Sie in diesem Buch alles, um Ihr „Mikrocontroller-Süppchen" zu kochen: Von den ersten Programmierschritten über Messungen unterschiedlichster Größen bis zum Erzeugen von Signalen und zur Kommunikation über diverse Schnittstellen.

 Entdecken Sie die schier endlosen Möglichkeiten der Mikrocontroller!

Mit nur wenig Programmieraufwand verwirklichen Sie im Handumdrehen Ihre Ideen. Schritt für Schritt begleitet dieses Buch Sie von den allgemeinen Grundlagen zur praktischen Umsetzung und erleichtert so auch komplexe Programmierungen.

 Am Beispiel des AVR®-Mikrocontrollers von Atmel® lernen Sie das Potenzial von Mikrocontrollern kennen und können sich dadurch auch leicht in „fremde" Mikrocontroller einarbeiten. Für Einsteiger bietet das Buch auch Hinweise zur Programmierung von Bitoperationen und einfache Codegerüste - so bleiben keine Fragen offen.

http://www.franzis.de/elektronik/simulation-computer/avr-mikrocontroller-kochbuch

*********************************************************

Kleiner Bascom AVR Kurs

Im Loetstelle-Forum wurde von "passat2001" gefragt, ob man eine einfache analoge Schaltung auch so umsetzen könne, damit man diese später über einen Computer anpassen/programmieren kann.

Es hat sich einfach so ergeben. :-)

Irgendwie ist aus dieser Frage ein kleiner Kurs geworden, der die AVR Mikrocontroller und deren Programmierung mit Bascom erklären soll.

Es handelt sich um den Foren-Thread "Digitale Lösung für Schaltungen / Problem?".

Da immer wieder Fragen auftauchten und deren Antworten sich im gleichen Thread befinden, ist der Thread inzwischen ein wenig unübersichtlich geworden.

Deshalb versuche ich hier die wichtigsten Beiträge zusammenzufassen.

Hinweis

Ich bitte dich, Fragen zu diesem Kurs, direkt im oben genannten Foren-Thread "Digitale Lösung für Schaltungen / Problem?" zu stellen, und nicht per Email an mich zu schicken.

Die Fragen und deren Antworten sind auch für Andere interessant.

Warum nur einem/einer helfen, wenn mit gleichem Aufwand viel mehr Menschen etwas davon haben könnten?

Zweitens, wird es mir ansonsten einfach zu viel.

Viele Fragen können auch von anderen Forenteilnehmern beantwortet werden -- oft auch besser als von mir.

Kapitel

  1. Vorstellung der wichtigsten Mikrocontroller
  2. Die wichtigsten Datenblätter
  3. Stromversorgung
  4. Ideale Mindestausstattung
  5. Billige Mindestausstattung
  6. Programmer (Programmiergerät)
  7. Programmer STK200
  8. Programmer mySmartUSB
  9. Bascom Einstellungen
  10. Hallo Welt
  11. Hallo Welt - Fortsetzung
  12. Hallo Welt - noch ein Beispiel
  13. Last über einen Transistor anschließen
  14. Schalter an den µC anschließen
  15. Variablen
  16. Schalter an den µC anschließen - Fortsetzung
  17. Ohne Worte
  18. Label, Unterprozeduren und Funktionen
  19. Interrupts
  20. AVR im KFZ-Boardnetz
  21. Taster softwareseitig entprellen
  22. Fuse-Bits und Lock-Bits - Teil 1
  23. Fuse-Bits und Lock-Bits - Teil 2
  24. Fuse-Bits und Lock-Bits - Teil 3
  25. Fusebits Standardeinstellungen
  26. UART - RS-232 vom µC zum Computer
  27. RS232 - MAX232 - ATmega8 (über Nullmodemkabel)
  28. RS232 - MAX232 - ATmega8 (über 1 zu 1 Kabel)
  29. UART - RS-232 vom Computer zum µC
  30. UART - RS-232 vom Computer zum µC - Teil 2
  31. Binärdarstellung IO
  32. Ausgänge mit Computer steuern
  33. 20 Ausgänge mit Computer steuern
  34. 3x4 Tastenfeld
  35. LCD - Liquid Crystal Display
  36. Zwei LCDs anschließen
  37. Analog/Digital-Converter mit dem Befehl GETADC
  38. Analog-Comparator
  39. Timer/Counter
  40. Timer0 als Timer (Codebeispiel: Sirene)
  41. Timer0 als Counter
  42. Speicher, HWSTACK, SWSTACK, FRAME


4AP  der 4-Teile-AVR-Programmer

http://halvar.at/elektronik/kleiner_bascom_avr_kurs/


*********************************************************

Offizielles Bascom Forum

http://bascom-forum.de/forum.php

*********************************************************

BASCOM - Tutorial - Einführung in Mikrokontroller

Pensionisten-Denkweise:
Diese Seiten richten sich an Anfänger und Hobby-Elektroniker, die (wie ich früher) immer noch Ihre kostbare Zeit mit diskreten Schaltungen verplämpern - nur weil Sie denken, Mikrocontrollerprogrammierung wäre kompliziert oder teuer weil spezielle Programmiergeräte angeschafft werden müssen.
Nichts dergleichen ist der Fall

Zur Programmierung reicht ein Kabel (...das man sich selbst lötet), die Software gibts kostenlos und wenn man mit einer einfachen Hochsprache wie in meinem Beispiel z.B. mit Bascom-Basic anfängt, dann hat man meist schon am ersten Abend ein Testprogramm am laufen. Man braucht also erstmal garnichts anzuschaffen als einen Controller für ca. € 2,- und mit ein paar vorhandenen Kleinteilen und einem Lötkolben in der Werkstatt kann man gleich loslegen!
Hat man das einmal geschafft eröffnet sich einem eine völlig neue Welt an Möglichkeiten und wo man früher tagelang an einer Ziffernazeige gebastelt hat, hat man dann schneller ein mehrzeiliges Display mit PC-Schnittstelle, Tastencodereingang und anderen Spielereien fertig!

Beispiel:
Ich hatte einen Schrittmotortakt (Spindeltrieb) so zu teilen, daß auf alle 730 Takte ein Ausgangsimpuls generiert wird.
Das entsprach dann glatt 0,1mm Spindelverfahrweg.
Konventionell wären das zwei 8-Bit-Zähler, zwei 8-Bit-Komparatoren und ein Logikgatter - also 5 ICs in Dip14-20.
Jetzt ist das ein einziges Dip8-IC für 1,50€ und 5 Zeilen Programmcode.
Für mich ein schlagendes Argument... und der Zahlenwert 730 steht da klar lesbar drin und muß beim nächsten Projekt nurnoch geändert werden.
Wer an der Komplettierung mit eigenen Erklärungen mitarbeiten möchte findet entsprechende Hinweise bei den Schaltungsbeispielen bzw. kann sich einfach per Mail bei mir melden.
Bitte kritisch lesen und mir Fehler oder unklare Formulierungen per email: technik@bunbury.de melden.
Alle meine Beispiele orientieren sich am ATmega8 und dessen Programmierung in Basic, da dies ein simpler und schneller Weg ist Erfolge zu erzielen und da das Gelernte in Verbindung mit Erfolgserlebnissen so am effektivsten memoriert wird.
Jedem, dem dieses Script zu trivial oder noch zu kompliziert ist empfehle ich eindringlich das "AVR - Microcontroller Lehrbuch" von Roland Walter (www.rowalt.de), daß sehr ausführlich und anschaulich alle Grundlagen erklärt und sehr viel weitergehende Informationen enthält.
Einige Seiten enthalten interaktive Scripte, die es ermöglichen den Erklärungstext und Codebeispiele mit den eigenen, realen Werten zu parametrieren - JavaScript sollte also aktiviert sein.

http://www.bunbury.de/Technik/avr/


1. Vorbereitung ATmega8

1. Vorbereitung

1.1 Was kann der Mega8, was kostet der und wo bekomme ich ihn?
1.2 Welche Hardware brauche ich um AVRs wie den Mega8 zu programmieren?
1.3 Welche Software brauche ich?


1.1 Was kann der Mega8, was kostet der und wo bekomme ich ihn?

Der ATmega8 verträgt Taktfrequenzen bis zu 16MHz (eine Operation wird in ca. 0,06 µs ausgeführt), besitzt 6 analoge Eingänge die ein Sensorsignal von z.B. 0 - 5V noch mit einer Genauigkeit von ca. 5mV auflösen können, 2 pulsbreitenmodulierte Ausgänge (PWM) mit der sich z.B. die Helligkeit einer LED in über 1000 Zwischenabstufungen steuern lässt, insgesamt 23 digitale Anschlüsse, über die man z.B . Schaltersignale einlesen oder Relais steuern kann, eine serielle Schnittstelle, mit der man ohne großen Programmieraufwand Daten vom PC oder Handy empfangen oder auf einem Bildschirm ausgeben kann und festen Speicher (EEprom) in dem man Werte so speichern kann, daß sie nicht verloren gehen, auch wenn die Betriebsspannung abgeschalten wird.

Dabei ist der Mega8 recht klein und besitzt die übliche Bauform einfacher Schaltkreise (DIL), die es auch Laien ohne Probleme möglich macht Schaltungen zu löten. Er hat sich mittlerweile quasi als ein Standard durchgesetzt und man kann ihn fast in jedem vernünftigen Elektronikgeschäft für 2 bis 3 Euro kaufen. (bei Conrad zahlt man natürlich das 3fache)

(nach oben)


1.2 Welche Hardware brauche ich um AVRs wie den Mega8 zu programmieren?

Nicht viel. Der Mega8 lässt sich fertig in eine Schaltung eingebaut programmieren - ohne teures Programmiergerät, ohne den Chip jedes mal umstecken zu müssen. Also erst die Schaltung aufbauen und einfach später am "lebenden" Objekt jeden einzelnen Befehl sofort ausprobieren!

Grundsätzlich genügt es 5V Betriebsspannung anzuschließen und ein 5-adriges Kabel zu löten, das am Parallelport des PCs angeschlossen wird. Sicherheitshalber baut man in einige Leitungen Widerstände ein um sowohl den Parallelport als auch den Chip selbst vor Schäden zu schützen.

Es sei darauf hingewiesen, daß es zu Störungen kommen kann, wenn die Programmieranschlüsse des Mega8 in einer Schaltung zusätzlich für andere Funktionen vorgesehen sind. D.h. ist z.B. an einem der für die Programmierung benötigten Pins schon ein Relais angeschlossen, dann kann dieses während des Programmierens anziehen oder die Programmierung schlägt fehl. Soweit möglich ist es günstig die Programmieranschlüsse also unbeschaltet zu lassen. Benötigt man alle Anschlüsse für die Schaltung ist es das Sicherste sich eine Extra-Platine zu löten und den Chip zum Programmieren umzustecken. Ein Programmierboard sieht am einfachsten so aus:



Diese Schaltung kann als Grundlage genommen werden um Schaltungen für den Maga8 zu entwerfen, die man jederzeit nachträglich umprogrammieren kann. Dazu empfiehlt es sich noch einen beliebigen 5poligen Zwischenstecker auf der Platine vorzusehen, um das Programmierkabel abzeihen zu können.
Bei anderen AVR-Typen finden sich die Signale MOSI, MISO, SCK und /Reset ebenfalls und hier sind lediglich die Pinnummern anzupassen.
Den Quarz und die beiden zugehörigen Kondensatoren können für einfache Anwendungen auch weggelassen werden, da der Mega 8 einen internen Oszillator besitzt. Allerdings empfehle ich zumindestens eine Schaltung zu besitzen, in der der Quarz oder ein Keramikoszillator enthalten sind. Wird der interne Oszillator einmal ausgeschaltet und auf extern eingestellt lässt sich der Mega8 erst wieder ansprechen und auch erst wieder zurück-umstellen, wenn auch wirklich ein externer Oszillator angeschlossen ist.

(nach oben)


1.3 Welche Software brauche ich?

Die Software "BASCOM" ist ein beliebter und sehr einfacher Basic-Compiler für die Programmierung des Mega8 und anderer AVRs. Er stellt einem sehr viele komplexe Funktionen zur Verfügung um z.B. die Ansteuerung von Modellbau-Servos oder die Ausgabe von Text auf LCD-Anzeigen mit einem einzigen Befehl zu erledigen. Um z.B. den Wert einer Variablen X über die serielle Schnittstelle auf den PC-Bildschirm zu senden genügt der Befehl: "Print X" - fertig!

Selbstverständlich gibt es auch sehr gute und großteils völlig kostenlose Compiler für C sowie Pascal und natürlich kann man auch direkt in Assembler programmieren - worauf ich hier jedoch nicht weiter eingehen will.

BASCOM ist nicht kostenlos - die Demo ist aber zeitlich und in den verfügbaren Funktionen nicht eingeschränkt. Lediglich die Programmgröße - also quasi die Länge und Komplexität des Programmes sind eingeschränkt. Zum Erlernen und für viele praktische Schaltungen ist diese Limitierung aber noch nicht störend. Wenn man BASCOM kennen und meist auch schätzen gelernt hat kann man sich entscheiden ob es einem die gerade mal 80,-Euro für die Vollversion wert sind oder ob man umsteigt. Der Support bei registrierter Vollversion funktioniert reibungslos (wenn auch in Englisch) und meist befinden sich im Anhang einer Email der Support-Mitarbeiter gleich die gewünschten Updates oder Dokumente.

Die BASCOM-Demo kann man sich
hier von meiner Seite oder direkt vom Anbieter MCS-electronics herunterladen. Man achte darauf, daß vor der Installation irgendein Drucker installiert wurde - BASCOM verweigert sonst beim ersten Starten den Dienst mit entsprechender Fehlermeldung. Und es sollte ein beliebiger Parallelport-Drucker(-treiber) sein - BASCOM akzeptiert USB-Drucker nicht! (Bug)

Da BASCOM Microcontroller direkt über unterschiedlichste Programmiergeräte beschreiben kann ist es wichtig sorgfältig darauf zu achten, daß die folgenden Einstellungen korrekt vorgenommen werden:

Options -> Programmer



Bei Programmer "Universal MCS Interface" und "WinAVR and SP12" auf der Lasche "Universal"



Das sollte alles sein. Sofern noch nicht geschehen schließt man einfach das Parallelportkabel und die 5V-Betriebsspannung an den Mega8 an und es kann los gehen. Man schreibt ein Programm (nächstes Kapitel) - drückt die Taste F7 um das Programm zu compilieren (in Chip-Sprache zu übersetzen) und ist dies ohne Fehlermeldung geschehen drückt man F4 um das Programmerfenster zu öffnen.

Öffnet sich sofort das folgende Fenster genügt ein Klick auf "Autoprogram chip" und man kann zusehen wie der Chip beschrieben wird - fertig!



Bei den meisten erscheint in diesem Moment aber statt des Programmers erstmal diese Fehlermeldung:



Das bedeutet, daß die Verbindung zum Chip nicht hergestellt werden konnte. In 90% aller Fälle (meine Erfahrung) liegt das an fehlerhaft gelöteten Kabeln, falscher Betriebsspannung und Kurzschlüssen auf Leiterplatten. Also lieber 8mal hingucken, die 5V Betriebsspannung im angeschlossenen Zustand nachmessen und jede einzelne Verbindung durchklingeln bevor man einen Hilferuf in die Welt schickt! Gegen falsches Löten kann euch im Internet keiner helfen!

Ist da 200%ig sicher alles einwandfrei und erscheint trotzdem immer wieder diese Fehlermeldung, dann kommuniziert BASCOM nicht korrekt mit dem Parallelport, entweder weil dieser eine andere Adresse als $378 hat (in der Systemsteuerung überprüfen) - oder (meistens) weil z.B. WinXP /2k / NT den Direktzugriff auf den Port verweigert.

In diesem Falle ladet euch die Datei "giveio.sys" und speichert sie im Ordner "../Windows/System32/drivers"

Ist das erledigt habt Ihr 2 Möglichkeiten:
- Ihr ladet euch die Datei "LoadDrv.exe" und könnt/müsst den Treiber jedes mal manuell starten und ggF. abschalten
- Ihr installiert den Treiber permanent indem Ihr die Datei "giveio.inf" ladet und ausführt.

Erklärungen, wie dieser Treiber und die Portfreigabe funktioniert findet Ihr reichlich im Netz. Ich habe den Treiber aus einer mMn seriösen Quelle - übernehme aber selbstverständlich keinerlei Garantie das er virenfrei ist und natürlich auch keine Gewährleistung für mögliche Schäden, die aus der Installation entstehen können.
Informiert euch selbst und wenn Ihr Zweifel habt, dann lasst die Finger davon und kauft euch einen USB-Programmer. Ich nutze diesen Treiber jedenfalls auch und hatte bislang keinerlei Probleme damit.

Dieses Low-Cost-Programmer-Kabel lässt sich nach meiner Erfahrung bis WinXP wirklich an jedem Rechner zum Laufen bewegen - Erfahrungen, ob das unter Vista auch noch geht habe ich einstweilen nicht - falls es jemandem von euch gelingt würde mich eine eine kleine Info freuen. Auf alle möglichen Fehlervarianten einzugehen würde den Rahmen dieses Scripts deutlich sprengen - helfen alle o.a. Maßnahmen nicht weiter, dann fragt bitte einfach in einem entsprechenden Forum.

(nach oben)

http://www.bunbury.de/Technik/avr/vorbereitung.htm



2. Programmierung BASCOM-AVR - Programmierpraxis


Wichtig: diese Anleitung soll die hardwarespezifischen Unterschiede der Programmierung zwischen PCs und Mikrokontrollern vermitteln und richtet sich damit an Leser, die in irgendeiner Weise bereits Vorkenntnisse in Programmierung allgemein besitzen. BASCOM besitzt eine ganz brauchbare Hilfe mit reichlich Beispielcode, mit der sich die genaue Syntax der Befehle wie If-Abfragen, Schleifen etc. schnell herausfinden lässt. Einige Teile sind interaktiv und ermöglichen es z.B. Erklärungen und Beispielrechnungen mit eigenen Werten nachzuvollziehen.
Dazu muß jedoch Javascript aktiviert sein

2. BASCOM - Programmierpraxis

2.1 Zahlen, wie sie ein µC versteht
2.1 prinzipieller Programmaufbau
2.3 digitale Ein- und Ausgänge
2.4 analoge Eingänge (ADCs)
2.5 "analoge" Ausgänge (PWM)
2.6 Hardwareinterrupts
2.7 Timer
2.8 serielle Schnittstelle
2.9 der EEprom


2.1 Zahlen, wie sie ein µC versteht

Um zu verstehen warum ein Microcontroller manchmal ein unerwartetes Ergebnis präsentiert, sollte man nicht nur wissen, wie man eine Binärzahl in eine Dezimalzahl umrechnet, sondern man sollte das Prinzip kennen, wie Zahlensysteme zusammenhängen, daß alle absolut gleichwertig sind und das man mit allen nach den selben Regeln identisch rechnen kann - ohne diese vorher in "normale" Zahlen umrechnen zu müssen.

Vorweg: Vermeiden Sie bei Mikroprozessorprogrammen wo immer möglich Fließkommazahlen!
Während es bei der üppigen Rechneleistung eines PCs kaum eine Rolle spielt wieviele Dezimalbrüche man miteinander verrechnet, kostet eine einzige Fließkommaoperation beim µC spürbar Speicher und Geschwindigkeit.

Hier nun erstmal 2 kleine Beispiele, mit denen Sie testen können, ob Ihr Zahlenverständnis wirklich ausreichend ist um auch mal einem Programmfehler auf die Schliche kommen zu können:

Die Variable x ist für beide Aufgaben als Byte dimensioniert:

x = 249 + 10 =
x = 249 / 10 =


Für alle die das
Zahlenscript schon gelesen haben, oder auch auch ohne dies die richtigen Antworten geben konnten habe ich hier noch ein paar kleine, nicht weiter dokumentierte Hilfsprogramme abgelegt, die bei den nötigen Berechnungen sehr hilfreich sein können.
(nach oben)

2.2 prinzipieller Programmaufbau

Ganz kurz vorweg 6 Punkte zur BASCOM-Syntax, die sich bei unterschiedlichen Hochsprachen häufiger unterscheiden:

- es ist nicht nötig Befehle oder Zeilen durch ein Semikolon o.ä. abzuschließen
- Strings bzw. Textkonstanten werden durch Gänsefüßchen gekapselt
- Kommentare werden durch ein Hochkomma eingeleitet und enden automatisch mit einem erzwungenen Zeilenumbruch (Enter-Taste)
- Binärzahlen werden durch &B und Hexadezimalzahlen mit &H eingeläutet. Dezimalzahlen sind natürlich ohne Präfix.
- die Zählweise bei Bits beginnt generell mit Bit 0, während Arrays stets mit Element 1 beginnen
- das Gleicheitszeichen wird sowohl für Vergleiche als auch für Wertzuweisungen identisch verwendet

Ein fertig geschriebenes Programm wird durch F7 compiliert und verläuft dies ohne Fehler kann es mit F4 auf den Chip "gebrannt" werden. Fehler beim Compilieren können durch Doppelklick auf die Fehlermeldung (Statuszeile ganz unten) direkt angesprungen werden.

Ein Bascom-Programm beginnt immer damit dem Compiler mitzuteilen für welchen Mikrokontrollertyp das Programm vorgesehen ist. Dies erfolgt indem man die Definitionsdatei benennt, in der alle prozessorspezifischen Adressen und Eigenheiten abgelegt sind. Diese Dateien befinden sich im Bascom-Stammverzeichnis und dort kann man im Zweifelsfalle auch nachschauen, wie die Datei für den gewünschten Prozessor genau heißt.

$regfile = "M8def.dat" < Definitionsdatei (hier für ATmega8)
$crystal = 8000000 < Quarzfrequenz in HZ angeben (hier 8MHz)
 
Dim x As Byte < Variablen definieren (hier x als Byte 0 - 255)
(Befehle)
Do < Beginn der Hauptschleife
(Befehle)
Loop < Ende der Hauptschleife
 
End < Programmende (für Compiler erforderlich)

Zu Anfang (also vor der Hauptschleife) definiert man Variablen, die Funktionen der Anschlüsse, konfiguriert die Hardware usw. Diesen Teil des Programmes bezeichne ich im Folgenden als Header. Der Header enthält alle Anweisungen, die beim Starten des Prozessors einmalig und vor allen anderen Programmteilen ausgeführt werden sollen.

Welche Zahlentypen verwendbar sind und welche Werte darin gespeichert werden können entnehmen Sie bitte der Bascom-Hilfe. Am häufigsten wird man wohl Bit (0 oder 1) ; Byte ( 8 Bit = 0 -255) und Word (16 Bit = 2 Byte = 0 - 65535) verwenden.
Nach dem Header folgt üblicherweise für Mikrocontroller eine Endlosschleife, da das Programm sonst nur einmal durchlaufen würde.

Vor oder auch nach der Hauptschleife kann man später noch beliebige Funktionsteile anfügen, die später Basic-üblich einfach durch Goto oder Gosub über Ihren Namen (Label) angesprungen werden können. Wird ein Unterprogramm von einem beliebigen Programmpunkt aus per Gosub Unterprogramm1 angesprungen, führt ein Return am Ende des Unterprogrammes dazu, daß das Programm bei erreichen des Return-Befehles wieder direkt nach dem Gosub-Befehl fortgesetzt wird. Das Unterprogramm selbst wird einfach durch seinen Namen, abgeschlossen durch einen Doppelpunkt eingeleitet und der Aufruf erfolgt ohne Doppelpunkt:

Gosub Unterprogramm1
(Befehle)
Unterprogramm1:

Return

Es ist nicht erforderlich Subroutinen bzw. Funktionen im Header zu definieren (Funktionsprototypen o.ä.) oder durch einen Befehl der Art Function oder Procedure einzuläuten - es genügt schlicht das Label (der Name mit Doppelpunkt).
Call by Value (Variablen- bzw. Pointerübergabe) an Funktionen geht nicht - also ausschließlich globale Variablen benutzen.

(nach oben)

2.3 digitale Ein- und Ausgänge

Bevor man die Anschlüsse benutzen kann muss man festlegen, welche Pins als Ein- oder Ausgänge genutzt werden sollen. Alle Pins sind bidirektional - man kann sich also aussuchen wo man was anschließt. Die Einstellung sollte also zu Anfang des Programms (Header) vorgenommen werden - kann aber später jederzeit wieder geändert werden. 
Die Pins sind in mit Buchstaben bezeichnete Ports unterteilt, denen jeweils Register-Bytes zugeordnet sind, die die Richtung der Daten speichern (Register DDR), die Eingangswerte zum Einlesen beinhalten (Register Pin) oder die Ausgabewerte (Register Port).

Der Mega8 besitzt 3 Ports: B; C und D, deren Anschlüsse im Bild ersichtlich sind.
Nochmal der Hinweis: die Zählweise beginnt immer mit 0.
Die Angaben in Klammern beziehen sich auf optionale Verwendungen des Pins: Pin23 - 28 lassen sich z.B. auch als Analogeingänge konfigurieren, über Pin 2 und 3 lässt sich eine serielle Verbindung zum Computer aufbauen usw.

Die Pins 9 und 10 (PB6 und 7) sind nur frei verfügbar, wenn der Mega8 auf internen Takt eingestellt ist, da sie sonst für den Quarzoszillator verwendet werden. Pin1 ist standardmäßig mit der Reset-Funktion belegt, womit PC6 auch nicht mehr uneingeschränkt verwendbar ist.
Die Reset-Funktion lässt sich prinzipiell auch deaktivieren um den Pin nutzbar zu machen - allerdings lässt sich der Chip dann nicht mehr einfach umprogrammieren. Ich rate davon ab und werde auch nicht näher darauf eingehen.

Man kann jeweils den Zustand aller Pins eines Ports gleichzeitig verändern/einlesen, indem man ein ganzes Byte in ein Register schreibt/ausliest.Jedes Bit des Bytes bezieht sich dann auf einen Pin des Ports. Will man nur den Zustand eines Bits, also eines einzigen Pins verändern oder abfragen muß man an den Befehl nur einen Punkt und die Nummer des zu verändernden Pins anhängen.
Also "RegisterPortbuchstabe.Pinnummer = Wert"
Es empfiehlt sich die Werte direkt binär anzugeben (&B...) weil man so einfach abzählen kann, welcher Pin welchen Wert bekommt:

Ein-/Ausgänge festlegen:

DDRD = &B00000101 schaltet PD0 und PD2 als Ausgang, alle Übrigen werden als Eingänge konfiguriert.
DDRD.2 = &B0 setzt nur PD2 auf 0, also auf Eingang und lässt die übrigen Stellen von DDRD unverändert.

Pins Ein- und Ausschalten:

PortD = &B00000101 schaltet die Pins PD0 und PD2 auf 1 (+5V) und setzt die Übrigen auf 0V
PortD.2 = &B1 schaltet nur PD2 auf 1 (+5V) und lässt die anderen unverändert

Signal an den Pins einlesen:

Die Eingänge eines AVRs brauchen immer eindeutige Spannungs-Signale: entweder 0V oder +5V. Ein Schalter kann aber nicht 2 verschiedene Spannungen ausgeben, sondern nur einen Stromkreis schließen oder öffnen. Deshalb muss man zusätzlich wie im Bild unten einen Widerstand vorsehen. Andere Schaltkreise, Fernsteuerungsempfänger oder Sensoren mit Digitalausgängen liefern meistens solche Signale und können ohne zusätzlichen Widerstand angeschlossen werden.

DDRD.2 = 0
x = PinD.2 
x ist 1 bei gedrückter Taste 
DDRD.2 = 0
x = PinD.2 
x ist 0 bei gedrückter Taste  

 

  Auch Transistoren machen letztlich nichts anderes als Schalter oder Relais: Kontakt auf oder zu. Deshalb müssen auch Transistoren mit Pull-Widerständen versehen werden, wie im Bild links.
Da am Transistorausgang nicht mehr als die 5V vom Pullupwiderstand rauskommen können, ist diese Schaltung auch geeignet um andere Spannungen als 5V einzulesen. Mit dem 10k Basiswiderstand und als Transistor z.B. einem BC550 erhält man bei beliebigen Eingangsspannungen ab ca. 1-2V bis 30V am AVR ein sauberes 0-Signal und mit 0V oder ganz ohne irgendein Signal am Eingang eine logische 1 am AVR.  

Das Eingänge häufig nur mit Tasten oder Transistoren gesteuert werden sollen wussten auch die Entwickler der AVRs und haben die Pullupwiderstände gleich mit eingebaut. Allerdings muss man diese extra einschalten - da sie im Grundzustand nicht aktiv sind. Statt sich noch ein Register merken zu müssen hat man dem Benutzer das Leben leicht gemacht: den Pullupwiderstand eines Pins schaltet man ein, indem man eine 1 ausgibt, obwohl der Pin als Eingang eingestellt wurde:

So kann man sich die extra Pullupwiderstände sparen, wenn man einen Taster oder Transistor anschließt, der 0V (Masse) schaltet:

DDRD.2 = 0
PortD.2 = 1
x = PinD.2 
x ist 0 bei gedrückter Taste 


Vielleicht ist es aufgefallen: wenn man einen einzelnen Pin, bzw. ein einzelnes Bit ein und ausschalten will ist es egal ob man das &B schreibt, weil die Werte 1 und 0 dezimal identisch sind mit der binären Zahl. Wenn man mehrere Bits gleichzeitig ändern will - also ein Byte angibt muß man darauf achten. Der Befehl DDRC = &B00001001 schaltet C.0 und C.3 als Ausgänge den Rest als Eingang. Dezimal muss 00001001 umgerechnet werden: DDRC=9 macht also genau das selbe. 
Abschließend noch ein zusammengefasstes Beispiel für die digitalen Ein- und Ausgänge:

DDRB = &B00110000 schaltet B4 und B5 als Ausgänge und B0-B3 als Eingänge, B6 und B7 gibts beim Mega8 garnicht  
PortB = &B00010010 Ausgang B4 wird auf +5V und B5 auf 0V geschaltet und nur der Pullup für den Eingang B1 wird aktiviert - die anderen Eingänge sind "offen" und müssen mit Ausgängen anderer Bausteine verbunden werden.  

Bei Eingängen, an die garnichts angeschlossen wird sollte man immer den Pullup aktivieren, da sie sonst zufällige Zustände haben und das Programm anfangen kann komische Sachen zu machen.

(nach oben)

2.4 analoge Eingänge (ADCs)

Mit dem Mega8 kann man 6 analoge Spannungssignale im Bereich von 0 bis +5V einlesen, z.B. von Sensoren. Standardmäßig werden die Spannungswerte mit 10 Bit binär gewandelt und ergeben damit eine Zahl von 0 (0V) bis 1023 (+5V). Die 6 Analogeingänge ADC0 - ADC5 befinden sich an den selben Pins wie der Digitalport C - also Pin 23 bis 28. Die Werte einzulesen ist vergleichsweise einfach. Der ADC muß nur mit einer Zeile im Header konfiguriert und mit einer weiteren gestartet und ab dann stehen die Werte zur verfügung:

Config Adc = Single , Prescaler = Auto  
Start Adc

Ist das einmal im Header geschehen, kann man den aktuellen Wert eines Analog-Kanals jederzeit mit der Funktion Getadc(Kanalnummer) auslesen:

x = Getadc(4) schreibt den Wert der Spannung an Pin 27 (ADC4) in die Variable x

Man beachte, daß die Zahl 10 Bit - also bis 1023 groß sein kann und damit natürlich nicht in einer Variable der Größe Byte gespeichert werden kann. Deshalb sollte x zuvor mindestens als Word (16Bit) definiert worden sein. Einen Variablentyp mit genau 10 Bit gibt es nicht - Word ist das Nächstgrößere.

(nach oben)

2.5 "analoge" Ausgänge (PWM)

Technisch gehört die Ausgabe von "analogen" Spannungen hinter die Einführung in die Timer, thematisch passt es hier aber besser, nach den analogen Eingängen. Eine Analogspannung kann ein Prozessor eigentlich nicht ausgeben, mit einem Trick aber etwas Ähnliches:.
Ein Motor würde z.B. an 6V ca. halb so schnell laufen wie bei 12V. Das Selbe - also halbe Drehzahl - erreicht man, wenn man an den Motor für eine halbe Sekunde die volle 12V-Spannung anlegt und Ihn dann wieder für eine halbe Sekunde ausschaltet. Die volle Drehzahl kann er nicht erreichen, das geht nur, wenn die 12V dauerhaft anliegen. Die halbe Drehzahl ergibt sich dadurch, daß der Motor die halbe Zeit beschleunigt und die andere Hälfte abbremst.

So ein Signal, bei dem die Ein- und Ausschaltzeit prozentual eingestellt wird (Puls-Breiten-Modulation) kann ein Controller erzeugen. Die Ein- und Ausschaltzeiten folgen dabei viel schneller als im Beispiel mit der halben Sekunde. Praktisch so schnell, daß eine LED nur schwach zu leuchten schneint und man garnicht bemerkt, daß diese kurz eingeschaltet und danach zeitweise ganz ausgeschalten ist. Der Mega8 stellt zwei PWM-Ausgänge zur Verfügung: OC1A (Pin15) und OC1B (Pin16)
Um diese benutzen zu können muß im Header der Timer1 für die PWM-Funktion konfiguriert, aktiviert und gestartet werden:

Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1
Enable Timer 1
Start Timer 1

Eine genaue Beschreibung was welche Angabe bedeutet findet sich in der Bascom-Hilfe.
Ist der Timer so konfiguriert, kann man den aktuellen Wert eines PWM-Augangs jederzeit mit der Funktion Pwm(Kanalnummer) einstellen. Ein PWM Signal wird dann ständig ausgegeben, bis man den Wert = 0 setzt oder den Timer1 stoppt.
In der Config-Zeile ist der PWM-Ausgang auf 10 Bit Auflösung eingestellt - also wieder Werte zwischen 0 und 1023. Gibt man dem PWM-Kanal jetzt den Wert 1023 vor, dann ist der Ausgang für 1023 von 1023 Zeitabschnitten eingeschaltet - also es kommt dauerhaft +5V aus dem Ausgang. Setzt man den Wert auf 0 (von 1023 Zeitschritten) ist der Ausgang ständig auf 0V. Bei allen anderen Zahlen ergeben sich Zwischenwerte - gibt man z.B. 10% der insgesamt 1023 Zählschritte, also 102 als Sollwert vor, dann bekommt z.B. eine LED am Ausgang auch nur 10% der Zeit Strom und scheint demnach auch nur mit 10% Ihrer Leuchtkraft zu leuchten.

Pwm1A = 512 gibt ein Schaltverhältnis von ca. 50% (512 von 1023) auf OC1A (Pin15) aus

Der PWM Ausgang lässt sich auch auf andere Auflösungen als 1023 Schritte einstellen. Die 10 Bit aus dem Beispiel haben nicht nur den Vorteil, daß sich so sehr feine Abstufungen einstellen lassen, sondern vorallem, daß mit 0-1023 der selbe Zahlenbereich benutzt wird wie bei den Analogeingängen. Theoretisch könnte man also die Spannung von einem Potentiometer an einem Analogkanal (1ADC ) direkt auf einen PWM-Kanal ausgeben und so z.B. die Drehzahl eines Motors einstellen: Pwm1A = Getadc(1) - führt aber leider zu einer Fehlermeldung. Man muß zuerst den Analogwert in eine Variable einlesen und kann dann die Variable auf den PWM-Ausgang schreiben um das zu realisieren:

x = Getadc(1) steuert mit dem Analogwert von ADC1 (Pin24) den PWM-Ausgang OC1A (Pin15)
Pwm1A = x

Man beachte, das x wieder mindestens vom Typ Word sein muß, um die 10Bit-Werte aufnehmen zu können.
(nach oben)

2.6 Hardwareinterrupts

Normalerweise läuft das Programm des Mikrocontrollers immer in einer Endlosschleife. Man kann nun z.B. ständig den Zustand einer Taste abfragen um daraufhin einen Vorgang auszulösen. Die Programmschleife braucht jedoch eine gewisse Durchlaufzeit - ist der Tastendruck bzw. das Eingangssignal sehr kurz, erscheint also erst nach einer Abfrage des Pin-Zustandes und ist schonwieder vorbei, wenn die Programmschleife wieder bei der Abfrage angekommen ist, dann "bemerkt" das Programm garnicht, daß ein Signal da war.
Dafür gibt es 2 spezielle Anschlüsse: Int0 (Pin4) und Int1 (Pin5).
Diese Pins kann man so konfigurieren, daß sie bei Signalen sofort das Hauptprogramm anhalten und zuerst einen anderen Programmteil ausführen, ohne das der Pinzustand in der Schleife noch abgefragt werden muß. Solche Funktionen, die daß Hauptprogramm augenblicklich unterbrechen können nennt man Interrupts und diese sind vor allem für sehr kurze oder zeitkritische Signale geeignet.
Bei der Einstellung der Parameter kann man auswählen, ob die Unterbrechung dauerhaft bei 0 Signal (Low Level), oder nur einmalig beim Umschalten von 0 auf 1 (rising) oder umgekehrt von 1 auf 0 (falling) erfolgen soll:

Config Int0 = Falling löst eine Unterbrechung des Hauptprogrammes aus, wenn Pin4 von 1 auf 0 umschaltet
Enable Interrupts aktiviert allgemein die Interruptfunktionen - muß nur einmal angegeben werden

Für die Beschaltung mit Pullup- oder Pulldownwiderständen gilt das selbe wie bei den "normalen" Digitaleingängen. Ein Interrupt-Anschluss sollte natürlich auch als digitaler "Eingang" definiert worden sein.

Nun muß man dem Prozessor noch mitteilen, was er machen soll, wenn der Interrupt ausgelöst wird. Dazu schreibt man vor oder nach der Hauptschleife ein Unterprogramm. Der Name desUnterprogrammes wird zuerst angegeben, abgeschlossen mit einem Doppelpunkt. Damit weiß Bascom, daß dies ein Label, bzw eine Sprungmarke ist. Beendet wird die Subroutine durch den Befehl Return, der dazu führt, daß der Prozessor dort wieder mit dem Hauptprogramm fortfährt, wo er unterbrochen wurde:

Unterprogramm1: < Beginn des Unterprogramms
(Befehle)
Return < Rückkehr zum Hauptprogramm

Im Header muß noch mitgeteilt werden, daß zu dem Unterprogramm gesprungen werden soll, wenn ein Interrupt ausgelöst wird:

On Int0 Unterprogramm1 springe bei Interrupt0 zum Unterprogramm1

Beim Aufruf eines Unterprogrammes übrigens nur den dessen Namen angeben, ohne Doppelpunkt. Natürlich kann ein Unterprogramm, daß automatisch durch einen Interrupt angesprungen wird auch jederzeit per Programmbefehl mit Gosub Unterprogrammname angesprungen werden.

Noch ein wichtiger Hinweis, falls die Hardwareinterrupts mit Tasten angesteuert werden:

Das "Prellen" von Kontakten ist ein häufiges Problem in elektronischen Schaltungen. Das bedeutet, daß bei Betätigung einer Taste nicht nur ein Impuls gesendet wird, sondern mehrere und häufig nochmals, beim Loslassen der Taste. Dieses Problem kann man entweder elektronisch lösen, indem man kleine Kondensatoren parallel zur Taste anschließt oder per Software. Die Interrupts im AVR werden meist flankengesteuert genutzt und werden so mehrmals aufgerufen, auch wenn eine Taste nur einmal betätigt wurde. Beim Aufruf des ersten Interrupts wird zwar die Abarbeitung anderer Interruptroutinen temporär blockiert, aber der AVR "merkt" sich, daß während dessen ein weiterer Interrupt aufgelaufen ist und führt diesen unmittelbar nach Beendigung der aktuellen Routine aus. Das Abschalten bzw. Disablen des Interrupts während der Abarbeitung hilft leider nichts, da er trotzdem gespeichert wird. Die Interruptroutine wird dann eben beim Wiedereinschalten des Interrupts erneut ausgeführt.

Eine mögliche und relativ einfache Lösung für dieses Problem ist, den Interruptspeicher des AVRs vor dem Verlassen der Routine zu löschen und dies geschieht indem man in das entsprechende Bit des GIFR-Registers eine logische 1 schreibt.
Für den Int0 macht man das z.B. durch den Befehl Gifr.intf0 = 1 . Signalflanken die während der Abarbeitung der Interruptroutine z.B. durch Prellen entstanden sind führen so nicht mehr zu einem wiederholten Anspringen der Routine.

(nach oben)

2.7 Timer

Der Mega8 besitzt zwei Timer: Timer0 und Timer1
Timer sind nichts anderes als Zähler, die durch den Prozessortakt selbstständig vorwärts- oder rückwärtszählen können. Je nachdem wie hoch die Quarzfrequenz ist und wie der Timer konfiguriert wird kann man bei bekanntem Timer-Takt anhand des Zählerstandes sehr genau die Zeit, also z.B. die Dauer eines Eingangs-Impulses messen. Man kann den internen Takt auch ausschalten (Modus: Counter) und Impulse von externen Signalquellen zählen lassen oder man kann Ihn als PWM-Ausgang konfigurieren.

Timer sind binärer Zähler - Timer0 ist 8 Bit "breit" und kann demnach nur von 0 bis 255 zählen. Kommt ein 256ter Zählimpuls geht er wieder auf 0 - das ist so, als ob man ein Display mit 2 Stellen hat, daß nach 99 auch nur wieder 00 anzeigen kann, statt 100. Timer1 ist 16 Bit breit, kann demnach bis 65355 zählen und geht beim 65356ten Zählschritt wieder auf 0

Wenn der maximale Zählerstand überschritten wird und sich der Zähler auf 0 zurückstellt, dann wird ein Interrupt ausgelöst. Wie bei den Hardwareinterrupts kann man dem ein eigenes Unterprogramm zuweisen, daß dann automatisch in festen Zeitabständen bei jedem Timerüberlauf aufgerufen wird.

Ein Beispiel:
Sie benutzen mit 65536 Zählschritten, 
einen Quarz mit MHz
und den Prescaler =  

Die Zählschritte des Timers erfolgen mit: Quarzfrequenz / Prescale = 16 MHz / 256 = 62500 Hz - also alle 0,016 ms. Die Dauer, die der Timer insgesamt benötigt bis die 65536 Schritte voll gezählt sind beträgt: 0,016 ms x 65536 = 1.048576 Sekunden. 
Stellt man den Timer im Unterprogramm gleich auf einen höheren Startwert als 0 ein, dann zählt er von dort ab natürlich nicht mehr die vollen 65536 Schritte bis er wieder auf 0 umschlägt. So kann man die Zeitabstände zwischen den Interrupts verkürzen und genau einstellen. 

Angenommen man will den Takt statt alle 1.048576 Sekunden genau auf Sekunden einstellen
(aktualisieren), dann darf der Timer nur noch 1,0 Sekunden / 0,016 ms  = 62500 Zählschritte zählen. Ergibt diese Rechnung keine glatte Zahl muß man runden*. Zieht man jetzt diesen Wert vom Maximalwert 65536 ab, erhält man den Startwert, auf den der Zähler voreingestellt werden muss: 3036
 Der Timer zählt jetzt also immer von 3036 bis 65536 und das Unterprogramm wird damit alle 1.0 Sekunden angesprungen, also mit 1 Hz.  Das Voreinstellen auf den neuen Startwert sollte man übrigens gleich als erstes im Unterprogramm erledigen. Der Timer kann dann im Hintergrund schon korrekt weiterzählen, während man andere Befehle ausführen lässt. Ein fertiges Programm, in dem der Timerinterrupt alle 1.0 Sekunden aufgerufen wird, könnte also prinzipiell einfach so aussehen:

$regfile = "M8def.dat" 'Definitionsdatei für ATmega8
$crystal = 16000000 'Quarz: 16 MHz
Config Timer1 = Timer , Prescale = 256 'Timer konfigurieren
On Timer1 Timerroutine 'Timerinterrupt Subroutine zuweisen
Enable Timer1 'Timer aktivieren
Start Timer1 'Timer starten
   
Do 'Beginn Hauptschleife
  'Programmbefehle einfügen
Loop 'Ende Hauptschleife
   
   
Timerroutine: 'Beginn Subroutine
Timer1 = 3036 'Timer auf neuen Startwert einstellen
  'Programmbefehle einfügen
Return 'Ende Subroutine
   
End  


*Es ist immer sinnvoll, sich vorher etwas Gedanken über Quarz, Prescale und Timer zu machen, wenn das Ergebnis genau werden soll. Je mehr Zählschritte dem Timer noch übrig bleiben, je genauer wird das Ergebnis und je weniger fällt das Runden auf glatte Zählschritte ins Gewicht. Eine Timerschleife für Timer0 mit 256 Schritten schon auf 250 Schritte voreinzustellen kann kaum vernünftige Resultate bringen. Muß man z.B. schon von 0,5 auf einen ganzen Takt aufrunden, ergäbe sich so auf die letzten 6 verbleibenden Zählschritte schon ein Fehler von knapp 10%, währen die 0,5 Rundung auf z.B. 200 verbleibende Schritte nur noch 0,025% ausmacht.

Konfiguriert man den Timer als Counter, dann kann man an die entsprechenden Eingänge: Pin 6 für Timer0 und Pin 11 für Timer1 digitale Signale anschließen, die dann gezählt werden. Man kann einstellen ob der Zählschritt bei der ansteigenden Flanke ( 0 -> 1 Wechsel) oder der abfallenden Flanke des Signals erfolgen soll und selbstverständlich kann man auch hier einen Prescaler vorgeben, so daß z.B. nur jeder 1024te Zählimpuls erfasst wird.

Beispiel:

Config Timer1 = Counter , Edge = Rising, , Prescale = 1024  ' Timer1 zählt jedes 1024te Signal an Pin11 in dem Moment, wo dieses von 0 auf 1 umschaltet.

Die Timer bieten noch weitere Einstellmöglichkeiten, die ich hier beim besten Willen nicht aufführen kann. Den Timer1 als PWM-Ausgang zu konfigurieren wurde oben schon teilweise erklärt, über weitere Möglichkeiten kann man sich hervorragend in der BASCOM-Hilfe belesen.
(nach oben)

2.8 serielle Schnittstelle

Die meisten älteren Computer besitzen noch serielle Schnittstellen (z.B. Com1) mit denen AVRs dank Ihrer eingebauten UART spielend kommunizieren können. Neuere Computer besitzen diese Anschlüsse häufig nicht mehr, hier kann man sich aber z.B. mit einem USB Adapter behelfen. Diese Adapter sind entweder kleine Geräte oder sogar im Stecker eines Kabels eingebaut und melden sich beim Betriebssystem wie ein Com-Port an. Alle alten Beispiel- und Terminalprogramme kann man damit über USB weiterverwenden und meist noch mit höheren Übertragungsgeschwindigkeiten. Natürlich kann man die serielle Schnittstelle auch benutzen, um mehrere AVRs miteinander Daten austauschen zu lassen.

Während man mehrere AVRs einfach zusammenschalten kann muss man beachten, dass die Spannungen von genormten RS232-Anschlüssen (wie am PC) zu hoch (+/-12V) und zudem invertiert sind. Will man nur Daten vom PC empfangen will man aber auch Daten zum PC senden müsste man sich zuerst die +/-12V erzeugen und das Signal dann noch invertieren. Dafür gibt es fertige Bausteine wie den Max232, die das alles auf einmal erledigen.
Allerdings ist das Ganze etwas umständlich: USB hat 5V Pegel, für RS232-Kompatibilität werden die Signale im Wandler invertiert und auf +/- 12V umgesetzt. Diese Spannungen muß der Wandler aus den +5V auch erstmal selbst erzeugen. Auf eurer Platine macht Ihr das ganze mit Max232 o.ä. dann wieder rückwärts - keine schicke Lösung. Die +/-12V RS232-Pegel haben nur da Vorteile, wo das Übertragungskabel sehr lang sein muß - 20m und mehr.
Die Fa. FTDI-Chip bietet ICs an (z.B. FT232R), die sich am USB-Port auch als Com-Port anmelden - aber direkt 5V-Signale ausgeben die man direkt an den Controller anschließen kann. Die ganze Hin- und Herwandlung und Invertierung auf 12V-Signale entfällt, man spart sich Bauteile und es sind wesentlich höhere Kommunikationsgeschwindigkeiten möglich. Meistens kann man so auch gleich die 5V-Versorgungsspannung vom USB-Port für den Controller benutzen und die FTDI-Chips geben meist sogar einen 12MHz-Takt aus, womit man sich den Quarz am Controller auch noch sparen kann.

Leider gibt es diese Wandlerchips nur in SMD-Bauformen, die für Laien nicht einfach zu verbauen sind. Bei der Fa. Elmicro gibt es für weniger als 20,-€ fertige Bausteine mit den Chips von FTDI die sich einfacher verbauen lassen und es gibt sogar fertige USB-RS232-Wandlerkabel, die direkt nichtinvertierte 5V-Signale ausgeben. Diese Kabel kann man direkt an den Controller anschließen und spart sich die ganze Zusatzschaltung mit MAX232 o.ä. vollständig.

Daten auszutauschen ist mit Bascom ausgesprochen simpel. Zunächst gibt man dem AVR im Header eine Baudrate an und schon kann man mit einem einfachen "Print X" den Wert einer Variablen an den Rechner senden. Natürlich können über so eine Datenleitung nur Binärzahlen (Bytes) gesendet werden. Jeder Zahl ist deshalb ein Buchstabe/Sonderzeichen (Ascii-Tabelle) zugeordnet, den PC-Programme anzeigen, wenn der entsprechende Zahlenwert empfangen wird.
Bascom kümmert sich von selbst um die Umwandlung des Zahlenwertes in ASCII-Zeichen und sorgt auch dafür, daß nach der Zahl in die nächste Zeile gesprungen wird, indem es das Sonderzeichen mit der Ascii-Nummer 13 (CR) als Zeilenumbruch anhängt.
Man kann aber natürlich auch direkt Binärwerte oder Buchstaben/Texte senden:

$baud = 9600 'aktiviert die Schnittstelle und setzt die Baudrate auf 9600

Aber Achtung! Vorsicht!! Obacht!!!
Schreibt man das Baud-Statement in den Header wird nicht nur die UART initialisiert, sondern es werden außerdem gleich die endsprechenden RXD / TXD-Pins konfiguriert! D.h. Praktisch: Pin 2 wird als Eingang und Pin 3 als Ausgang gesetzt und die Digital-IOs PD0 und PD1 sind damit nicht mehr verfügbar! Wenn man die serielle Schnittstelle nicht benutzt sollte also auch auf das $baud-Statement im Header verzichtet werden.

Ein Beispiel für die Ausgabe von Werten über die serielle Schnittstelle:

x = 107
y = 110

Bascom-Befehl gesendete Werte Bildschirmanzeige
Print "x"
Print "y"
sendet binär die Werte 120 und 121 für die Buchstaben x und y
und anschließend den Wert 13 für Zeilenwechsel
x
y
Print x
Print y
zerlegt die Zahl 107 in 3 Ascii-Zeichen und sendet
diese nacheinander + Zeilenwechsel
107
110
Print x ;
Print y ;
das Semikolon verhindert den Zeilenwechsel 107110
Printbin x
Printbin y
sendet direkt die Variablenwerte ohne Umwandlung
(das Empfangsprogramm wandelt nach Ascii um)
k
n
Print "x = ";
Print x
Print
Print "y "
Printbin 61;
Print y
Beispiel für Kombinationen
(Ascii Code 61 entspricht Gleichheitszeichen;
Semikolon nach "y" wurde vergessen, Print ohne
weitere Angabe sendet nur einen Zeilenumbruch)
x = 107

y
=110

Tip: Will man zwischen anderen ASCII-Zeichen ein Sonderzeichen versenden, daß BASCOM nicht kennt, dann kann man den ASCII-Code des Sonderzeichens einfach in geschweiften Klammern in den String hineinschreiben, den man senden will.
Beispiel: Print "Hallo Welt!" sendet genau das selbe wie Print "Hallo{032}Welt{033}" weil die {032} dem Ascii-Code des Leerzeichens und {033} dem Ausrufungszeichen entspricht.
Wichtig: der Ascii-Code in den geschweiften Klammern muß immer dreistellig als Dezimalwert angegeben werden.

Wenn man Daten empfangen will ist das Ganze etwas aufwendiger. Trifft ein Byte beim AVR ein muß dieses möglichst schnell ausgelesen werden, weil erst dann der Speicher (Udr) frei ist um den nächsten Wert zu empfangen. Weil soetwas zeitkritisch ist ist im AVR wieder ein Interrupt vorgesehen (Urxc), mit dem automatisch beim Eintreffen eines Bytes ein Unterprogramm anspringen kann, um das Auslesen sofort zu erledigen.

Den RS232-Empfang im Header vorbereiten:

On Urxc Datenempfang ' Unterprogramm für RS232 Empfang angeben
Enable Urxc ' Interrupt aktivieren
   
Dim x As Byte 'beliebige Variable zum Auslesen des Wertes

und dann später im Programm:

Datenempfang: ' Label für Unterprogramm
x = Udr ' empfangenen Wert (Udr) in die Variable x auslesen
  ' weitere Befehle
Return ' Rückkehr zum Ursprungsprogramm

In der Variablen x steht jetzt der Wert, der zuletzt empfangen wurde. Trifft ein neues Byte ein wird der letzte Wert von x natürlich überschrieben. Deshalb sollte man - wenn mehrere Bytes nacheinander zu erwarten sind - x möglichst sofort im Unterprogramm weiterverarbeiten, oder in einem Array ablegen. Drückt man auf dem PC eine Taste, dann wird der zur Taste gehörige Ascii-Wert empfangen. Diesen kann man entweder direkt auswerten (If-Abfrage o.ä.) oder mit dem Befehl y = chr(x) einer anderen Variablen (String) wieder das Zeichen/den Buchstaben zuweisen. Häufig ist es aber für einzelne Zeichen (Steuertasten) sinvoll sich das zu sparen. Tragen sie in eines beider Felder einen Wert ein und klicken Sie ins andere um das Ergebnis zu erhalten:

Ascii-Zeichen:
(Buchstabe, Ziffer, Sonderzeichen)
Ascii-Wert:
(Dezimalzahl)

Für den Empfang bzw. zum Senden von Daten im Ascii-Format genügt auf dem PC grundsätzlich jedes Terminalprogramm. Wie die grunsätzlichen Einstellungen vorzunehmen sind habe ich exemplarisch für HyperTerminal beschrieben. Sicher gibt es sehr viel bessere Terminalprogramme (in Bascom ist auch eines enthalten), allerdings hat Hyperterminal den großen Vorteil, daß es auf vielen Windowsrechnern bereits vorinstalliert ist, da es zum Programmpaket gehört. D.h. ohne extra Programminstallation kann man so Daten seiner AVR-Schaltung an fast jedem Windowsrechner anzeigen lassen und auch senden. Die Anleitung findet Ihr hier: Hyperterminaleinrichtung
Sofern man eine PC-Programmiersprache beherrscht ist es natürlich schöner sich eigene Programme zu schreiben, mit denen man dann auch nicht nur einzelne Buchstaben oder Zahlen, sondern auch direkt die binären Werte verarbeiten kann.

Und noch etwas: der AVR generiert seine Baudrate indem er den Quarztakt teilt. Wie bei allen binären Teilen kann es da zu Rundungsfehlern kommen, die zumindest bei höheren Baudraten, also schnellem Datentransfer, zu Übertragungsfehlern führen können. Deshalb ist es sinnvoll hierbei keine "glatten" Taktfrequenzen zu verwenden, sondern "krumme" Quarze mit Frequenzen wie 3,6864 7,3728 oder 9,216 MHz, weil hier die AVR-Interne Taktteilung ohne Fehler aufgeht. Genauere Erklärungen dazu findet Ihr auf der Seite www.rowalt.de bzw. im AVR-Lehrbuch von Roland Walter.

(nach oben)

2.9 der EEprom

Der EEprom ist ein Speicher, in dem man Daten wie Variablen und Texte fest abspeichern kann, so, daß sie auch nach dem Abschalten der Betriebsspannung nicht verloren gehen und beim nächsten Einschalten des Gerätes wieder ausgelesen werden können. Wichtig zum Thema EEprom zu wissen ist, daß man nur einzelne Bytes abspeichern kann. D.h. um einen Text zu speichern muß man z.B. Buchstabe für Buchstabe die jeweiligen Ascii-Zahlen speichern und beim nächsten Programmstart wieder zu einem Text zusammensetzen. Das speichern und auslesen ist denkbar simpel und erfordert keinerlei Konfiguration oder Aktivierung im Header:

Writeeeprom x , 1 ' Speichert den Wert der Variablen x in Speicherzelle 1
   
Readeeprom x , 1 ' liest Speicherzelle 1 aus und weist den Wert der Variablen x zu

Es können nur Varablen des Typs Byte direkt abgespeichert werden, bei Variablentypen die mehrere Bytes benötigen (z.B. Word) muß man den Wert zunächst in einzelne Bytes zerlegen, diese einzeln abspeichern und später, beim Auslesen, wieder zusammensetzen:

Dim x As Byte ' x als Byte definieren
Dim y As Word ' y als Word definieren
y = 899 ' y beliebigen Wert zuweisen (z.B. ADC Wert o.ä.)

In einer als Byte vorbereiteten Variablen x kann man kurzzeitig die einzelnen Bytes vom Word y zwischenspeichern. Das Kombinieren des Teilens und Speicherns in einer Befehls-Zeile ist bei Bascom nicht möglich:

x = High(y) ' weist x das MSB (High-Byte) des Words y zu
Writeeeprom x , 1 ' speichert x in Zelle 1
x = Low(y) ' weist x das LSB (Low-Byte) des Words y zu
Writeeeprom x , 2 ' speichert x in Zelle 2

Das Word y ist so auf die EEprom-Speicherzellen 1 und 2 aufgeteilt. Wenn man verstanden hat, wie Binäre Zahlen funktionieren (Zahlenscript gelsen?) dann ist es simpel diese 2 Bytes später wieder zu einem Wert des Typs Word zusammenzusetzen:

Readeeprom x , 1 ' Speicherzelle 1 (High-Byte) in die Variable x auslesen
y = x * 256 ' bitte selbst nachdenken...
Readeeprom x , 2 ' Speicherzelle 2 (Low-Byte) in die Variable x auslesen
y = y + x  

y hat jetzt wieder den ursprünglichen Wert, der vorher zerlegt abgespeichert wurde. Natürlich muß man die Adressen der Speicherzellen nicht unbedingt direkt angeben, sondern kann auch hierfür Variablen verwenden.
Wichtig zu wissen ist, daß das Lesen und Beschreiben des EEproms für µC-Verhältnisse recht lange benötigt und vorallem, daß der EEprom nicht beliebig of beschrieben werden kann. Es empfiehlt sich also das Lesen/Schreiben nicht innerhalb einer Schleife ständig zu wiederholen, sondern die Daten nur wenn es nötig ist einmal zu speichern (z.B. auf Tastendruck im Unterprogramm) und die Daten z.B. nur einmal beim Starten vor der Hauptschleife auszulesen.

(nach oben)

http://www.bunbury.de/Technik/avr/bascom.htm


3. Beschaltung Sensorwerte messen

Wenn man einen Mikrocontroller programmiert hat ist das natürlich nur die halbe Miete. TTL-ICs und Mikrocontroller wie der Mega8 können meist nur 5V-Signale einlesen und ausgeben und der Ausgangsstrom ist auf wenige mA beschränkt.

Was ist zu tun, um einen Motor mit 12V Spannung und 1A Strom zu steuern?
...um ein Sensorsignal mit 0-10V einzulesen?
...um zu kleine Signale von wenigen mV zu verstärken?
...um einen PC anzuschließen?
...um einen Modellbau-Empfänger oder ein Modellbauservo anzuschließen?

Dazu finden Sie am Ende der Seite einen Link, indem die Beschaltung von TTL-Schaltkreisen im Allgemeinen erklärt wird und diese Schaltungen funktionieren natürlich auch am Mega8.

Vorab sollten Sie sich aber folgende Betriebsdaten des Mega8 einprägen oder besser notieren!
Sie werden diese beim Basteln oder Berechnen von Bauteilen immer wieder benötigen:

Betriebsspannung: +5V
max. Eingangs-/Ausgangsspannungen von Signalen: +5V
max. Ausgangsstrom pro Pin: 40mA
max. Gesamtstrom aller aktiven Ausgangspins: 200mA

Auch wenn einem Ausgangsströme von 40mA erstmal als nicht sehr viel erscheinen mögen ist der Mega8 im Vergleich zu seiner Schaltkreis-Verwandschaft geradezu üppig ausgestattet, viele Schaltkreise sind nichtmal in der Lage den Strom für eine LED am Ausgang zu liefern.

http://www.bunbury.de/Technik/avr/beschaltung.htm

http://www.bunbury.de/Technik/avr/bascom.htm

*********************************************************

4TAP  4-Teile-AVR-Programmer  am COMx-PORT

4TAP - ein AVR "bitbanging" Programmer für die serielle Schnittstelle,
bestehend aus 3 Widerständen und einem Transistor.


Ich wollte endlich auch mal Mikrocontroller programmieren, aber mit möglichst geringem Anfangswiderstand. Ohne Bootloader, ohne Entwicklungsplatine, sondern etwa so wie im "Lernpaket Mikrocontroller" von Franzis. Das Programmieren und Flashen sollte aber komfortabler sein, am liebsten in Basic. Der Mega8-ISP-Programmer vom selben Autor wie das Lernpaket (Burkhard Kainka), kam der Sache schon ziemlich nahe. Allerdings musste für den Einsatz von AVRdude dessen  Konfigurationsdatei editiert werden. Außerdem muss immer die serielle Schnittstelle geöffnet sein, weil ohne einen HIGH-Pegel an RTS der Controller in den Reset-Zustand geht. Herausgekommen ist der "4-Teile-AVR-Programmer", kurz 4TAP.

http://www.franksteinberg.de/4TAP.htm






DIN A4  ausdrucken

*********************************************************
Impressum: Fritz Prenninger, Haidestr. 11A, A-4600 Wels, Ober-Österreich, mailto:schaltungen@schaltungen.at
ENDE

Comments