Servus,
ich versuche einmal mein Problem verständlich zu schildern:
ich habe eine Funktion realisiert, die 30 Stellen auf einem Display
ausgeben kann. Nennen wir diese Funktion meinetwegen sendedisplay(). In
dieser Funktion werden jetzt die jeweiligen Stellen auf dem Display
abgefahren.
1
sendedisplay()
2
{
3
sende(stelle1);
4
sende(stelle2);
5
sende(stelle3);
6
...
7
}
Diese sende Funktion würde ich am liebsten immer aktualisieren lassen,
beispielsweise in der while-Schleife und nur die Variablen stelle1,
stelle2, stelle3 ... aktualisieren.
Ich hoffe das Problem einigermaßen verständlich erläutert zu haben. Wie
lässt sich das realisieren. Ich verlange keine Komplettlösungen, sondern
nur einige Anregungen und Links.
Besten Dank
Das ist natürlich nur ein Scherz, Du hast die Frage sicher anders
gemeint. Und zwar, wie Du das PLUS weitere Aktionen auf dem
Mikrocontroller unterbekommen kannst.
Das geht z.B. ungefähr so:
- über einen Interrupt passieren irgendwelche Dinge, sagen wir mal es
werden Taster abgefragt
- dieser Interrupt setzt dann eine Variable, sagen wir ein "keyUp"-Flag
- in der Hauptschleife fragst Du das keyUp ab und erhöhst dann eine
Variable, die dann wieder auf das Display ausgegeben werden soll
Dann sieht das ganze so aus:
1
volatileuint8_tkeyUp;
2
volatileuint8_tcounter;
3
4
_ISR(INT0_vect)
5
{
6
if(pin=HIGH){
7
keyUp=1;
8
}
9
}
10
11
sendedisplay()
12
{
13
sende(stelle1);
14
sende(stelle2);
15
sende(stelle3);
16
}
17
18
main
19
{
20
while(1){
21
if(keyUp){
22
counter++;
23
}
24
sendedisplay();
25
}
26
}
ACHTUNG: das ist nur mal schnell runtergekippt und nicht
notwendigerweise compilierbar!
Als wird in der Hauptschleife einerseits auf Ereignisse reagiert,
andererseits immer das Display ausgegeben.
Das kannst jetzt auch noch erweitern und z.B. das Display nur jede
Sekunde aktualisieren, indem ein Timer-Interrupt jede Sekunde ein Flag
setzt, das Deiner Hauptschleife sagt, es soll das Display aktualisieren:
1
volatileuint16_tticks;
2
volatileuint8_tsekunde;
3
volatileuint8_tkeyUp;
4
volatileuint8_tcounter;
5
6
_ISR(TIMER0_OVF)
7
{
8
ticks++;
9
if(ticks>1000){
10
sekunde=1;
11
}
12
}
13
14
_ISR(INT0_vect)
15
{
16
if(pin=HIGH){
17
keyUp=1;
18
}
19
}
20
21
sendedisplay()
22
{
23
sende(stelle1);
24
sende(stelle2);
25
sende(stelle3);
26
}
27
28
main
29
{
30
while(1){
31
if(keyUp){
32
counter++;
33
}
34
if(sekunde){
35
sendedisplay();
36
sekunde=0;
37
}
38
}
39
}
(Btw, nachlesen, was das volatile bedeutet und wie man in der
Hauptschleife "atomic" auf die Variablen zugreift!)
Isildur schrieb:> Diese sende Funktion würde ich am liebsten immer aktualisieren lassen,> beispielsweise in der while-Schleife und nur die Variablen stelle1,> stelle2, stelle3 ... aktualisieren.
Ja, dann mach das doch!
WO drückt denn jetzt der Schuh?
>> Ich hoffe das Problem einigermaßen verständlich erläutert zu haben.
Nicht wirklich. Aber meine Glaskugel sagt, dass du wahrscheinlich haben
willst, dass eine Stelle nur dann aktualisiert werden soll, wenn sich
ihr anzuzeigender Wert auch tatsächlich verändert hat.
Na, dann musst du dir eben in Variablen speichern, was an der jeweiligen
Stelle momentan gerade angezeigt wird und nur dann, wenn die neue
Information davon abweicht, dann wird die Anzeige aktualisiert.
zb in C
1
voidsendedisplay()
2
{
3
staticintaktuellStelle1=-1;
4
staticintaktuellStelle2=-1;
5
6
if(stelle1!=aktuellStelle1){
7
sende(stelle1);
8
aktuellStelle1=stelle1;
9
}
10
11
if(stelle2!=aktuellStelle2){
12
sende(stelle2);
13
aktuellStelle2=stelle2;
14
}
15
16
....
durch den Einsatz von Arrays kannst du dir übrigens noch eine Menge
Tipparbeit ersparen.
Conny G. schrieb:> _ISR(INT0_vect)> {> if (pin = HIGH) {> keyUp = 1;> }> }
Dafür setzt man lieber ein Bit in nem GPIOR, da spart man sich im
Interrupt ein Register (und das zugehörige push/pop) und ein STS und in
der main spart man ebenfalls und im obigen Fall könnte man die ISR dann
sogar naked machen.
Bernd K. schrieb:> Conny G. schrieb:>> _ISR(INT0_vect)>> {>> if (pin = HIGH) {>> keyUp = 1;>> }>> }>> Dafür setzt man lieber ein Bit in nem GPIOR, da spart man sich im> Interrupt ein Register (und das zugehörige push/pop) und ein STS und in> der main spart man ebenfalls und im obigen Fall könnte man die ISR dann> sogar naked machen.
Und das ist hilfreich für einen Anfänger? :-)
Conny G. schrieb:> Und das ist hilfreich für einen Anfänger? :-)
Naja, er könnte es sich frühzeitig angewöhnen diese GPIOR Register für
sinnvolle Zwecke zu nutzen, das hat auch den Vorteil dass er wieder was
neues gelernt hat, nämlich die Existenz derselben von der er bis vor ein
paar Stunden vermutlich noch gar nichts ahnte ;-)
@Isildur: Der Vorteil eben dieser Register gegenüber einer volatile
uint8_t ist der daß für erstere genau wie bei IO-Pins nur ein einziger
Taktzyklus erforderlich ist um ein bit zu setzen, zu löschen oder zu
prüfen während eine globale volatile Variable im RAM mindestens zwei
Zyklen zum Lesen, 2 weitere zum Schreiben und ein oder zwei um ihren
Wert zu prüfen oder zu ändern, also 5 oder 6 Zyklen mindestens und auch
um den selben Faktor mehr Programmspeicher (Flash) benötigt. Wenn Du Dir
den vom Compiler erzeugten Assemblercode anschaust wird Dir schwindlig
werden von all der Verschwendung ;-)
Bernd K. schrieb:> Conny G. schrieb:>> Und das ist hilfreich für einen Anfänger? :-)>> Naja, er könnte es sich frühzeitig angewöhnen diese GPIOR Register für> sinnvolle Zwecke zu nutzen, das hat auch den Vorteil dass er wieder was> neues gelernt hat
Das hat Zeit, bis er aus dem Stadium '0-Wissen' rausgekommen ist.
Ehe das Thema GPIOR relevant wird, gibt es tausende andere Dinge, die
erst mal wichtiger sind.
WOW,
super schon mal vielen Dank für den ganzen Input, werde das heute Abend
alles mal ausprobieren.
Eine Frage noch vorab, ich habe hier auch nen paar Taster rumfliegen.
Idee ist wirklich über die Tasten jeweils verschiedene Menüs anzuzeigen
(vermutlich auch verschachtelt).
Fragt man die Taster standardmäßig übers Polling oder über Interrupts
ab. Ziel ist in einiger Zeit (nach Einarbeitung natürlich) schon einige
verschachtelte Menüführung mit dem Display zu realisieren.
Vielen Dank für die ganzen Antworten!
Hi Isildur,
Tasten abfragen und Entprellen ist ein ganzes Thema für sich.
Genau genommen sollte man Taster nicht per pin change oder Flanken
Interrupt abfragen (Gründe: such mal im Forum nach Taster und Interrupt,
da kommen bestimmt wilde Diskussionen zutage), da war mein Beispiel oben
ungeschickt.
Für die Entprellung von Tasten gibt es einen riesigen Artikel.
Als Methode kann ich diese empfehlen:
http://www.mikrocontroller.net/articles/Entprellung#Timer-Verfahren_.28nach_Peter_Dannegger.29
vg,
Conny
Das funktioniert gan z sicher nicht, es sei denn du hast einen Haufen
Variablen, für jeden Buchstaben einen. Das allerdings wäre komplett
dämlich.
Zeige dein ganzes Programm. Aus den Schnipseln kann keiner was ableiten.
Sehr wahrscheinlich sitzt das Problem ganz woanders.
Das ist wieder mal so eine Frage, bei der man dann antworten möchte:
Lies ein C-Buch!
Da Du die Variablen static deklariert hast und sie über eine
Header-Datei in zwei verschiedene C-Dateien einfügst, erhälst Du zwei
Sätze gleichnamiger Variablen die jeweils "lokal" zu der entsprechenden
C-Datei sind.
Dadurch initialisierst Du zwar die eine der beiden Modullkokalen
Variablensätze mit senddisplay_menu1(), liest aber einen dritten Satz
aus, denn ich vermute, Du includest die Header-Datei mit den
Variablendefinition ein drittesmal.
Was mich zu noch einem Hinweis bringt: Poste komplette Programme. Die
Meinung von Anfängern, dass das nicht gepostete schon korrekt sei,
erweist sich in den meisten Fällen als falsch.
Isildur schrieb:> sendekommando(displaystelle1);> sendekommando(displaystelle2);> sendekommando(displaystelle3);> sendekommando(displaystelle4);
Das ist Copy&Paste-Code der übelsten Sorte.
Sowas kann man für die allerersten Schritte mal probieren.
Aber ein richtiges Programm kann man so nicht schreiben.
Das wird unübersichtlich, unwartbar, unverstehbar, fehlerträchtig und
riesig.
Sachen, die mehr als einmal ähnlich benötigt werden, macht man mit
Arrays und Schleifen.
Dann muß man sie nur einmal hinschreiben und einmal testen und kann sie
beliebig erweitern.