Anzeige:

Digitale Lösung für Schaltungen / Problem?

Hier finden sie die archivierten Beiträge des alten PHPBB Forums von www.loetstelle.net

Von gerold am 10.03.2008 18:15

Hallo!

Dieses Beispiel kann man natürlich auch ein wenig ausbauen:

Code:
'es handelt sich um einen ATmega8
$regfile = "M8def.dat"

'der eingebaute RC-Oszillator läuft mit 1 Mhz
$crystal = 1000000

'im Speicher werden für den Hardware-Stack 32 Byte reserviert
$hwstack = 32

'im Speicher werden für den Software-Stack 10 Byte reserviert
$swstack = 10

'im Speicher werden für den Frame 40 Byte reserviert
$framesize = 40

'PB1 ist Ausgang. Die anderen Pins sind Eingänge
Ddrb = &B00000010


Do
   'PB1: Signal einschalten (HIGH)
   Portb.1 = 1

   'Eine Sekunde Warten
   Wait 1

   'PB1: Signal ausschalten (LOW)
   Portb.1 = 0

   'Eine Sekunde Warten
   Wait 1
Loop


'Ende des Programms
End

Und hier sieht man auch wie ein Programm normalerweise aufgebaut ist. Jedes Programm hat eine MainLoop -- eine Hauptschleife. Das Programm in der Hauptschleife wird so lange wiederholt, bis entweder Reset gedrückt wird oder der µC keinen Strom mehr bekommt.

mfg
Gerold
Smile

Größere Last über einen Transistor anschließen

Von gerold am 11.03.2008 08:01

Hallo!

Wenn man nicht nur eine Low Current LED anschließen möchte, dann muss man das Ausgangssignal verstärken. Das Einfachste ist, wenn man einen Transistor zum Verstärken verwendet.

Folgender Schaltplan zeigt auf, wie man eine normale 20 mA LED an den µC anschließen kann.



R3 habe ich im Schaltplan mit "1k - 10k" angegeben. Das hat einen Grund.

Ist ein als Ausgang definierter Pin des µC auf LOW geschaltet, dann zieht dieser Pin gegen GND. Das hat den Vorteil, dass man die Basis des Transistors nicht zusätzlich über einen Widerstand gegen GND ziehen muss um diesen zu entstören. Bei einem 2N2222-Transistor genügt ein 10k-Widerstand um die LED in voller Stärke leuchten zu lassen. Aber bei 10k ist die Basis des Transistors nicht so stark entstört wie es bei einem 1k-Widerstand der Fall wäre.

Nimmt man 10k als Basiswiderstand, dann braucht die Schaltung sehr wenig Strom, ist aber nicht so gut entstört. Nimmt man 1k als Basiswiderstand, dann braucht die Schaltung mehr Strom, ist dafür aber gut entstört.

Man muss also von Fall zu Fall entscheiden, wie wichtig die Entstörung der Transistor-Basis ist und kann mit diesem Wissen zwischen 1k und 10k variieren. Außerdem wird es ja nicht so oft vorkommen, dass man mit dem Finger direkt an die Transistor-Basis greift. Wink

Und so kann man auch größere Last an den µC anschließen:
http://www.strippenstrolch.de/1-6-8-relais-mit-kleinem-strom-ansteuern.html

Je mehr Strom die Last zieht, desto kleiner muss der Basiswiderstand sein. 10k ist bei einem Relais schon ziemlich hoch.

mfg
Gerold
Smile

Von gerold am 11.03.2008 08:26

Hallo passat2001!

Im nächsten Beitrag möchte ich noch erklären, wie man Schalter an den µC anschließen kann.

Danach möchte ich näher auf deine Aufgabenstellung eingehen. Könntest du uns vielleicht ein wenig genauer erklären, was du genau machen möchtest. Welche Signale in welcher Stärke und in welcher Schaltgeschwindigkeit bekommst du und was soll damit zu welchem Zeitpunkt geschaltet werden?

mfg
Gerold
Smile

Es geht auch billiger

Von gerold am 11.03.2008 14:16

Hallo!

Ich muss doch noch einen Beitrag zwischenschieben. Mir ist aufgefallen, dass sich zwar viele für die Mikrocontrollerprogrammierung interessieren, sich aber die von mir beschriebene Basisausstattung nicht leisten können.

