sei() - und das Programm läuft nicht

Gast #2218424
Lesenswert?

Hi,

wie kann es sein, dass mein Programm nach dem sei() Befehl nicht mehr 
rund läuft. Es wird nur noch die setup() funktion ausgeführt und das 
immer und immer wieder. Die Main while schleife wird nie erreicht. 
Simuliert in AVR-Studio. Ohne sei() funktionierts. Hab ich irgendwo 
ausversehen nen watchdog angeschalten und blicks nicht, oder???
1
int main(void){
2

3
setup();
4

5
while(1){
6
......
7
}
8
return 1;
9
}
10
*
11
*
12
void setup(void){
13
  DDRD = (1<<LEDPIN);
14
  DDRB = 0b00001111; // PB0-1-2-3 ausgang
15
  
16
  Armed = false;
17

18
  //timer0 (8bit) - run 62,5khz
19
  //used to get SumSig
20
  
21
  TCCR0 = (1 << CS02);  //Normal mode - prescalser clk/256
22
            //Overflow nach 4,096ms
23
  TIMSK |= (1<<TOIE0);      //overflow int en
24
  TCNT0 = 0;
25
  GICR = (1<<INT0);                       
26
  MCUCR = ((1<<ISC01)|(1<<ISC00));  //rising edge
27

28
  uart_init();
29
  i2c_init();
30

31
        sei();
32
  _delay_ms(2000);
33
  
34
}//setup

grüße Flo
Gast #2218450
Lesenswert?

DIe ISR stehen über der Setup funktion.
1
volatile unsigned char cSumSig[5];
2
volatile uint8_t channel=0,valid=0;
3

4

5
ISR(TIMER0_OVF_vect){
6
  channel = 0;
7
  valid=0;
8
}
9
ISR(INT0_vect){
10
  if(valid == 1){
11
    cSumSig[channel] = TCNT0;
12
    armed = cSumSig[channel];
13
    channel++;
14
    }
15
  else{
16
    valid=1;
17
    }
18
  TCNT0 = 0;
19
}
Gast #2218553
Lesenswert?

Warum hast du zwei Header für Interrupts mit eingebunden?
#include <avr\interrupt.h>
#include <avr/signal.h>

Durch den Compiler geht der Code immer noch nicht wegen fehlender 
Definition von GyroCalibrated, Armed und uart_init.h
Gast #2218672
Lesenswert?

Es muss #include <avr/interrupt.h> statt #include <avr\interrupt.h> 
heißen.
Durch das falsche Include erzeugt ISR(...) keine ISR und beim ersten 
Interrupt, der Auftritt springt Dein COntroller ins Leere bzw. landet 
wieder am Programmanfang.
Gast #2218700
Lesenswert?

In der Timer-ISR kann man, glaube ich nicht hängenbleiben. Und wenn der 
Compiler eine Datei nicht findet, meckert er schon rum.

Aber, wie ist die Variante?:
Deine 2s-Wartefunktion ist ja aus einer Bibliothek. Also nicht im 
Quelltext enthalten. Bei der Ausführung von delay versucht der 
Simulaotor die Funktion zu finden. Geht nicht, also nimmt er irgendeine 
(ich glaube, die am weitesten hinten im Speicher liegt), und die zeigt 
er dann an. Warte mal ~500 "Sprünge zu Setup" ;-) , dann ist die 
Warteschleife abgearbeitet, die ständig durch die Timer-ISR unterbrochen 
wird.

P.S.:
Michael A. schrieb:
> Das ist ziemlich egal, sonst würde der Compiler heftig meckern

...war wieder mal zu langsam
#2218714
Lesenswert?

Flo schrieb:
> DIe ISR stehen über der Setup funktion.
>
>
1
> volatile unsigned char cSumSig[5];
2
> volatile uint8_t channel=0,valid=0;
3
> 
4
> 
5
> ISR(TIMER0_OVF_vect){
6
>   channel = 0;
7
>   valid=0;
8
> }
9
> ISR(INT0_vect){
10
>   if(valid == 1){
11
>     cSumSig[channel] = TCNT0;
12
>     armed = cSumSig[channel];
13
>     channel++;
14
>     }
15
>   else{
16
>     valid=1;
17
>     }
18
>   TCNT0 = 0;
19
> }
20
>

Kann es sein, dass bei dem sei() direkt ein- bis mehrere INT0 anstehen? 
Darin wird dann munter "channel" inkrementiert, und das - soweit ich 
sehe - auch über 5 hinaus, d.h. wir haben u.U. eine Speicherkorruption.

Viele Grüße,
        Simon
Gast #2218759
Lesenswert?

Ralf schrieb:
> ... Warte mal ~500 "Sprünge zu Setup" ;-) , dann ist die
> Warteschleife abgearbeitet, die ständig durch die Timer-ISR unterbrochen
> wird.

Gutes Argument. Da hatte ich auch zu wenig Gedult mit dem Simulator...
Wenn man das 2s-Delay verkürzt sieht alles gut aus.
Gast #2219924
Lesenswert?

Danke für die Resonanz, aber:
alle vorschläge durchgemacht. Leider kein Erfolg. Jetzt hab ich ein 
neues Projekt erstellt, in dem ich meiner Meinung nach das gleiche 
Interrupthandling implementiert hab. Und hier funktionierts.

Es wird die while Schleife ausgeführt bis eben einer der gewollten 
Interrupts auftritt.

Wieder zurück ins alte Programm..... gleiches Lied. Kommt am setup(); 
Aufruf nicht vorbei. Seh ich den Wald vor Bäumen nicht, oder??

Testversion:
1
//Atmega32 16MHz
2
#include <avr\io.h>
3
#include <avr\interrupt.h>
4
#include <stdlib.h>
5
#include <inttypes.h>
6
#include <stdint.h>
7

8
volatile unsigned char cSumSig[5];
9
volatile uint8_t channel=0,valid=0;
10

11

12
ISR(TIMER0_OVF_vect){
13
  channel = 0;
14
  valid=0;
15
}
16

17
ISR(INT0_vect){
18
  if(valid == 1){
19
    cSumSig[channel] = TCNT0;
20
    
21
    channel++;
22
    }
23
  else{
24
    valid=1;
25
    }
26
  TCNT0 = 0;
27
}
28

29
void setRX(void){
30
  
31
  TCCR0 = (1 << CS02);  //Normal mode - pre clk/256 -->62,5khz
32
                        //Overflow nach 4,096ms
33
  TIMSK |= (1<<TOIE0);        //overflow int
34
  TCNT0 = 0;
35
  GICR = (1<<INT0);    //GIMSK
36
  MCUCR = ((1<<ISC01)|(1<<ISC00));  //rising edge
37
  sei();
38
}
39

40
void main(void){
41
  
42
  DDRD |= (1<<PD0);
43
  setRX();
44

45
  while(1){
46
    PORTD = PIND ^(1<<PD0);
47
    
48
  }
49
}
Gast #2219941
Lesenswert?

Flo schrieb:
> Jetzt hab ich ein
> neues Projekt erstellt, in dem ich meiner Meinung nach das gleiche
> Interrupthandling implementiert hab.

Das ist der Unterschied:
Ralf schrieb:
> Warte mal ~500 "Sprünge zu Setup" ;-) , dann ist die
> Warteschleife abgearbeitet, die ständig durch die Timer-ISR unterbrochen
> wird.

Möglicherweise gravierend.
Und: Hat zwar nichts mit der Funktionalität zu tuen. Lass der 
Init-Funktion die Freude, sich schnell beenden zu können und mach das 
sei() in die main().
Gast #2220167
Lesenswert?

Dann werd ich die uarts mal nachreichen. Glaub aber nicht, dass da ein 
Fehler drin ist. Hab ja nicht ich programmiert :)

Die sei() in die main oder wie in der Testversion in ne eigene RXinit 
rein werd ich heut Abend mal versuchen. Die 2 s Delay kann ich mir dann 
schenken!?
KLappt ja auch ohne warten...
Angehängte Dateien:
#2220314
Lesenswert?

Flo schrieb:
> Dann werd ich die uarts mal nachreichen. Glaub aber nicht, dass da ein
> Fehler drin ist. Hab ja nicht ich programmiert :)

Ist es aber. Diese Zeile ist die Quelle deines Problems:
1
  UCSRB =~(1<<RXEN); // RX enable
Hier werden sämtliche UART-Interrupts erlaubt, und der UDRE-Interrupt 
löst dann sofort nach dem sei() aus. Und da es keine entsprechende ISR 
gibt, gibt es einen Software-Reset und dein Programm beginnt von vorn.
Gast #2220465
Lesenswert?

Das ists !!
MERKE: das nächste mal alles Posten. SORRY.

Aber ich dachte mit
1
UCSRB =~(1<<RXEN);
 wird nur der Empfänger Eingeschalten. Und nur mit setzen des RXCIE bzw. 
TXCIE werden die Interrupts angeschalten!?

Wenn ein Zeichen zu senden ist, wird ja hier
1
while(!(UCSRA & (1<<UDRE)))
gewartet bis der EMpfänger bereit ist. Das ist die Polling Methode,oder? 
Warum läuft während der Zeit der Timer1 weiter, aber der Timer0 nicht?

Ich dachte bisher, da der Timer0 OVF die höhere Priorität hat, dass die 
ISR auf jeden Fall ausgelöst wird während auf UDRE gewartet wird.

Muss ich statt
1
 while(!(UCSRA & (1<<UDRE)))
 - das Senden mit einer ISR handeln? Welchen Vektor muss ich da 
abfangen? USART _RXC | _UDRE | _TXC

grüeß FLo
#2220482
Lesenswert?

Flo schrieb:
> Aber ich dachte mit
1
UCSRB =~(1<<RXEN);
> wird nur der Empfänger Eingeschalten.

Nein, diese Zeile setzt alle Bits in UCSRB auf 1 außer RXEN (und ist 
damit völlig sinnlos).

> Und nur mit setzen des RXCIE bzw.
> TXCIE werden die Interrupts angeschalten!?

Richtig, und genau das passiert in der Zeile.

> Das ist die Polling Methode,oder?

Ja.

> Warum läuft während der Zeit der Timer1 weiter, aber der Timer0 nicht?

Beide Timer laufen weiter.

> Ich dachte bisher, da der Timer0 OVF die höhere Priorität hat, dass die
> ISR auf jeden Fall ausgelöst wird während auf UDRE gewartet wird.

Die ISR löst auch während des Wartens aus (was aber nichts mit 
Proritäten zu tun hat). Oder versuchst du innerhalb einer anderen ISR zu 
senden?
Gast #2220550
Lesenswert?

Nein, das hab ich durcheinander gebracht. Prios sind ja nur bei 
paralellem auftreten der INT's wichtig.

Ich hoffe ja, dass es nur das aktivieren der UART interrupts war was 
mich die letzten 2 Tage geärgert hat.

Thx für die Unterstützung.

FLo

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren