PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [erledigt] globale Variable in ISR ändern + im Hauptprogramm



grumpf
03.02.2008, 12:11
Hai,

ich hab ein Problem mit einer Interrupt-Routine. Ich habe folgenden Code (Ausschnit).



#include <../include/avr/io.h>
#include <../include/avr/interrupt.h>
#include <../include/stdlib.h>
#include <../include/util/delay.h>

volatile uint16_t Zeittick = 0 ;

SIGNAL (TIM1_OVF_vect)
{
// ISR-Code
//PORTB ^= (1<<PB2);
PORTB |= (1 << PB2); /* setzt Bit 3 an PortB auf 1 */
//PORTB &= ~(1 << PB2); /* loescht Bit 3 an PortB */
Zeittick++;

}

int main (void) {
//Zeittick = 0;
if (Zeittick >= 20)
{
//PORTB ^= (1<<PB3);
//Zeittick = 0;
PORTB |= (1 << PB3); // setzt Bit 3 an PortB auf 1
}


Die ISR "TIM1_OVF_vect" wird angesprungen, der Timer läuft, alles prima. Aber die If-Abfrage im Hauptprogramm wird einfach nich ausgeführt. Stecke ich diese Abfrage in die ISR gehts. Wo hab ich da einen Fehler drin ? Wie kann ich eine Variable in einer ISR sonst manipulieren und im Hauptprogramm abfragen ?
Ist die If-Agbfrage in der ISR taucht das Problem auf, dass die Variable Zeittick bei einem Softreset nicht zuverlässig auf Null gesetzt wird. ICh versteh aber nicht warum.... :(

Internette Grüße
Stefan

Moritz f.
03.02.2008, 16:04
Hallo,
ist das wirklich dein ganzer Source Code? Denke nicht, so würde das ja nicht mal kompilieren. . .

Das if ist denke ich in ner Endlosschleife drin, oder?

und warum hast du sachen die zeittick=0 auskommentiert?

lg MoFe

grumpf
03.02.2008, 17:42
Hallo Moritz,

natürlich ist das nicht mein ganzer Code. Es ist nur der interessante Ausschnitt. Vom Rest weiß ich, dass es läuft. Du hast recht hinter der If-Abfrage kommt noch eine Endlosschleife. Mir geht es auch nur darum erst mal zu sehen, dass die entsprechende LED (PB3) überhaupt reagiert wenn die if-Abfrage im Hauptprogramm ist. Die auskommentierten Stellen sollen ein wenig zeigen, was ich schon versucht hab. Das Programm macht so, wie es da steht keinen Sinn, da geb ich dir Recht. Das Problem mit der globalen Variable kann man aber denke ich nachvollziehen. Bei Interesse poste ich auch den gesamten Code, der ist aber denke ich erstmal unwichtig.

Internette Grüße
Stefan

PicNick
03.02.2008, 18:06
Mit 16bit / 2 byte Variablen ist das so eine Sache zwischen ISR und Main.
Ich persönlich mache meist solche "if"s in der ISR und setze nur einen Flag für die Mainroutine

Eigentlich aber seh ich keinen Fehler. Versuch wirklich einfach mal ein uint8_t , also nur ein Byte

Hubert.G
03.02.2008, 18:40
Du hast recht hinter der If-Abfrage kommt noch eine Endlosschleife.
Wenn die Endlosschleife nach der if-Schleife beginnt, kann sie ja nicht angesprungen werden.

grumpf
03.02.2008, 19:39
Hallo an alle,

danke für eure prompten Antworten. Leider bin ich immer noch nicht weiter. Die If-Abfrage muss natürlich in die Endlosschleife. Ich hatte vorher da stehen Zeittick = 0 und in der if-Abfrage if Zeittick == 1
Habe die Abfrage jetzt wieder in die Endlosschleife genommen, aber ohen Erfolg. Auch die Verwendung einer unit8_t Variable brachte keinen Unterschied :(
Ich poste mal den gesamten Code, vielleicht hab ich ja doch anderer Stelle einen Denkfehler.....


#include <../include/avr/io.h>
#include <../include/avr/interrupt.h>
#include <../include/stdlib.h>
#include <../include/util/delay.h>

#define UPPPER_BOUND 10

volatile uint8_t Zeittick ;




int myRand( int UpperBound )
{
int x;

while( (x = rand()) >= RAND_MAX - (RAND_MAX % UPPPER_BOUND) )
;
return x % UPPPER_BOUND;
}

// Eine nichtunterbrechbare Interrupt-Service-Routine
SIGNAL (TIM1_COMPA_vect)
{
// ISR-Code
//PORTB ^= (1<<PB2);
//PORTB |= (1 << PB2); // setzt Bit 3 an PortB auf 1
PORTB &= ~(1 << PB2); // loescht Bit 3 an PortB
Zeittick = Zeittick + 1;

}

SIGNAL (TIM1_OVF_vect)
{
// ISR-Code
//PORTB ^= (1<<PB2);
PORTB |= (1 << PB2); /* setzt Bit 3 an PortB auf 1 */
//PORTB &= ~(1 << PB2); /* loescht Bit 3 an PortB */
Zeittick = Zeittick + 1;

}
void long_delay(uint16_t ms) {
for(uint16_t temp=0; temp<=ms; temp++){ _delay_ms(1);}
}
int main (void) {
//Zeittick = 0;



// allgemein
GTCCR = 0b11100001; // Timer anhalten
SREG |= (1 << 7);
GIMSK = 0b00100000;
PCMSK = 0b00000100;
// Timer 0
TCCR0A = 0b11100001; // Timer0 A und B auf Phasecorrect PWM-Mode
// und löschen bei erreichen des Werte in OC0A bzw.
// OC0B
TCCR0B = 0b00000010; // WGM02-Bit löschen für PWM-POhase-Correct-Mode
// OC0A-Ausgang wird beim hchzählen gesetzt und
// beim runterzählen gelöscht
// und Prescaler auf clk/1024 einstellen

OCR0A = 0b01100011; // Output-Compare-Register einstellen
OCR0B = 0b00101111; // Output-Compare-Register einstellen

// Timer 1
TCCR1 = 0b01000101;
OCR1A = 0b11000000;
OCR1B = 0b00011111;
OCR1C = 0b11111111;


TIMSK = 0b01000100;
// sei();

// OCR1A = 0b01111111;
// OCR1B = 0b00111111;

DDRB = 0b11111111; // PortB auf Ausgabe stellen
GTCCR = GTCCR & 0b11111110 ;//0b00000000; // Timer starten

uint8_t Dauer_LED1 = 2;//myRand(255);
uint8_t Helligkeit_LED1 = 255;//myRand(255);
uint8_t LED1;

while(1) {
if (Zeittick >= 3)
{
//PORTB ^= (1<<PB3);
//Zeittick = 0;
PORTB |= (1 << PB3); // setzt Bit 3 an PortB auf 1
}



/*
for (LED1 = 0; LED1<Helligkeit_LED1;LED1++)
{
OCR1B=LED1;
_delay_ms(Dauer_LED1);
}
//PORTB |= (1 << PB2); // setzt Bit 3 an PortB auf 1
//long_delay(1000);
for (LED1 = 0; (Helligkeit_LED1-LED1)>0;LED1++)
{
OCR1B=255-LED1;
_delay_ms(Dauer_LED1);
}
*/
//PORTB &= ~(1 << PB2); // loescht Bit 3 an PortB

//long_delay(1000);

/*
OCR0A = 100;
long_delay(1000); // Eine Sekunde warten...
OCR0A = 1;
long_delay(1000); // Eine Sekunde warten...
*/
//PORTB |= (1 << PB2); /* setzt Bit 3 an PortB auf 1 */
}

return 0;
}

Ich verstehs nicht. Wenn noch jemand eine Idee hat wäre das klasse. Nur noch als Info, mit diesem Code könnt ihr alle vier PWM Kanäle des Tiny25 nutzen, klappt prima. Nur eben bis auf die Geschichte mit der globalen Variable.

Internette Grüße
Stefan

McJenso
03.02.2008, 21:01
Hallo,

deine Schreibweise finde ich immer noch nicht schön. Aber das muss ich ja auch nicht. Einige Zeilen sind aber ganz ansehnlich und da fällt mir auf den ersten Blick :wink: auf:
in der ISR
PORTB &= ~(1 << PB2); // loescht Bit 3 an PortB
in main
PORTB |= (1 << PB3); // setzt Bit 3 an PortB auf 1

Da passt doch was nicht.

Einen Reset mit Software löst du am besten über den Watchdog aus oder du ziehst über einen Pin den Reset auf 0. Dann wird auch auch alles richtig initialisiert.

Gruß

Jens

grumpf
04.02.2008, 08:58
Hallo Jens,

hast recht, die Kommentare stimmen nicht ganz, was vor den // steht zählt, in sofern ist das schon korrekt. Ändert aber auch nichts an dem Problem der Variablenübergabe von ISR zu Main mittels globaler Variable. Das mit dem Reset hat mich auch verwundert. Ich nutze ein STK500 zum entwickeln. Wenn ich dort die Reset-Taste drücke, wird die Variable Zeittick anscheinend nicht initialisiert. Durch die Reset-Taste bin ich ja erst auf die Sache überhaupt aufmerksam geworden.

Internette Grüße
Stefan

PicNick
04.02.2008, 09:04
Ist die Groß-Kleinschreibung sicher korrekt ?
TIM1_OVF_vect

(GCC macht sich da ins Halstuch)

grumpf
04.02.2008, 10:06
Hai,

die Schreibweise ist korrekt, ich hab sie direkt aus dem Header-File kopiert und die ISR werden ja auch angesprungen.

Internette Grüße
Stefan

PicNick
04.02.2008, 10:20
Gut.
Im Grunde verhält sich dein Programm einfach so, als würde da nicht "volatile" stehen.
Kannst du die "*.LSS" - Datei posten ? Da müßte drinstehen, was der Wurstel tatsächlich übersetzt hat oder nicht.

grumpf
04.02.2008, 20:40
Hai,

so wie es aussieht, übersetzt der Compiler die Variablen-Deklaration überhaupt nicht ?! HAb mal den Code bis zur ersten ISR gepostet. Die Variablen-Deklaration müsste vorher sein, ich finde sie aber nicht.




main.elf: file format elf32-avr

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000356 00000000 00000000 00000094 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000004 00800060 00000356 000003ea 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000001 00800064 00800064 000003ee 2**0
ALLOC
3 .stab 00000360 00000000 00000000 000003f0 2**2
CONTENTS, READONLY, DEBUGGING
4 .stabstr 00000071 00000000 00000000 00000750 2**0
CONTENTS, READONLY, DEBUGGING
5 .debug_aranges 00000020 00000000 00000000 000007c1 2**0
CONTENTS, READONLY, DEBUGGING
6 .debug_pubnames 00000060 00000000 00000000 000007e1 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_info 00000202 00000000 00000000 00000841 2**0
CONTENTS, READONLY, DEBUGGING
8 .debug_abbrev 0000012f 00000000 00000000 00000a43 2**0
CONTENTS, READONLY, DEBUGGING
9 .debug_line 00000217 00000000 00000000 00000b72 2**0
CONTENTS, READONLY, DEBUGGING
10 .debug_frame 00000060 00000000 00000000 00000d8c 2**2
CONTENTS, READONLY, DEBUGGING
11 .debug_str 00000127 00000000 00000000 00000dec 2**0
CONTENTS, READONLY, DEBUGGING
12 .debug_loc 00000058 00000000 00000000 00000f13 2**0
CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:

00000000 <__vectors>:
0: 0e c0 rjmp .+28 ; 0x1e <__ctors_end>
2: 27 c0 rjmp .+78 ; 0x52 <__bad_interrupt>
4: 26 c0 rjmp .+76 ; 0x52 <__bad_interrupt>
6: 26 c0 rjmp .+76 ; 0x54 <__vector_3>
8: 37 c0 rjmp .+110 ; 0x78 <__vector_4>
a: 23 c0 rjmp .+70 ; 0x52 <__bad_interrupt>
c: 22 c0 rjmp .+68 ; 0x52 <__bad_interrupt>
e: 21 c0 rjmp .+66 ; 0x52 <__bad_interrupt>
10: 20 c0 rjmp .+64 ; 0x52 <__bad_interrupt>
12: 1f c0 rjmp .+62 ; 0x52 <__bad_interrupt>
14: 1e c0 rjmp .+60 ; 0x52 <__bad_interrupt>
16: 1d c0 rjmp .+58 ; 0x52 <__bad_interrupt>
18: 1c c0 rjmp .+56 ; 0x52 <__bad_interrupt>
1a: 1b c0 rjmp .+54 ; 0x52 <__bad_interrupt>
1c: 1a c0 rjmp .+52 ; 0x52 <__bad_interrupt>

0000001e <__ctors_end>:
1e: 11 24 eor r1, r1
20: 1f be out 0x3f, r1 ; 63
22: cf ed ldi r28, 0xDF ; 223
24: cd bf out 0x3d, r28 ; 61

00000026 <__do_copy_data>:
26: 10 e0 ldi r17, 0x00 ; 0
28: a0 e6 ldi r26, 0x60 ; 96
2a: b0 e0 ldi r27, 0x00 ; 0
2c: e6 e5 ldi r30, 0x56 ; 86
2e: f3 e0 ldi r31, 0x03 ; 3
30: 03 c0 rjmp .+6 ; 0x38 <.do_copy_data_start>

00000032 <.do_copy_data_loop>:
32: c8 95 lpm
34: 31 96 adiw r30, 0x01 ; 1
36: 0d 92 st X+, r0

00000038 <.do_copy_data_start>:
38: a4 36 cpi r26, 0x64 ; 100
3a: b1 07 cpc r27, r17
3c: d1 f7 brne .-12 ; 0x32 <.do_copy_data_loop>

0000003e <__do_clear_bss>:
3e: 10 e0 ldi r17, 0x00 ; 0
40: a4 e6 ldi r26, 0x64 ; 100
42: b0 e0 ldi r27, 0x00 ; 0
44: 01 c0 rjmp .+2 ; 0x48 <.do_clear_bss_start>

00000046 <.do_clear_bss_loop>:
46: 1d 92 st X+, r1

00000048 <.do_clear_bss_start>:
48: a5 36 cpi r26, 0x65 ; 101
4a: b1 07 cpc r27, r17
4c: e1 f7 brne .-8 ; 0x46 <.do_clear_bss_loop>
4e: 36 d0 rcall .+108 ; 0xbc <main>
50: 81 c1 rjmp .+770 ; 0x354 <_exit>

00000052 <__bad_interrupt>:
52: d6 cf rjmp .-84 ; 0x0 <__vectors>

00000054 <__vector_3>:
}

// Eine nichtunterbrechbare Interrupt-Service-Routine
SIGNAL (TIM1_COMPA_vect)
{
54: 1f 92 push r1
56: 0f 92 push r0
58: 0f b6 in r0, 0x3f ; 63
5a: 0f 92 push r0
5c: 11 24 eor r1, r1
5e: 8f 93 push r24
// ISR-Code
//PORTB ^= (1<<PB2);
//PORTB |= (1 << PB2); // setzt Bit 3 an PortB auf 1
PORTB &= ~(1 << PB2); // loescht Bit 3 an PortB
60: c2 98 cbi 0x18, 2 ; 24
Zeittick = Zeittick + 1;
62: 80 91 64 00 lds r24, 0x0064
66: 8f 5f subi r24, 0xFF ; 255
68: 80 93 64 00 sts 0x0064, r24
6c: 8f 91 pop r24
6e: 0f 90 pop r0
70: 0f be out 0x3f, r0 ; 63
72: 0f 90 pop r0
74: 1f 90 pop r1
76: 18 95 reti

00000078 <__vector_4>:

}

SIGNAL (TIM1_OVF_vect)
{
.......




Muss ich mir wohl was anderes einfallen lassen, hat jemand eine Idee ?

Internette Grüße
Stefan

Nachtrag: es sieht so aus, als würde der Compiler sämtliche Variablen-Deklarationen außerhalb des HAuptprogramms bzw. der Unterprogramme ignorieren?!

PicNick
05.02.2008, 08:14
62: 80 91 64 00 lds r24, 0x0064
66: 8f 5f subi r24, 0xFF ; 255
68: 80 93 64 00 sts 0x0064, r24


Das wär ja ok.

Jetzt haben wir aber den anderen Teil noch nicht gesehn.

Sparst Du ?

grumpf
05.02.2008, 18:46
nö, ich spare nicht. Ich erhielt nur die Nachricht, dass mein Beitrag zu lang wäre, daher dachte ich, ich beschränke mich auf den (wichtigen?) Anfang. Aber ich kann die Datei natürlich auch als Attachment dranhängen, hatte ich garnicht dran gedacht.

Internette Grüße
Stefan

die Datei bitte in main.lss umbenennen, ist unsinnig 21kb zu zippen, aber anders akzeptiert das Forum die Datei nicht (?)

PicNick
05.02.2008, 19:23
:oops: Ich dachte nur, weil grad' der interessante Teil gefehlt hat :oops:

Also, an der Variablen "Zeittick" liegt es jedenfalls nicht
Sie ist auf der addresse 0x0064, und genau da greifen sowohl die ISR's als auch dein Main-Vergleich hin.


// Eine nichtunterbrechbare Interrupt-Service-Routine
SIGNAL (TIM1_COMPA_vect)
{
Zeittick = Zeittick + 1;
62: 80 91 64 00 lds r24, 0x0064
66: 8f 5f subi r24, 0xFF ; 255
68: 80 93 64 00 sts 0x0064, r24

}
SIGNAL (TIM1_OVF_vect)
{
Zeittick = Zeittick + 1;
86: 80 91 64 00 lds r24, 0x0064
8a: 8f 5f subi r24, 0xFF ; 255
8c: 80 93 64 00 sts 0x0064, r24

}

int main (void)
{
while(1)
{
if (Zeittick >= 3)
f8: 80 91 64 00 lds r24, 0x0064
fc: 83 30 cpi r24, 0x03 ; 3
fe: e0 f3 brcs .-8 ; 0xf8
{
PORTB |= (1 << PB3); // setzt Bit 3 an PortB auf 1
100: c3 9a sbi 0x18, 3 ; 24
102: fa cf rjmp .-12 ; 0xf8 <__stack+0x19>
}
}
}

Das kann man also vergessen. Beide ISR's zählen am Zeitticker ?

Jetzt muß man das Timer u. Interrupt Setup auf Richtigkeit checken, denn wenn die laufen, MUSS die main-routine irgendwann >=3 erkennen.

grumpf
05.02.2008, 19:35
ich hab die Variable Zeittick mal in beide ISR geschrieben um überhaupt eine Reaktion zu bekommen, leider Fehlanzeige. Die Interrupts arbeiten einwandfrei, ich nutze sie ja auch um Port-Pin PB2 zu manipulieren und der tut wie von ihm erwartet. Ich hätte jetzt spontan auf ein Peoblem mit dem Compiler getippt (AVR-GCC), aber du hast recht, wenn man sich die Speicherzugriffe mal ansieht, sollte es laufen :(

Internette Grüße
Stefan

izaseba
06.02.2008, 20:20
Hallo,

Kann sein, daß Du ein Hardwareproblem hast ?
PB3 geschossen, LED defekt, kalte Lötstelle ?
An der Software liegt es meiner Meinung nach nicht.

Gruß Sebastian

grumpf
07.02.2008, 08:06
Hai,

ich hab auch schon daran gedacht, aber die LED funktioniert. Wenn ich sie direkt ansteuere tut sie wie erwartet. Ich fürchte das wird so langsam mystisch und transzendental. Werde mir wohl einen anderen Weg suchen müssen :(
Sollte ich noch was finden, meld ich es hier. Hat denn noch niemand mit dem Tiny25 gearbeitet und könnte mal das Programm ausprobieren ?
Ich bleib am Ball

Internette Grüße
Stefan

izaseba
07.02.2008, 18:41
Da ich T25 da habe und mein stk500 ausgepackt liegt, habe ich mal eben schnell ein Testaufbau gemacht und Dein Programm geflasht.

PB3 Bleibt in der Tat Low, PB 2 Toogelt fröhlich vor sich hin.

Ich habe kurz Dein Code überflogen , was fällt auf, außer, daß Dein getipse keien Sau lesen kann(will) ?

in TCCR1 ist PWM1A gesetzt, was sagt das Dattenblatt dazu :

When set(one) this Bit enables PWM mode based on comparator OCR1A in Timer/Counter1 and the counter value is reset to $00 in the CPU clock cycle after a compare match with OCR1C register value

Man schaue was Du in OCR1C drin hast ? 0b11111111

Frage, findet ein Überlauf statt ?

Gruß Sebastian

grumpf
07.02.2008, 20:07
Hai Sebastian,

ja, genau weil PB2 toggelt, weiß ich, dass die ISR angesprungen wird. Es geht mir ja auch um PB3. Die sollte reagieren. Das tut sie auch nicht, wenn ich Zeittick in beiden ISR inkrementiere. Daraus schließe ich, dass etwas mit der Übergabe der Variablen Zeittick nicht stimmt. PB2 tut wie von ihm erwartet, es geht aber um PB3 (kann man übrigens in meinem Code durchaus erkennen, oder ? O:) )

Internette Grüße
Stefan

McJenso
07.02.2008, 20:47
Hallo,

ich rufe gleich Scully und Mulder, das scheint ja ein Fall für die beiden zu werden. Bis die da sind, hast du mal innerhalb der ISR geprüft, ob Zeittick inkrementiert wird? Nimm mal die Optimierung raus, musst dann natürlich auch die delays löschen. Und kommentiere alles raus, was nicht gebraucht wird. Irgend eine Änderung?

Gruß

Jens

izaseba
07.02.2008, 20:52
Sorry,
ich hatte irgendwie den Overflow interrupt im Kopf...
ich wollte es genau wissen !
Habe meinen Dragon ausgepackt und Tin draufgesteckt.
Folgende Erkentnisse :

SIGNAL (TIM1_COMPA_vect) wird garnicht angesprungen
SIGNAL (TIM1_OVF_vect) wird genau 2 Mal angesprungen dabei wird Zeittick beim ersten mal 1 beim zweitem 2 und beim Verlassen des Interrupts macht der Tiny einen Reset und fängt in der main von vorne an ?
Komisch das...

Gruß Sebastian

izaseba
07.02.2008, 21:04
Ehm, sorry, ich bin irgendwie durch den Wind heute, es ist anders

Zuerst Springt er in die Overflow, dann in die Comp, da kommt der wieder in die if Abfrage rein und danach macht es erst den reset ?

izaseba
07.02.2008, 21:33
So hier ist ein Programm, daß auch funktioniert


#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <util/delay.h>

volatile uint8_t Zeittick ;



ISR (TIMER1_COMPA_vect)
{
PORTB ^= (1 << PB2)|(1<<PB3); // loescht Bit 3 an PortB
Zeittick = Zeittick + 1;

}

int main (void) {
DDRB = (1<<PB3)|(1<<PB2);
TCCR1 = (1<<PWM1A)|(1<<COM1A1)|(1<<CS11);
OCR1A = 0x80;
OCR1C = 0xFF;
TIMSK = (1<<OCIE1A);
sei();

while(1) {
if (Zeittick >= 3)
{
PORTB ^= (1 << PB3); // setzt Bit 3 an PortB auf 1
}

}

return 0;
}


Was mir noch auffällt ist ist die Bunte Mischung aus SIGNAL und *_vect hier


SIGNAL (TIM1_OVF_vect)

Ob das was zu sagen hat , weiß ich nicht

grumpf
08.02.2008, 08:01
Guten Morgen,

danke erst mal für euer Engagement, finde ich super. Die Sache mit der Optimierung werd ich mir ansehen, klingt garnicht schlecht.
@Sebastian, danke für den Code werde ihn mal testen. So im ersten überfliegen seh ich keinen Unterschied zu meinem Code (ok er sieht ordentlicher aus O:) , aber inhaltlich? ) Werd ihn mal genau vergleichen und studieren, danke erstmal.
Ich melde mich mit den Ergebnissen....

Internette Grüße
Stefan

grumpf
09.02.2008, 21:01
Guten Abend,

also so langsam gehen mir die Ideen aus. Ich hab mal deinen Code genommen und compiliert. Das Ergebnis ist das gleiche wie bei mir. Anscheinend wird der Zeittick nicht global verändert. Kannst du mir mal dein hex-File schicken, vielleicht liegts ja an meinem Compiler oder an meinen Einstellungen. Ich häng mal mein Makefile an. Seht ihr da einen Fehler ? Die *.txt Endung ist nur fürs Forum.
Ich hab auch alle Optimierungsstufen durchprobiert, Ergebnis negativ. Das kann doch alles nicht sein. Ich glaub ich werd doch lieber Gärtner...

Internette Grüße
Stefan
PS: hab grad was interessantes entdeckt. Schreibe ich in die Overflow ISR NUR meinen Zeittick rein, geht es. Die Variable wird im Hauptprogramm richtig erkannt. Steht noch eine weitere Zeile in der ISR geht es nicht ?! Es spielt auch keine Rolle wo der Zeittick steht, ist die Zeile allein - ok ; ist eine weitere Zeile dabei - nicht ok

grumpf
10.02.2008, 00:16
ich hab das Problem gelöst, auch wenn ich nicht weiß wieso. Wo liegt der Unterschied zwischen folgenden beiden Codes (außer dass ich in der ISR einen anderen Pin manipuliere)

Dieser Code geht....


#include <../include/avr/io.h>
#include <../include/avr/interrupt.h>
#include <../include/stdlib.h>

volatile uint16_t Zeittick ;

// Eine nichtunterbrechbare Interrupt-Service-Routine
SIGNAL (TIM1_COMPA_vect)
{
PORTB &= ~(1 << PB1); // loescht Bit 1 an PortB
}

SIGNAL (TIM1_OVF_vect)
{
PORTB |= (1 << PB1); // setzt Bit 1 an PortB auf 1
Zeittick=Zeittick +1;
}

int main (void) {
// allgemein
GTCCR = 0b11100001; // Timer anhalten
SREG |= (1 << 7);
GIMSK = 0b00100000;
PCMSK = 0b00000100;
// Timer 1
TCCR1 = 0b01001100;
OCR1A = 123; //LED2
OCR1B = 200; //LED4
OCR1C = 0b11111111;
TIMSK = 0b01000100;

DDRB = 0b11111111; // PortB auf Ausgabe stellen
GTCCR = GTCCR & 0b11111110 ;// Timer starten
while(1) {
if (Zeittick==5)
{
PORTB ^= (1<<PB3);
Zeittick = 0;
}
}
return 0;
}



und dieser geht nicht...


#include <../include/avr/io.h>
#include <../include/avr/interrupt.h>
#include <../include/stdlib.h>

volatile uint16_t Zeittick ;

// Eine nichtunterbrechbare Interrupt-Service-Routine
SIGNAL (TIM1_COMPA_vect)
{
PORTB &= ~(1 << PB2); // loescht Bit 2 an PortB
}

SIGNAL (TIM1_OVF_vect)
{
PORTB |= (1 << PB2); // setzt Bit 2 an PortB auf 1
Zeittick=Zeittick +1;
}

int main (void) {
// allgemein
GTCCR = 0b11100001; // Timer anhalten
SREG |= (1 << 7);
GIMSK = 0b00100000;
PCMSK = 0b00000100;
// Timer 1
TCCR1 = 0b01001100;
OCR1A = 123; //LED2
OCR1B = 200; //LED4
OCR1C = 0b11111111;
TIMSK = 0b01000100;

DDRB = 0b11111111; // PortB auf Ausgabe stellen
GTCCR = GTCCR & 0b11111110 ;// Timer starten
while(1) {
if (Zeittick==5)
{
PORTB ^= (1<<PB3);
Zeittick = 0;
}
}
return 0;
}


Auch wenn ich nicht verstehe, warum. Aber immerhin kann ich jetzt weiterprogrammieren. Wenn es mir jemand erklären kann wäre ich etwas schlauer.

Internette Grüße
Stefan

grumpf
10.02.2008, 17:05
Hai,

das Problem hat mir einfach keine Ruhe gelassen. Jetzt viele Kaffee und wenig schlaf später hab ich es, glaube ich gefunden. Das kommt davon, wenn man so viele Dinge auf einmal testen will. Das Problem liegt in dem aktivierten PIN-Interrupt "PCMSK = 0b00000100; ". Den hatte ich auch mal getestet und leider aktiviert gelassen. Das Interrupt hab ich gelassen, die ISR allerdings gelöscht bzw. auskommentiert. Lege ich eine leere ISR an oder deaktiviere das Interrupt klappt alles wie erwartet.
Danke an alle, die an der Lösungs dieses Problems mitgewirkt haben.

Internette Grüße
Stefan

izaseba
10.02.2008, 22:14
Hallo,
Pin Change Interrupt ?
hehe, das erklärt auch das verhalten beim Debuggen...
Da hast Du Dir einen wirklich fiesen Fehler eingebaut :-(

Gruß Sebastian

P.S. Brauchst Du immer noch meine hex Datei ?

grumpf
11.02.2008, 13:53
Hai Sebastian,

nein, danke. Ich brauch sie nicht mehr.

Internette Grüße
Stefan