Ich bin von der Ausstattung ausgegangen, die am wenigsten Probleme macht und dem Lernenden am meisten hilft. Dafür ist nun mal ein Buch notwendig, das nicht nur die Grundlagen vermittelt und dafür braucht man (außer man hat wirklich viel Phantasie) auch das zugehörige Experimentierboard. Ich spreche vom "AVR - Mikrocontroller Lehrbuch".

Natürlich kann man die Mikrocontrollerprogrammierung auch ohne diese Ausstattung lernen. Man braucht aber erheblich länger dafür, da man sich die Informationen aus dem Internet zusammensuchen muss und nicht Kapitel für Kapitel *nur* neues lernt.

Weiters kann man zur Not auch auf den von mir vorgeschlagenen mySmartUSB-Programmer verzichten. Es gibt Programmer für den Parallelport und für den Seriellen Port, die man sich selber zusammenlöten kann. Wenn man sich das "ATMEL Evaluations-Board Version 2.0" von Pollin besorgt, dann hat man so einen Seriellen Programmer sogar mit an Board. Man kann das Programm damit zwar nicht direkt aus Bascom heraus zum µC übertragen, aber die von Bascom erzeugten HEX-Dateien können mit dem Programm "PonyProg" http://www.lancos.com/prog.html zum µC übertragen werden.

Das ist zwar für Vielprogrammierer nicht angenehm und auf keinen Fall schnell, aber es ist billig.

Ich hoffe, damit mehr Hobby-Elektroniker zum Einstieg in die µC-Programmierung zu bewegen.

mfg
Gerold
Smile

PS: Das sollte man aber auch wissen: http://www.roboternetz.de/phpBB2/viewtopic.php?t=38913

.

Von passat2001 am 11.03.2008 18:02

Ich lese natürlich auch noch mit. Konnte nur leider heute erst die Teile bestellen...

Schalter an den µC anschließen

Von gerold am 11.03.2008 19:59

Hallo!

Letztens habe ich erklärt, wie man über ein digitales Signal des µC eine LED oder ein Relais ansteuern kann. Heute ist es so weit, dass ich in die andere Richtung gehen möchte. Wie schließt man einen Schalter an?

Es gibt zwei grundsätzliche Möglichkeiten. Entweder der Schalter zieht gegen VCC oder er zieht gegen GND. Beides lässt sich detektieren. Und was passiert wenn der Schalter nicht gedrückt wird? Das wird oft nicht bedacht. Und erst heute (wie peinlich) ist es mir selber passiert, dass ich mich nicht darum gekümmert habe. Und statt 10 Hz hatte ich schwankende 2600 Hz an einem Eingang und wusste nicht warum. Smile

Wenn der Schalter gegen VCC zieht, dann sollte man den Eingang über einen PullDown-Widerstand gegen GND ziehen. So ist sicher gestellt, dass am Eingang LOW anliegt und erst wenn der Schalter gedrückt wird zu HIGH wird. Zieht der Schalter gegen GND, dann sollte ein PullUp-Widerstand gegen VCC ziehen.

Und wenn man Bauteile sparen möchte, dann kann man den in den µC eingebauten PullUp-Widerstand softwaremäßig aktivieren. Es gibt also für jeden möglichen Eingangspin auch die Möglichkeit, einen PullUp-Widerstand zu aktivieren. Dieser ist bei den AVRs zwischen 20 und 50 kByte groß.

So sieht es aus, wenn der Schalter gegen VCC zieht:


So sieht es aus, wenn der Schalter gegen GND zieht:


Zwar hat der Reset-Eingang auch einen PullUp-Widerstand eingebaut, aber beim Reset machen wir eine Ausnahme und beschalten ihn trotzdem zusätzlich noch mit einem externen PullUp-Widerstand.

Es gibt mehrere Möglichkeiten, um festzustellen, ob der Taster gedrückt wird oder nicht. Die einfachste ist die, den Status des Eingangspins abzufragen. Dieses kleine Beispielprogramm steuert zwei LEDs an. Im Ausgangszustand leuchtet die LED1. Drückt man den Taster dann leuchtet die LED2.

Dieses Beispiel geht davon aus, dass der Taster den Eingangspin gegen VCC zieht.

Code:
$regfile = "M8def.dat"
$crystal = 1000000
$hwstack = 32
$swstack = 10
$framesize = 40


'LED1 an PB1
Led1 Alias Portb.1
Config Led1 = Output

