Hallo,
ich verstehe die Welt nicht mehr, daher, please help.
(Ich verwende AVR Studion 4 mit GNU GCC Compiler für AVR Mega; Sprache:
Standard "C")
Problem:
Im hauptprogramm setze ich nach der Initialisierung in der
Hauptprogrammschleife sekündlich eine global deklarierte Steuervariable
"OneWireFlag", die im Time-Compare-Intterrupt (Timerclock 0,5 us)
ausgewertet wird. danach wird ein kurzes Stepping durchlaufen, wobei die
Steuervariable das Ganze händelt.
Soweit, so gut, das geht alles. Am Ende wird die Steuervariable auif
einen "Endcode", hier 0x88 gesetzt.
Das Hauptprogramm wartet nun in einer while-Schleife auf diesen Endcode.
Solange die Warteschleife nur aus:
while (OneWireFlag != 0x88) {
wdt_reset()
}
besteht, funktioniert es nicht. Die Schleife wird nie verlassen, bzw.
der Wert von OneWireFlag wird nicht ausgewertet.
Das klappt dann erst, wenn ich zusätzlich eine komplexere Subroutine in
der Schleife aufrufe. Nur das einfügen von Inline "nop" bringt nichts...
Für mich ist das ein Compilerproblem bzw. ein Optimierungsproblem???
Hat einer eine Idee? Mir fehlen dazu die Erfahrungen mit dem GNU GCC.
Danke.
So, die Programmschipsel hänge ich mal an:
Ausschnitt aus dem Hauptprogramm:
Aufruf der Subroutine
Die Subroutine (Testversion)
1 | U8 OneWire_ReadRom(void)
|
2 | {
|
3 | U8 i, crc;
|
4 | OneWire_Write_Byte(0xF0);
|
5 | crc=0;
|
6 | return crc;
|
7 | }
|
8 | U8 OneWire_Write_Byte(U8 WriteByte)
|
9 | {
|
10 | U8 i;
|
11 | for (i = 0;i < 8; i++){
|
12 | OneWireFlag = OneWire_Write_Bit(WriteByte & (1 << i));
|
13 | }
|
14 | OneWireFlag=0;
|
15 | return OneWireFlag;
|
16 | }
|
17 | U8 OneWire_Write_Bit(U8 Bitwert)
|
18 | {
|
19 | if (Bitwert == 0) {
|
20 | OneWireFlag = 0x10; // write 0
|
21 | } else {
|
22 | OneWireFlag = 0x20; // write 1
|
23 | }
|
24 | while (OneWireFlag != 0x88) //DIESE BOESE WARTSCHLEIFE
|
25 | {
|
26 | // csabs(2,1); // mit geht, ohne nicht...
|
27 | wdt_reset();
|
28 | }
|
29 | return OneWireFlag;
|
30 | }
|
Die Timer-Rouine (gekürzt)
1 | ISR (TIMER1_COMPC_vect) //fuer 0newire bus / divers
|
2 | {
|
3 | // timer zaehlt mit 0.5 us
|
4 | U16 Icompvalue;
|
5 | Icompvalue = OCR1C;
|
6 | if (OneWireFlag == 1) {
|
7 | ...............................
|
8 | ...............................
|
9 |
|
10 | } else if (OneWireFlag == 0x10) {
|
11 | OneWirePortWrite &= ~(1<<OneWirePortPin); //pin = 0
|
12 | OneWirePortDir |= (1<< OneWirePortPin); // dir = output
|
13 | OneWireFlag = 0x11;
|
14 | Icompvalue += 64*2; //64 us low
|
15 | OCR1C = Icompvalue;
|
16 | } else if (OneWireFlag == 0x11) {
|
17 | // PORTB ^= 0x80; /// xtc
|
18 | OneWirePortDir &= ~(1<<OneWirePortPin); // Release
|
19 | OneWireFlag = 0x88;
|
20 | Icompvalue += 50 * 2; //50 us wait
|
21 | OCR1C = Icompvalue;
|
22 |
|
23 | // schreibe 1
|
24 | } else if (OneWireFlag == 0x20) {
|
25 | OneWirePortWrite &= ~(1<<OneWirePortPin); //pin = 0
|
26 | OneWirePortDir |= (1<< OneWirePortPin); // dir = output
|
27 | _noppen();
|
28 |
|
29 |
|
30 | OneWireFlag = 0x21;
|
31 | Icompvalue += 4*2; //2 us low
|
32 | OCR1C = Icompvalue;
|
33 | } else if (OneWireFlag == 0x21) {
|
34 |
|
35 | OneWirePortDir &= ~(1<<OneWirePortPin); // Releas resp hig
|
36 | Icompvalue += 64*2; //64
|
37 | OCR1C = Icompvalue;
|
38 | OneWireFlag = 0x22;
|
39 | } else if (OneWireFlag == 0x22) {
|
40 | OneWirePortDir &= ~(1<<OneWirePortPin); // Release
|
41 | OneWireFlag = 0x88;
|
42 | Icompvalue += 50 * 2; //50 us wait
|
43 | OCR1C = Icompvalue;
|
44 |
|
45 |
|
46 | } else if (OneWireFlag == 0x88) {
|
47 | Icompvalue += 50*2; //50 us warten
|
48 | OCR1C = Icompvalue;
|
49 | } else if (OneWireFlag == 0x0) {
|
50 | Icompvalue += 200;
|
51 | OCR1C = Icompvalue;
|
52 | } else {
|
53 | Icompvalue += 20000; //10 ms
|
54 | OCR1C = Icompvalue;
|
55 | }
|
56 | }
|