Guten Tag allerseits!
Kleines Problem hier!
Ich mache 6 Temperaturmessungen mittels Thermoelementen und ATMega2561,
welche auf einem Display angezeigt und aktualisiert werden.
Die Routine sieht folgendermassen aus:
1
while(1){
2
LCD_Print("test",90,120,2,1,1,red,red);
3
delay_ms(300);
4
LCD_Print("test",90,120,2,1,1,blue,blue);
5
delay_ms(300);
6
}
7
8
ISR(INT4_vect)
9
{
10
delay_ms(100);
11
key=key_press(pos,site);
12
LCD_Print("test",90,100,1,1,1,red,green);
13
delay_ms(100);
14
LCD_Print("test",90,100,1,1,1,black,green);
15
}
im Beispiel wird die while-schleife durch einen Tasteninterrupt
unterbrochen. Mittels key_press() ermittle ich noch die genaue Taste, da
nur die Kolonnen auf Interruptleitungen hängen. Was soweit auch
funktioniert, die while-Schleife wird unterbrochen und danach
weitergeführt, was auch mein Ziel ist.
Jetz zu meinem Problem.
Wenn ich in der selben Struktur die Temperaturmessung vornehme, das
heisst in der while-Schleife verschiedene berechnungen mache, häng ich
irgendwo im Programm fest, die while-Schleife wird jedoch nicht weiter
durchlaufen und die Werte nicht aktualisiert...woran kann das liegen?
Hier noch die erwähnte Temperaturberechnungs-Schleife:
du kannst nicht in der ISR und in dem hauptprogramm auf den Display
rumschreiben. Das führt immer zu Problemen.
Auch ein Delay hat nicht in der ISR verloren.
Ändere erstmal diese punkte und zeige uns dann das komplette Programm.
Peter II schrieb:> du kannst nicht in der ISR und in dem hauptprogramm auf den Display> rumschreiben. Das führt immer zu Problemen.
1
while(1){
2
LCD_Print("test",90,120,2,1,1,red,red);
3
delay_ms(300);
4
LCD_Print("test",90,120,2,1,1,blue,blue);
5
delay_ms(300);
6
}
7
8
ISR(INT4_vect)
9
{
10
delay_ms(100);
11
key=key_press(pos,site);
12
}
> Auch ein Delay hat nicht in der ISR verloren.
dieser Delay von 100ms ist noch dazu da um die Taste zu entprellen.
Führt das auch schon zu Problemen?
Und hier noch ke_press():
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include"../header/MMI/matrix_keyboard.h"
4
5
voidInit_Key_Port()
6
{
7
/* All Ports input of the matrix keyboard */
8
DDRE=((0<<DDE7)|(0<<DDE6)|(0<<DDE5)|(0<<DDE4));
9
DDRD=((0<<DDD7)|(0<<DDD4));
10
DDRG=((0<<DDG3)|(0<<DDG0));
11
/* Pullup resistance active for keyboard ports*/
12
PORTE=((1<<PE7)|(1<<PE6)|(1<<PE5)|(1<<PE4));
13
PORTD=((1<<PD7)|(1<<PD4));
14
PORTG=((1<<PG3)|(1<<PG0));
15
}
16
17
charkey_press(intpos,intsite)
18
{
19
charnumber=0;
20
intkeycode,keyflag=4;
21
Init_Key_Port();// make sure all keyboard ports are initialized
22
23
/* check line D */
24
PORTD=(0<<PD4);// PORT D4 at pullup desactive
25
DDRD=(1<<DDD4);// PORT D4 in input
26
keycode=0x08&0x0F;// line code
27
/* check column */
28
if((PINE&(1<<PINE7))==0);// faking condition
29
elseif((PINE&(1<<PINE5))==0)keycode+=0x10&0xF0;
30
elseif((PINE&(1<<PINE4))==0)keycode+=0x20&0xF0;
31
elseif((PINE&(1<<PINE6))==0)keycode+=0x40&0xF0;
32
elsekeyflag--;
33
PORTD=(1<<PD4);// PORT D4 at pullup active
34
DDRD=(0<<DDD4);// PORT D4 in output
35
36
if(keyflag==3)
37
{
38
/* check line C */
39
PORTD=(0<<PD7);// PORT D7 at pullup desactive
40
DDRD=(1<<DDD7);// PORT D7 in input
41
keycode=0x04&0x0F;// line code
42
/* check column */
43
if((PINE&(1<<PINE7))==0);// faking condition
44
elseif((PINE&(1<<PINE5))==0)keycode+=0x10&0xF0;
45
elseif((PINE&(1<<PINE4))==0)keycode+=0x20&0xF0;
46
elseif((PINE&(1<<PINE6))==0)keycode+=0x40&0xF0;
47
elsekeyflag--;
48
PORTD=(1<<PD7);// PORT D7 at pullup active
49
DDRD=(0<<DDD7);// PORT D7 in output
50
}
51
52
if(keyflag==2)
53
{
54
/* check line B */
55
PORTG=(0<<PG0);// PORT G0 at pullup desactive
56
DDRG=(1<<DDG0);// PORT G0 in input
57
keycode=0x02&0x0F;// line code
58
/* check column */
59
if((PINE&(1<<PINE7))==0);// faking condition
60
elseif((PINE&(1<<PINE5))==0)keycode+=0x10&0xF0;
61
elseif((PINE&(1<<PINE4))==0)keycode+=0x20&0xF0;
62
elseif((PINE&(1<<PINE6))==0)keycode+=0x40&0xF0;
63
elsekeyflag--;
64
PORTG=(1<<PG0);// PORT G0 at pullup active
65
DDRG=(0<<DDG0);// PORT G0 in output
66
}
67
68
if(keyflag==1)
69
{
70
/* check line A */
71
PORTG=(0<<PG3);// PORT G3 at pullup desactive
72
DDRG=(1<<DDG3);// PORT G3 in input
73
keycode=0x01&0x0F;// line code
74
/* check column */
75
if((PINE&(1<<PINE7))==0);// faking condition
76
elseif((PINE&(1<<PINE5))==0)keycode+=0x10&0xF0;
77
elseif((PINE&(1<<PINE4))==0)keycode+=0x20&0xF0;
78
elseif((PINE&(1<<PINE6))==0)keycode+=0x40&0xF0;
79
elsekeyflag--;
80
PORTG=(1<<PG3);// PORT G3 at pullup active
81
DDRG=(0<<DDG3);// PORT G3 in output
82
}
83
84
/* Interrupt Ports input */
85
DDRE=((0<<DDE7)|(0<<DDE6)|(0<<DDE5)|(0<<DDE4));
86
/* Ports output */
87
DDRD=((1<<DDD7)|(1<<DDD4));
88
DDRG=((1<<DDG3)|(1<<DDG0));
89
/* Pullup resistance Interrupt Ports active */
90
PORTE=((1<<PE7)|(1<<PE6)|(1<<PE5)|(1<<PE4));
91
/* Pullup resistance output Ports inactive */
92
PORTD=((0<<PD7)|(0<<PD4));
93
PORTG=((0<<PG3)|(0<<PG0));
94
sei();
95
/* Switch table which return the value of the pressed key */
Ja, der Delay in der ISR kann zu Problemen führen. Dort sollte auch kein
Aufruf externer Programme stehen.
Ich handhabe das so, dass ich in der ISR Flags setze und die dann im
Hauptprogramm auswerte und nach Ausführung der entsprechenden Routine
wieder lösche.
Felix Pflaum schrieb:> Ja, der Delay in der ISR kann zu Problemen führen. Dort sollte auch kein> Aufruf externer Programme stehen.>> Ich handhabe das so, dass ich in der ISR Flags setze und die dann im> Hauptprogramm auswerte und nach Ausführung der entsprechenden Routine> wieder lösche.
Das Problem ist, dass die Temperaturmessungen eine gewisse Zeit (~5sec)
benötigen, was beim setzen eines Flags dann auch Verzögerungen
verursacht.. Oder seh ich das falsch?
was hat das sei(); in der ISR der key_press verloren?
> dieser Delay von 100ms ist noch dazu da um die Taste zu entprellen.> Führt das auch schon zu Problemen?
früher oder später auf jeden Fall, dann in der Zeit geht nichts anders
mehr.
Peter II schrieb:> was hat das sei(); in der ISR der key_press verloren?
ist raus, da habich was getestet
> früher oder später auf jeden Fall, dann in der Zeit geht nichts anders> mehr.
ok, aber soweit ich bis jetzt testen konnte sind mir dadurch noch keine
probleme aufgetreten.
Ich häng immernoch an der Ausgabe der Temperaturwerte. Manchmal
funktioniert es sogar:=)...aber ich kann mir nicht vorstellen wo sich
das Programm festsetzt.
Rico H. schrieb:> aber ich kann mir nicht vorstellen wo sich> das Programm festsetzt.
du rufst ja noch tausend andere dinge in der key_press auf
Sensoren();
DiffMess();
das hat alles dort nichts zu suchen, key_press sollte nur eine
zurückliefern welche Taste gedrückt wurden ist.
Peter II schrieb:> das hat alles dort nichts zu suchen, key_press sollte nur eine> zurückliefern welche Taste gedrückt wurden ist.
was soviel heisst, dass ich doch mittels Flags arbeiten muss und z.b
nach jeder einzelnen Messung die Flags abfragen muss, was die
Reaktionszeit erheblich verkleinert?!
Rico H. schrieb:> was soviel heisst, dass ich doch mittels Flags arbeiten muss und z.b> nach jeder einzelnen Messung die Flags abfragen muss,
Ja!!!
> was die> Reaktionszeit erheblich verkleinert?!
ja, das system kann dann auch noch andere dinge erledigen.
Peter II schrieb:> Ja!!!
Ok dann werde ich mich mal hinter die Flags setzen..Fragen werden früher
oder später wieder auftauchen, ich bin froh über solch kompetente Leute,
danke vielmas
> ja, das system kann dann auch noch andere dinge erledigen.
andere Dinge?
Ziel ist für mich jetzt folgende implementation, richtig?:
while(1){
Messung 1
Abfrage Flags //falls ein Flag gesetzt, Funktionsaufruf (und jmp
zurück?)
Messung 2
Abfrage Flags
...
Messung 6
Abrage Flags
}
Rico H. schrieb:> Ziel ist für mich jetzt folgende implementation, richtig?:>> while(1){> Messung 1> Abfrage Flags //falls ein Flag gesetzt, Funktionsaufruf (und jmp> zurück?)> Messung 2> Abfrage Flags> ...> Messung 6> Abrage Flags> }
Im Prinzip ja.
Nur kannst du dir ja auch selbst das Leben einfacher machen, indem du
auf COde-Duplizierungen verzichtest, indem du realisierst, dass deine
'Messungen' im Grund ja immer gleich sind, nur mit anderen Zahlenwerten.
Und diese Zahlenwerte kann man zb auch in ein Array stecken, bzw. die
für eine relevante Messung notwendigen Zahlenwerte zuerst in einer
Struktur zusammenfassen und dann davon ein Array machen
1
// was ist alles für EINE Messung an Wissen notwendig?
2
structtempMeasurment{
3
uint8_tADC_Code;
4
uint8_tLCDLine;
5
};
6
7
// und hier sind sie dann. Diese Sensoren (ADC_Code) sind abzufragen
// beim nächsten Schleifendurchlauf kommt dann der nächste Sensor drann
38
// welcher ist das?
39
nrMeas++;
40
if(nrMeas==MEASUREMENT_COUNT)
41
nrMeas=0;
42
43
44
45
// hier dann deine Tastenauswertung
46
AbfrageFlags
47
48
}
49
}
So werden reihum ebenfalls alle Sensoren abgefragt und zwischendurch die
Flags ausgewertet. Bei jedem Durchgang durch die while-Hauptschleife
wird EIN Sensor abgefragt und ausgewertet. Aber eben jedesmal ein
anderer.
Und ... du hast keine Codeduplizierung mehr!
Karl Heinz Buchegger schrieb:> So werden reihum ebenfalls alle Sensoren abgefragt und zwischendurch die> Flags ausgewertet. Bei jedem Durchgang durch die while-Hauptschleife> wird EIN Sensor abgefragt und ausgewertet. Aber eben jedesmal ein> anderer.>> Und ... du hast keine Codeduplizierung mehr!
VIELEN DANK!! Das macht das ganz schon viel Übersichtlicher!! Habe gar
nicht daran gedacht, da ich mich irgendwie völlig im Code verloren
habe..
Ist es sinnvoller die Abfrage der Flags durch IF-Schleifen oder einen
SWITCH zu machen?
Rico H. schrieb:> Ist es sinnvoller die Abfrage der Flags durch IF-Schleifen oder einen> SWITCH zu machen?
a) es gibt keine if - "Schleifen"
eine Schleife ist ein Codestück, in dem etwas wiederholt wird.
Bei einem if wird nichts wiederholt. Ein if ist eine Auswahl
aus 2 Möglickeiten
b) Kann man generell nicht sagen.
Ob man
1
if(Variable==1)
2
....1
3
4
elseif(Variable==2)
5
....2
6
7
elseif(Variable==5)
8
....3
9
10
else
11
....4
schreibt, oder ob man da ein
1
switch(Variable)
2
{
3
case1:
4
....1
5
break;
6
7
case2:
8
....2
9
break;
10
11
case5:
12
....3
13
break;
14
15
default:
16
....4
17
}
draus macht, wird sich nicht viel reissen. Bei einem switch kann
der Compiler besser optimieren und der Wert von 'Variable' wird
nur einmalig ausgewertet. Aber ansonsten ist da auch viel
persönliche Vorliebe dabei.