'LED2 an PB2
Led2 Alias Portb.2
Config Led2 = Output

'TASTER1 an PD2
Taster1 Alias Pind.2
Config Pind.2 = Input


Do
   If Taster1 = 1 Then
      Led1 = 0
      Led2 = 1
   Else
      Led1 = 1
      Led2 = 0
   End If
Loop


End

Und so sieht es aus, wenn man mit dem Taster den Eingangspin gegen GND zieht. Es wird der interne PullUp-Widerstand aktiviert um den Eingang in einem definierten Zustand zu halten. Das Einschalten des internen PullUp-Widerstand: Zuerst wird der Pin als Eingang definiert und dann setzt man den Pin auf HIGH. So als wäre dieser ein Ausgang. Aber statt dass am Pin ein HIGH angelegt wird, wird damit der PullUp-Widerstand aktiviert.

Code:
$regfile = "M8def.dat"
$crystal = 1000000
$hwstack = 32
$swstack = 10
$framesize = 40


'LED1 an PB1
Led1 Alias Portb.1
Config Led1 = Output

'LED2 an PB2
Led2 Alias Portb.2
Config Led2 = Output

'TASTER1 an PD2
Taster1 Alias Pind.2
Config Pind.2 = Input
Portd.2 = 1       'PullUp-Widerstand einschalten


Do
   If Taster1 = 0 Then
      Led1 = 0
      Led2 = 1
   Else
      Led1 = 1
      Led2 = 0
   End If
Loop


End

Du hast sicher schon bemerkt, dass noch etwas hinzugekommen ist. Mit ALIAS kann man einer Variable einen zusätzlichen Namen geben. Schlüssige Namen erleichtern das Programmieren und sollten oft eingesetzt werden.

Versuche doch mal zum Test diese Zeile aus dem Code raus zu nehmen:
Code:
Portd.2 = 1       'PullUp-Widerstand einschalten

Drücke nach dem Übertragen des Programms mehrmals den Taster. Dann weißt du was es bedeutet, den PullUp-Widerstand zu vergessen. Wink

Fragen?

mfg
Gerold
Smile

Variablen

Von gerold am 12.03.2008 08:53

Hallo!

In diesem Beitrag geht es wieder um reine Theorie. Aber bitte trotzdem durchlesen, da dieses Thema sehr wichtig ist. Es geht um Variablen.

Was ist eine "Variable"? In der µC-Programmierung ist eine Variable ein Name für einen Speicherbereich. Außerdem ist in Bascom an die Variable auch noch der Datentyp gebunden, der in dem Speicherbereich gespeichert werden kann.

In Bascom gibt es mehrere mögliche Datentypen.

- BIT: besteht aus nur einem Bit und kann 0 oder 1 enthalten
- BYTE: besteht aus 8 Bit und kann Ganzzahlen von 0 bis 255 enthalten
- WORD: besteht aus 16 Bit und kann Ganzzahlen von 0 bis 65535 enthalten
- INTEGER: besteht aus 16 Bit und kann Ganzzahlen von -32768 bis +32767 enthalten
- LONG: besteht aus 32 Bit und kann Ganzzahlen von -2147483648 bis 2147483647 enthalten
- SINGLE: besteht aus 32 Bit und kann Fließkommazahlen von 1,5 x 10^–45 bis 3,4 x 10^38 enthalten
- DOUBLE: besteht aus 64 Bit und kann Fließkommazahlen von 5,0 x 10^–324 bis 1,7 x 10^308 enthalten
- STRING: Dieser Datentyp kann Text mit der Länge von bis zu 254 Zeichen enthalten. Dafür wird im Speicher immer ein Zeichen mehr als die Länge des Textes benötigt, da der Text immer mit einem 0-Byte abgeschlossen wird.

Man muss Bascom mitteilen, welche Variablen mit welchem Datentyp man benutzen möchte. Das passiert mit dem Befehl DIM und sieht z.B. so aus:

Code:
DIM my_bit_var as BIT
DIM my_byte_var as BYTE
DIM my_byte_array(3) as BYTE
DIM my_word_var as WORD
DIM my_single_var as SINGLE
DIM my_string_var as STRING * 10

Die Besonderheit des STRING-Datentyps ist die, dass man mit ``*`` die Länge des Textes angeben kann. ``my_string_var`` braucht im Speicher 11 Byte, da noch ein 0-Byte dazu kommt um den Text abzuschließen.

