7. IF-Funktion und alltägliche Probleme, Interrupts

Anleitungen für "hausgemachte" LED Projekte

Moderator: T.Hoffmann

Benutzeravatar
Pehu
Mega-User
Mega-User
Beiträge: 469
Registriert: Mi, 01.11.06, 19:33
Kontaktdaten:

Do, 11.01.07, 22:27

So, nun die Fortsetzung.
Manche Sätze, oder hinter manche Begriffe sind Apostrophen zufinden. Weil das Board irgendwie auf die Befehle reagiert und einen Fehler bringt...

Verkürzter Befehl für Deklaration der I/Os-Pins (Eingänge/Ausgänge)

Im Tutorial 6. Grundstruktur und ein paar Grundbefehle (Basic-Sprache) wurde über das Deklarieren der I/Os-Pins (Eingänge/Ausgänge) geschrieben.
Da wurde jeder einzelner I/O-Pin mit dem Befehl "Config PinX.X = Output" deklariert.
Möchte man 10 I/O-Pins deklarieren, so müsste man 10 mal den oberigen Befehl eingeben.

Es geht auch einfacher und zwar mit einem Befehl, mit dem man gleich eine Pinreihe (z.B:PC0-PC5, PD0-PD7,...) deklarieren kann:

DdrX = &BYYYYYY <- X = für den Buchstaben der Pinreihe und Y die dazugehörige Nummer zum Buchstaben der Pinreihe. (Das erste Y von Links steht für 0, das zweite Y von Links für 1,... ). Wenn das Y eine 1 ist, wird der Pin als Ausgang deklariert und bei 0 als Eingang.

Hier Klicken für Pinbelegung des Atmega8.


Hier ein Beispiel mit der Pinreihe "PC0-PC5":
1014_tut2_1.gif
1014_tut2_1.gif (4.02 KiB) 29830 mal betrachtet
IF-Funktion

"IF" heißt auf Deutsch übersetzt "Wenn". Also eine Wenn-Funktion.
Wenn eine angegebene Bedingung erfüllt wird, soll er folgendes ausführen, ansonsten folgendes ausführen.

Der Grundaufbau der 'IF-Funktion:

Code: Alles auswählen


IF (Bedingung) Then

Else

End if

Im letzten Tutorial, habe wir einen I/O-Pin als Eingang deklariert, bei dem ein Taster hängt. Jedoch dem Taster bzw. I/O-Pin keine Funktion zugewiesen. Hiermit werden wir dem Taster1 eine Funktion verpassen:

Code: Alles auswählen


If Taster1 = 1 Then 'Wenn am Taster1 High-Pegel liegt, sprich Taster1 gedrückt, dann die Befehle unten ausführen
Led1 = 1
Led2 = 1 
Waitms 500 
Led1 = 0
Led2 = 0
End If 'Hier endet die IF-Funktion

Was passiert:
Wenn am Taster1 High-Pegel anliegt bzw. Taster1 gedrückt wird, dann werden Led1 und Led2 für 0,5 Sek. gemeinsam leuchten.

Wenn wird unseren Code vom vorherigen Tut ergänzen, sprich dem Taster1 eine Funktion zuordnen, sieht unser gesamter Code folgender Maßen aus
(jedoch gibt es ein Problem!!!)
:

Code: Alles auswählen

$regfile = "m8def.dat"

$crystal = 1000000

Config Pind.5 = Output
Config Pind.6 = Output
Config Pind.2 = Input

Taster1 Alias Pind.2
Led1 Alias Portd.5
Led2 Alias Portd.6

Do

If Taster1 = 1 Then
Led1 = 1
Led2 = 1
Waitms 500
Led1 = 0
Led2 = 0
End If

Led1 = 1
Waitms 1000
Led1 = 0
Waitms 1000
Led2 = 1
Waitms 1000
Led2 = 0
Waitms 1000

Loop'
Nun zum Problem:

'Überträgt man den oberen Code zum Microntroller leuchten die Leds abwechseln hin und her, wie mit dem Code vom vorherigen Tut.'

Nun wenn man den Taster1 drückt, reagiert er nicht immer darauf.

'Der Grund ist (der Code zum Grund befindet sich unten):'

