Hallo liebe Mikrocontroller-Gemeinde,
Ich habe im Studium ein kleines bisschen über Mikrocontroller und
embedded Systems gelernt und wollte nun mein Wissen anwenden:
Ich bin begeisterter Geocacher und wollte nun mit Freunden einen
Nachtcache legen. Als eine Station wollten wir ein Nachtaktives
Reaktivlicht setzen. Weil ich schon mal was von Microcontrollern gehört
hab, hab ich die Aufgabe übernommen und stehe jetzt vor nem kleinen
Problem.
Mein kleines Reativlicht soll auf eine Fernbedinung reagieren und als
Ausgabe den neuen Waypoint in Form eines Morsecodes ausgeben.
Die Schaltung habe ich soweit gelötet und sollte auch so funktionieren.
Ich verwende einen ATMega8-16DIP mit TSOP1738 und normalen LEDs als
ausgabe.
Ich programmiere mit micropascal for AVR Pro.
Mein Programmcode sieht so aus
1
program geo;
2
3
4
{ Declarations section }
5
6
7
8
{ Declarations section }
9
10
11
// Hauptprogramm (Main)
12
13
var incoming_IR_yes : boolean ;
14
15
// Ausgabe auf die LED´s
16
procedure Ausgabe ;
17
//var ;
18
begin
19
20
PORTB.B5 := 0x00 ;
21
Delay_ms (3000) ;
22
PORTB.B3 := 0x00 ;
23
24
25
end;
26
27
28
//Hauptschleife für Abfrage Infrarot
29
30
procedure Abfrage_infrarot_eingang ; // oder alles als function
31
var i : integer ;
32
33
34
begin
35
36
37
PORTC := 0x00 ; //alles aus auf port c einga infrarot
38
PORTB := 0xff ; //alles aus auf port b
39
40
PORTB.B5 := 0x00 ; //rot an
41
Delay_ms (1000) ; //pause
42
PORTB.B5 := 0x01 ; //rot aus
43
Delay_ms (1000) ; //pause
44
PORTB.B5 := 0x00 ; //rot an
45
Delay_ms (1000) ; //pause
46
PORTB.B5 := 0x01 ; //rot aus
47
Delay_ms (1000) ; //pause
48
PORTB.B5 := 0x00 ; //rot an
49
Delay_ms (1000) ; //pause
50
PORTB.B5 := 0x01 ; //rot aus
51
52
{while PORTC.B3 <> 0x00 do // unendlich schleife start
53
begin
54
55
56
57
// if PORTC.B3 <> 0x01 then Ausgabe //else
58
{begin // oder ne braek und er läuft weiter in die nächste function weiß noch nciht genau ob das funst
59
Delay_ms (100) ; //mit dem delay müssen wir noch mal spielen bzw rechnen weil einmal in der gesamt signallaufzeit reicht mussen ja nur eine 1 erwischen um auzulösen
60
PORTB.B1 := 0x00 ;
61
Delay_ms (100) ;
62
PORTB.B1 := 0x01 ;
63
Delay_ms (100) ;
64
65
PORTB.B3 := 0x00 ;
66
Delay_ms (100) ;
67
PORTB.B3 := 0x01 ;
68
Delay_ms (100) ;
69
70
PORTB.B5 := 0x00 ;
71
Delay_ms (100) ;
72
PORTB.B5 := 0x01 ;
73
end;
74
delay_ms (10)
75
end;} // unendlich schleife ende
76
77
i := 0 ;
78
while i <> 0 do
79
begin
80
i := PORTC.B3 ;
81
i := sbit at PORTC.B3;
82
83
end;
84
Ausgabe;
85
86
end;
87
88
89
90
begin
91
DDRC := 0x00 ; //port auf eingang
92
DDRB := 0xff ; //port auf ausgang
93
PORTB := 0xff ; //alle ausgaänge port b aus
94
Delay_ms (3000) ;
95
96
incoming_IR_yes := false;
97
PORTB.B5 := 0x00 ; //dide 1 an an is 0x00
98
PORTB.B3 := 0x00 ;
99
PORTB.B1 := 0x00 ;
100
Delay_ms (500) ;
101
PORTB.B5 := 0x01 ; //diode aus aus is 0x01
102
PORTB.B3 := 0x01 ;
103
PORTB.B1 := 0x01 ;
104
Delay_ms (2500) ;
105
106
107
108
Abfrage_infrarot_eingang;
109
110
111
112
113
end.
Problem ist nun, dass wenn ich auf den Eingang PortB.B3 eine 1 setze,
wird die Ausgabeprozedur nicht aufgerufen.
Ich hab das erstmal am SKT500 ausprobiert? hat jemand eine Idee,
Ich bin schon ziemlich ratlos, daher auch die vielen auskommentierten
Codestückchen...
Vielen Dank im Vorraus
Torsren Wessling schrieb:> procedure Abfrage_infrarot_eingang ; // oder alles als> {while PORTC.B3 <> 0x00 do> // unendlich schleife start
Das ist keine unendliche Schleife.
Die Schleife hängt ganz eindeutig von einer Bedingung ab.
Was passiert, wenn die Bedingung nicht mehr, oder noch nicht erfüllt
ist?
> Ich bin schon ziemlich ratlos, daher auch die vielen auskommentierten> Codestückchen...
Du hast IMHO falsch angefangen.
Das wichtigste war, dass dein µC am Anfang eine Blinkerei inszeniert,
damit da was zum schauen hast. Quasi ein 'Willkommen' auf µC Art. Das
ist als Vortest nicht schlecht, aber im Grunde ist es für dein
eigentliches Programm völlig unwichtig und raubt dir momentan nur die
Übersicht.
Fang nochmal an.
Aber diesmal soll dein erster Zwischenschritt sein:
Dein Programm bedient 2 LED
Am Programmanfang wird die eine eingeschaltet und die andere aus.
Dann geht das Programm in die obligatorische Endlosschleife über
In der Endlosschleife fragt es ständig den Input Pin ab
Ist der auf 0, dann passiert nichts
Ist der aber auf 1, dann schaltet dein Programm die beiden LED um.
Die leuchtende wird ausgeschaltet, die nicht leuchtende ein
Dieser Programmansatz ist klein genug, dass du dir nicht wieder selbst
die Übersicht raubst.
Und nein. Mach das erst mal ohne procedure. Das sind nur ein paar Zeilen
Code.
Und wenn das dann funktioniert, dann baust du es aus.
Super, danke für eure schnellen antworten.
@ Karl Heinz:
Das mit dem rumgeblinke ist noch drin geblieben, um zu überprüfen ob ich
meine Schaltung richtig gelötet habe und jetzt im nachhinnein um
herauszufinden, ob der Controller in die Ausgabeprozedur springt.
Werde das mal nach deinem Rat schlanker gestallten und mich dann nochmal
melden, ob das so hingehauen hat!
Danke nochmal!
Kleines Update hierzu:
Ich habe Euren Rat befolgt und das Programm nochmal ganz von vorne
angefangen.
Ich konnte das Programm endlich vernünftig struckturieren und habe es
geschafft die LEDs zum richtigen Blinken zu bekommen!
Danke nochmal für Euren guten Rat!
Und grade weil ihr mir so gut geholfen habt, habe ich nochmal eine
Bitte!
könntet ihr nochmal über meinen(verkürzten) Code schauen.
Ich habe den extra eingekürzt, weil 200 Zeilen in denen nur LEDs an und
wieder ausgemacht werden, sind für Euch ja wahrscheinlich uninteressant!
Mein Problem ist folgendes:
Die Aktivierung per IR-Empfänge funktioniert einwandfrei. Nachdem der
Blinker aktiviert worden ist, soll erstmal eine grüne LED für 2 Sekunden
leuchten, um den Benutzer darauf vorzubereiten, dass gleich was
passieren wird. Dannach soll der Morsecode mit der Blauen LED starten.
dann leuchtet nochmal die grüne LED, denn dannach startet eine rote LED
mit der Anzeige des anderen Morsecodes. Dannach ist Ende. der Controller
wartet wieder auf eine erneute Aktivierung.
Es funktioniert fast alles: und mit fast mein ich auch wirklich nur eine
Kleinigkeit.
Die grüne LED leuchtet am Anfang nicht. es startet sofort die blaue LED
mit der Übertragung. dannach leuchtet die grüne LED so wie es sein soll,
und die Rote LED arbeitet auch vernünftig.
Hier mein verkürzter Code: vielleicht findet ihr ja den Grund dafür!
1
program Geocaching;
2
3
{ Declarations section }
4
(* //OUTPUTS
5
// LED GRÜN == PORTB.B1
6
// LED BLAU == PROTB.B3
7
// LED ROT == PORTB.B5
8
9
//INPUT
10
// TSOP == PINC.C3
11
12
*)
13
14
15
begin
16
17
DDRB := 0xFF; //Ports B auf Ausgang
18
19
DDRD := 0x00; //Ports D auf Eingang
20
21
PortB.B1 := 0x00;
22
Portb.B0 := 0x00;
23
Portb.B2 := 0x00;
24
Portb.B3 := 0x00; //schaltet alle LED aus
25
Portb.B4 := 0x00;
26
Portb.B5 := 0x00;
27
28
29
30
while TRUE do
31
begin
32
33
if PINC.B3 = 0 then
34
begin
35
//Bereit halten mit grüner LED 2Sek
36
PORTB.B1 := 0x01; //Dieser Teil, also das An- und Ausschalten von PORTB.B1, es scheint, als würden diese 3 Zeilen übersprungen, funktioniert nicht! Keine Ahnung warum nicht, aber
37
delay_ms(2000);
38
PORTB.B1 := 0x00;
39
40
41
// Übermittlung der Nördlichen Breite
42
//5
43
PORTB.B3 :=0x01;
44
delay_ms(300); //dit
45
PORTB.B3 := 0x00;
46
47
delay_ms(300); //Symbolabstand //funktioniert einwandfrei, hab das nur abgekürzt.
48
49
PORTB.B3 :=0x01;
50
delay_ms(300); //dit
51
PORTB.B3 := 0x00;
52
53
(*Hiernach wird mit dem Ein- und Ausschalten der LEDs weiter gemacht.
54
bis dann das hier folgt.*)
55
56
57
58
//Bereit halten mit grüner LED 2 Sek
59
PORTB.B1 := 0x01;
60
delay_ms(2000);
61
PORTB.B1 := 0x00; //das funktioniert auch einwandfrei