Dann gibt es noch eine Besonderheit. Die Variable ``my_byte_array`` wurde als Array definiert. Damit wurden intern drei Speicherbereiche mit dem gleichen Namen reserviert. Und man kann auf die einzelnen Speicherbereiche über den in Klammern geschriebenen Index zugreifen. ``my_byte_array(1), my_byte_array(2), my_byte_array(3)``. Das ist von Vorteil, wenn man sich später Schreibarbeit sparen möchte und immer wiederkehrende Aufgaben in einer Schleife abarbeiten möchte. Aber das ist jetzt noch nicht wichtig.

So schreibt man einen Wert in eine Variable:
Code:
my_bit_var = 1
my_byte_var = 200
my_byte_array(1) = 10
my_byte_array(2) = 20
my_byte_array(3) = 30
my_word_var = 20000
my_single_var = 10.5
my_string_var = "Hallo Welt"

Man kann einer Variable auch den Wert einer anderen Variable übergeben. Das sieht so aus:
Code:
my_word_var = my_byte_var
my_byte_array(3) = my_byte_var
my_byte_array(2) = my_byte_array(1)

Man muss aber aufpassen! Man darf einer Variable keinen Wert übergeben, der nicht in die Variable rein passt. Schreibt man den Wert einer WORD-Variable in eine BYTE-Variable, dann werden nur die unteren 8 Bit übernommen. Die oberen 8 Bit werden einfach abgeschnitten.

Dieser Code funktioniert:
Code:
my_word_var = 100
my_byte_var = my_word_var

Die Zahl 100, in einen Code aus Nullen und Einsen (Binärsystem) umgewandelt, sieht so aus:
Code:
1100100

Das sind 7 einzelne Bits. Diese 7 Bits haben in einer BYTE-Variable Platz, da der Speicherbereich für ein Byte 8 Bit groß ist.

Dieser Code funktioniert nicht:
Code:
my_word_var = 1000
my_byte_var = my_word_var

Die Dezimalzahl 1000, umgewandelt in eine Binärzahl (0/1), sieht so aus:
Code:
1111101000

Das sind 10 einzelne Bits. 10 Bits haben nicht mehr in einer BYTE-Variable Platz. Es werden die linken 2 Bit abgeschnitten. Im Speicher steht jetzt:
Code:
11101000

Wenn man diese Binärzahl in eine Dezimalzahl umwandelt, dann kommt die Dezimalzahl ``232`` dabei raus. In der Variable steht jetzt der Wert 232 und nicht wie erwartet der Wert 1000.

Das Binärsystem und die Umrechnung von Binär nach Dezimal und umgekehrt erkläre ich hier nicht. Das wird sowiso in vielen Computerbüchern erklärt und Wikipedia hat dazu auch noch etwas zu sagen:
http://de.wikipedia.org/wiki/Dualsystem

Umrechnung von Zahlensystemen:
http://www.arndt-bruenner.de/mathe/scripts/Zahlensysteme.htm

Der Windows-Taschenrechner kann verschiedene Zahlensysteme umwanden. Man muss ihn dafür nur in die wissenschaftliche Darstellung umschaltet.

Da wir ab jetzt in fast jedem weiteren Beispielprogramm mit Variablen arbeiten werden, macht es früher oder später garantiert "Klick" und du wirst verstehen. Wink

mfg
Gerold
Smile


PS: Für die Wissenshungrigen unter uns: http://avrhelp.mcselec.com/index.html?language_fundamentals.htm

.

Schalter an den µC anschließen - Fortsetzung

Von gerold am 12.03.2008 18:00

Hallo!

Es gibt noch mehr Möglichkeiten wie man auf einen Schalter reagieren kann. Hier ist die nächste Möglichkeit: BITWAIT

BITWAIT ist ein Befehl der so lange an einer Stelle wartet, bis die übergebene Variable oder ein Pin auf 0 oder auf 1 gesetzt wird. Dieser Befehl blockiert das gesamte Programm. Dessen muss man sich bewusst sein.

Hier der zugehörige Schaltplan:


Und hier das Beispiel:

Code:
$regfile = "M8def.dat"
$crystal = 1000000
$hwstack = 32
$swstack = 10
$framesize = 40


'LED1 an PD7
Led1 Alias Portd.7
Config Led1 = Output