Er arbeit die Befehle im Hauptprogramm (innerhalb Do & Loop') ab und das endlos und wenn er im roten markierten ist Z.B.: in der 1 Sek. Pause und wir drücken auf Taster1, dann reagiert er nicht darauf.

Weil er nicht gerade die 'IF-Funktion durchführt (grün markiert).

'Sprich wir müssen im richtigen Moment den Taster1 drücken damit er reagiert und zwei Leds einmal gleichzeitig blinken lässt. Oder man hält den Taster1 gedrückt, bis er wieder zur IF-Funktion angelangt.:

Do

If Taster1 = 1 Then
Led1 = 1
Led2 = 1
Waitms 500
Led1 = 0
Led2 = 0
End If

Led1 = 1
Waitms 1000
Led1 = 0
Waitms 1000
Led2 = 1
Waitms 1000
Led2 = 0
Waitms 1000


Loop'


'Nun gibt es zwei Lösungsmöglichkeiten:'

'1. Taster mit Interrupt'
'2. Timer der in Intervall ein Interrupt auslöst, welches dann ein Unterprogramm aufruft mit der If-Funktion'

'Fangen wir mit 1. Taster mit Interrupt an'


Interrupt'


Auf Deutsch übersetzt bedeutet Interrupt' "Unterbrechung".
Der Microcontroller hat verschiedene 'Interrupt-Quellen. Z.B.: Durch Auslösen eines Tasters, Timerüberlauf, ...
Der Atmega8 hat zwei I/O-Pins, die man als Interrupt' einsetzen kann. Das wäre PD2 (INT0) und PD3 (INT1).
Siehe Pinbelegung des Atmega8.



'Das heißt sobald ein Interrupt ausgelöst wird, wird das Hauptprogramm sofort unterbrochen und das ausgewählte Unterprogramm wird ausgeführt. Nach dem das Unterprogramm durchgelaufen ist, kehrt es an der Stelle des Hauptprogramms zurück, an der es vorhin unterbrochen worden ist.
'Hierzu müssen wir folgendes im Code ergänzen:

Code: Alles auswählen


Config Int0 = Rising 'Hier konfigurieren unseren Int0 (PD2), Rising bedeutet wenn es ansteigt, sprich von Low auf High
Enable Interrupts 'Einschalten der Interrupts
Enable Int0 'Einschalten des Int0 (PD2)
On Int0 Unterprogramm 'Hier wird das Unterprogramm angegeben, wenn es Interrupt stattfindet und es wird zum "Unterprogramm" geleitet, den Namen kann natürlich selber frei bestimmen

'Dann noch die IF-Schleife in unserem Hauptprogramm entfernen.'

'Und ein Unterprogramm (muss unter dem Hauptprogramm bzw. "Loop" eingegeben werden):'

Code: Alles auswählen

Unterprogramm:  'Name des Unterprogramms'
Led1 = 1
Led2 = 1
Waitms 500
Led1 = 0
Led2 = 0
Return  'zurück zu der Stelle des Hauptprogramms wo es unterbrochen wurden ist.'
'Dann sollte unser ganzer Code folgender Maßen aussehen:'

Code: Alles auswählen

$regfile = "m8def.dat"

$crystal = 1000000

Config Pind.5 = Output
Config Pind.6 = Output
Config Pind.2 = Input

Config Int0 = Rising
Enable Interrupts                                           'einschalten der Interrupts
Enable Int0
On Int0 Unterprogramm

Taster1 Alias Pind.2
Led1 Alias Portd.5
Led2 Alias Portd.6

Do

Led1 = 1
Waitms 1000
Led1 = 0
Waitms 1000
Led2 = 1
Waitms 1000
Led2 = 0
Waitms 1000

Loop'

Unterprogramm:

Led1 = 1
Led2 = 1
Waitms 500
Led1 = 0
Led2 = 0

Return
'Das Hauptprogramm wird endlos abgearbeitet, sobald ein Interrupt' kommmt, wird das Unterprogramm geöffnet und die Leds leuchten gemeinsam, dann kehrt es zum Hauptprogramm zurück. 'Damit haben wir sichergestellt, das unser Microcontroller immer auf unseren Taster reagiert.'

'2. Die zweite Lösung findet Ihr im nächsten Thema. Weil ich ständig Fehlermeldungen vom Board zurückkriege und fast alles in Apostroph schreiben muss und es immer schlimmer wird...'
Zuletzt geändert von Pehu am Sa, 13.01.07, 12:23, insgesamt 4-mal geändert.
Andy
Hyper-User
Hyper-User
Beiträge: 1284
Registriert: Mi, 17.05.06, 13:03

Do, 11.01.07, 22:38

Hmmm...hast du Punkt 7 übersprungen?...weil du jetzt mit Punkt 8 anfängst?...oder soll dem Punkt 7 ein gesondertes Thema vorbehalten sein, welches du dann nur noch nicht angefangen hast? :wink:
Benutzeravatar
Pehu
Mega-User
Mega-User
Beiträge: 469
Registriert: Mi, 01.11.06, 19:33
Kontaktdaten:

Do, 11.01.07, 22:44

@Andy Upps, Danke für den Hinweis. Habs geändert. :wink:
Andy
Hyper-User
Hyper-User
Beiträge: 1284
Registriert: Mi, 17.05.06, 13:03

Fr, 12.01.07, 13:37

Hi...nochmals.
Wie sieht denn die Programierung in PWM (Phasen Weiten Modulation) aus, um die LED´s langsam an und wieder aus zu schalten (Dimmfunktion)
Hatte da mal ein Beispiel gehabt, war aber nicht mit dem Bascom Kompatibel, weil er mit den Befehlen nichts anfangen konte. (Ich Denke mal das wurde damals in C geschrieben)
Benutzeravatar
Fightclub
Post-Hero
Post-Hero
Beiträge: 5114
Registriert: Mi, 01.03.06, 18:40

Fr, 12.01.07, 13:41

@pehu: wenn du dich über das board beschweren willst dann darfst du das gerne tun. und zwar auf http://www.phpbb.com. Chris, Olaf, Neo und ich sind da leider die falsche Adresse für. Auch wenn ich den Fehler nicht selbst gesehen habe und eine ferndiagnose immer sehr schwierig ist würde ich aufgrund dessen was du berichtest eher sagen dass der fehler am server lag (ausgelastet, wartung, oder sonst was) oder an deiner verbindung lag (überlastet, oder sonstige fehler). Denn dass das Forum wegen des Codes einen internen Fehler haben sollte klingt für mich sehr unwahrscheinlich. Vermutlich warens nicht die Apostrophe, sondern eher die Zeit fürs eintragen.

Zum Tut kann ich nur wieder sagen, super gemacht.
Benutzeravatar
Timm
Mega-User
Mega-User
Beiträge: 387
Registriert: So, 25.06.06, 18:53

Fr, 12.01.07, 15:47

Danke Pehu für die ganzen Tut's ich glaub ich fang damit auch mal an.. brauch ich ja später auch beruflich.
Die lösungsmöglichkeit ist mit einem "else"oder :D
Benutzeravatar
Fightclub
Post-Hero
Post-Hero
Beiträge: 5114
Registriert: Mi, 01.03.06, 18:40

Fr, 12.01.07, 16:48

@timm: wenn der ic aber im else-zweig ist wenn man den taster drückkt hilft dir das auch nicht weiter.
Benutzeravatar
Timm
Mega-User
Mega-User
Beiträge: 387
Registriert: So, 25.06.06, 18:53

Fr, 12.01.07, 17:07

Fightclub hat geschrieben:@timm: wenn der ic aber im else-zweig ist wenn man den taster drückkt hilft dir das auch nicht weiter.
hmm ja gut ich dachte ja nur :D hab mit sowas eigentlich nix am hut. nur ein bisschen in der schule aber halt dephi
Benutzeravatar
alexStyles
Auserwählter
Auserwählter
Beiträge: 2333
Registriert: So, 20.08.06, 16:51
Wohnort: Düsseldorf
Kontaktdaten:

Fr, 12.01.07, 17:10

Also das mit dem Internen Fehler hatte Ich auch schon des öfteren so beim Bilder Upload ...
Aber nach einiger Zeit ging es bisher immer wieder :D 8)

MfG Alex

PS: zum Tut ... Oha xD jetzt merke Ich wofür dieses Englische wirrwarr in Indformatik zu nutze war :lol:
Benutzeravatar
Fightclub
Post-Hero
Post-Hero
Beiträge: 5114
Registriert: Mi, 01.03.06, 18:40

Sa, 13.01.07, 12:00

@timm: delphi is find ich viel zu umständlich, immer dieses variablen deklarieren blablabla und dann noch diese fehlermeldungen wo man hinterher genauso schlau is wie vor der meldung :roll:
Benutzeravatar
Jay
Hyper-User
Hyper-User
Beiträge: 1096
Registriert: Mo, 08.05.06, 07:54
Wohnort: Österreich

Sa, 13.01.07, 12:11

also ich hab mir selber QBasic und später VisualBasic beigebracht
BASCOM-AVR ist eine leistungsfähige Programmiersprache, die eine hohe Kompatibilität zu QBASIC- bzw. Visual BASIC-Befehlen aufweist.
da bin ich gut dabei! :lol:

MfG
Jay
Benutzeravatar
Timm
Mega-User
Mega-User
Beiträge: 387
Registriert: So, 25.06.06, 18:53

So, 14.01.07, 17:00

Fightclub hat geschrieben:@timm: delphi is find ich viel zu umständlich, immer dieses variablen deklarieren blablabla und dann noch diese fehlermeldungen wo man hinterher genauso schlau is wie vor der meldung :roll:
stimmt schon :D aber wir müssen es lernen... :wink:
Andy
Hyper-User
Hyper-User
Beiträge: 1284
Registriert: Mi, 17.05.06, 13:03

Mo, 15.01.07, 22:11

Hi

Nochmal ne andere Frage.

Wenn ich in einem Programm bzw. Unterprogramm diverse Ausgänge anders Belege wie zum Beispiel:

Portb.0 = 0
Portb.1 = 0
Portb.2 = 1
Portb.3 = 0
Portb.4 = 1

etc.

Könnte man diese Änderungen nicht auch verkürzen, damit man nicht so viel Speicher der yC´s belegt?

Wie etwa bei der Configuration am Anfang des Programs mit "Ddrb = &B001100"

Wäre das nicht irgendwie möglich?
Benutzeravatar
Pehu
Mega-User
Mega-User
Beiträge: 469
Registriert: Mi, 01.11.06, 19:33
Kontaktdaten:

Di, 16.01.07, 07:02

Ja, es gibt noch einen anderen Befehl:

Portb = &B000000

0 = Low, 1 = High.

Naja, ob du mit diesem Befehl Code bzw. Speicher sparen tust, weiß ich nicht. Denn wichtig ist, die kompilierte Datei zum Schluss. Ich vermute Bascom wird als Kompiler, genau das gleiche kompilieren, egal um kurzer oder langer Befehl. Aber im Bascom hast du dann eine bessere Übersicht.
Andy
Hyper-User
Hyper-User
Beiträge: 1284
Registriert: Mi, 17.05.06, 13:03

Di, 16.01.07, 07:33

Jou Danke dir...werde es mal ausprobieren...es geht mir ja auch dadrum, die Befehlszeilen etwas zu vereinfachen um nicht Kilometerlangetextezutippen und alle Befehle zu wiederholen nur weil man einen Zustand ändert.

Na gut klar... um einen Anfänger wie mir, das ganze Verständlich zu machen und alles zu Erklären, wie alles zusammen hängt, ist es natürlich besser es Zeile für Zeile zu schreiben.
Aber im nachhinein, wenn man es Verstanden hat, wäre es dann in der kürzeren Form einfacher und man benötigt weniger Text.

Aber wie war das?...um Lesen zu können , muß man ersteinmal das Alphabet lernen. :wink:
Andy
Hyper-User
Hyper-User
Beiträge: 1284
Registriert: Mi, 17.05.06, 13:03

Sa, 20.01.07, 19:19

So...nu habe ich da noch ne Frage...

Und zwar betrifft es den D/A - A/D Wandler in den yC´s.

Da die yC´s ja die AD/DA Wandler schon Integriert haben, dachte ich mir, diese Sinnvoll zu Nutzen aber ich wüßte jetzt nicht wie...
Ich Dachte da irgendwie an eine SOUND TO LIGHT Ansteuerung, die bei bestimmten Frequenzen bestimmte Befehlsfolgen abrufen kann...

Bei einem heftigen Bass meinetwegen ein Flashen aller LED´s und bei krassen Höhen halt ne art Stroboskop und so weiter...nur, wüßte ich jetzt nicht, wie ich das Anstellen sollte....hat da jemand irgendwie eine Idee, die man mal Probieren könnte?
Vielleicht auch ein kleines Programmbeispiel wäre sehr sinnvoll.
root
Mega-User
Mega-User
Beiträge: 459
Registriert: Di, 28.03.06, 21:32

So, 21.01.07, 12:11

Kenne mich leider nicht in Basic aus, aber du musst halt erstmal den Interrupt aktivieren und ein paar Einstellungen vornehmen, z.B. ob er im Freerun oder Singlerun laufen soll usw.. Wie gesagt in Basic kenn ich mich nicht aus, müsstest dir am besten mal die entsprechenden Register im Datenblatt anschauen.
Wenn du dann alles soweit hast bekommst du entsprechend der anliegenden Spannung einen Wert, bei 8-Bit zwischen 0 und 255 dem du dann beispielsweise über eine Tabelle eine bestimmte pwm Frequenz zuordnen kannst.

Aber hier wird dir auch sicherlich jemand einen Code in Basic geben können :wink:
Andy
Hyper-User
Hyper-User
Beiträge: 1284
Registriert: Mi, 17.05.06, 13:03

So, 21.01.07, 17:57

Das wäre richtig Cool, denn dann könnte man dadrauf Aufbauen, dann weiß man ja schon wie soetwas Funktionieren würde, damit man eine Basis hat um hinter das Geheimnis zu kommen, wie´s funktioniert.
zerlot
Mini-User
Beiträge: 4
Registriert: Do, 15.02.07, 20:22

Do, 15.02.07, 21:18

hab mal ne frage zu den interrupts, weil ich ein problem habe. softwaremäßig geht alles und auf dem pollin board funktioniert der taster auch. doch wie schließe ich den taster in meiner schaltung richtig?
habe eine led leister und die leds werden nacheinander an geschalten (knight-rider mäßig). mit dem taster sollte man die geschwindigkeit einstellen. jedoch sobald ich irgendwas an den interrupt port anschließe geht die geschwindkeit sofort ins unendliche -> leds leuchten alle schwach.
interrupt ist auf rising eingestellt. sobald ich nur mit dem finger oder nem kabel an den pin komme, wird die geschwindkeit ins unendliche erhöht :)
aufm board hats aber mit dem taster richtig funktioniert.

danke für eure hilfe
Andy
Hyper-User
Hyper-User
Beiträge: 1284
Registriert: Mi, 17.05.06, 13:03

Do, 15.02.07, 21:26

Ich Denke mal, das hängt damit zusammen, das die Taster an einem Pul Up Widerstand hängt und du diesen in deiner Schaltung nicht bedacht hast.
Wenn dein Taster geöffnet hat, liegt der Eingang Quasi "in der Luft" und dann weiß das IC meist nicht, was es machen soll..., weil der Eingang nicht "Wirklich" definiert ist.
zerlot
Mini-User
Beiträge: 4
Registriert: Do, 15.02.07, 20:22

Fr, 16.02.07, 12:50

mir ist noch was aufgefallen. wenn ich den pin mit einem widerstand bzw einem kabel berühre erhöht sich die geschwindkeit trotzdem... wie ist das möglich? der widerstand bzw das kabel ist ja mit nichts verbunden, somit wird ja auch kein strom fließen. wie muss ich das richtig anschließen?
Benutzeravatar
Fightclub
Post-Hero
Post-Hero
Beiträge: 5114
Registriert: Mi, 01.03.06, 18:40

Fr, 16.02.07, 13:49

falsch. Der Widerstand ist mit DIR verbunden.
zerlot
Mini-User
Beiträge: 4
Registriert: Do, 15.02.07, 20:22

Sa, 17.02.07, 01:27

aso ja....aber wie soll ich des den nun richtig anschließen? finde keinen schaltplan für einen externen interrupt im internet.
Benutzeravatar
Pehu
Mega-User
Mega-User
Beiträge: 469
Registriert: Mi, 01.11.06, 19:33
Kontaktdaten:

Sa, 17.02.07, 09:00

In der Pollin-Bedienungsanleitung ist doch ein Schaltplan vom Board drin.Du kannst dir die Taster abkupfern.
zerlot
Mini-User
Beiträge: 4
Registriert: Do, 15.02.07, 20:22

Sa, 17.02.07, 13:24

ist ne gute ideee... dann werd ich mal die anleitung suchen. hat von euch noch niemand einen taster an den interrupt angeschlossen? man findet dazu echt nichts im internet.
Antworten