'LED2 an PD6
Led2 Alias Portd.6
Config Led2 = Output

'TASTER1 an PD2
Taster1 Alias Pind.2
Config Pind.2 = Input
Portd.2 = 1       'PullUp-Widerstand einschalten

Dim Status As Bit


Do
   'Warten bis der Taster1 gegen GND zieht
   Bitwait Taster1 , Reset
   'Warten bis der Taster1 gegen VCC zieht
   Bitwait Taster1 , Set

   'Wenn die Variable Status...
   If Status = 0 Then
      '...auf 0 gesetzt ist, dann LEDs wechseln...
      Led1 = 0
      Led2 = 1
      '...und Status-Variable auf 1 setzen.
      Status = 1
   Else
      '...auf 1 gesetzt ist, dann LEDs wechseln...
      Led1 = 1
      Led2 = 0
      '...und Status-Variable auf 0 setzen.
      Status = 0
   End If
Loop


End

Wenn man den Taster drückt, dann wechseln die LEDs hin und her. Experimentiere damit ein wenig. Lasse doch mal die Zeile ``Bitwait Taster1 , Set`` weg und schau was dann passiert. Versuche es dir zu erklären.

Und eines dürfte bei diesem Beispiel ziemlich schnell auffallen. Wenn man den Taster drückt, dann wird normalerweise die LED gewechselt. Aber ab und zu passiert nichts oder es blinkt nur kurz auf.

Die meisten Taster oder Schalter "prellen". Das kommt daher, dass der Taster beim Schalten ein wenig nachschwingt. Das Signal eines Tasters oder Schalters ist beim Schalten nicht rein.

Das kann man auf der Hardwareseite umgehen, wenn man einen kleinen Keramikkondensator (sagen wir mal 10 nF -- je nach Qualität des Schalters muss man diesen Wert evt. ein wenig erhöhen) parallel zum Taster schaltet. Man kann dieses Problem auch softwareseitig aus der Welt schaffen. Aber darauf möchte ich erst später eingehen.

Hier der Schaltplan mit entprelltem Taster:


ACHTUNG! Wenn die Schaltung Strom bekommt, dann läd sich der Kondensator C3 über den internen PullUp-Widerstand auf. Das bedeutet, dass in diesem Moment PD2 nach GND gezogen wird. Sobald der Kondensator aufgeladen ist, zieht der PullUp PD2 nach VCC. Da die zwei Prüfungen mit BITWAIT so ziemlich das Erste sind was ausgeführt wird, wird die Schleife einmal durchlaufen ohne einen Tastendruck abzuwarten. Möchte man das vermeiden, dann sollte man mit ``WAITMS`` ein paar Millisekunden warten bevor man die MainLoop loslegen lässt.

mfg
Gerold
Smile

Von gerold am 12.03.2008 18:29

Ohne Worte:



Code:
$regfile = "M8def.dat"
$crystal = 1000000
$hwstack = 32
$swstack = 10
$framesize = 40


'LED1 an PD7
Led1 Alias Portd.7
Config Led1 = Output

'LED2 an PD6
Led2 Alias Portd.6
Config Led2 = Output

'LED3 an PD5
Led3 Alias Portd.5
Config Led3 = Output

'TASTER1 an PD2
Taster1 Alias Pind.2
Config Pind.2 = Input
Portd.2 = 1       'PullUp-Widerstand einschalten

Dim Status As Byte


Do
   Bitwait Taster1 , Reset
   Bitwait Taster1 , Set

   If Status = 0 Then
      Led1 = 1
      Led2 = 0
      Led3 = 0
      Status = 1
   Elseif Status = 1 Then
      Led1 = 0
      Led2 = 1
      Led3 = 0
      Status = 2
   Else
      Led1 = 0
      Led2 = 0
      Led3 = 1
      Status = 0
   End If
Loop


End

Was macht dieses Programm?

mfg
Gerold
Smile

Von gerold am 12.03.2008 20:26

Hallo!

Ich brauche Rückmeldungen, damit ich weiß ob ich auf dem richtigen Weg bin. Bitte teilt mir mit ob es Probleme gibt oder ob alles bis jetzt problemlos läuft.

lg
Gerold
Smile

PS: Sobald hier Rückmeldungen kommen, schreibe ich den nächsten Beitrag. Smile

Anzeige: