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???
Flo schrieb:> wie kann es sein, dass mein Programm nach dem sei() Befehl nicht mehr> rund läuft.
Du hast keinen Interrupt-Handler definiert.
Viele Grüße,
Simon
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
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.
Matt schrieb:> Es muss #include <avr/interrupt.h> statt #include <avr\interrupt.h>> heißen.
Das ist ziemlich egal, sonst würde der Compiler heftig meckern
(kommentier den Aufruf mal ganz raus).
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
Flo schrieb:> DIe ISR stehen über der Setup funktion.>>
1
>volatileunsignedcharcSumSig[5];
2
>volatileuint8_tchannel=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
vielleicht lässt auch das 2sec-Delay den Watchdog ansprechen.
Wird zwar nicht vom setup() initialisiert, aber was ist wenn die
"Watchdog Always On"-Fuse gesetzt ist?
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.
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
volatileunsignedcharcSumSig[5];
9
volatileuint8_tchannel=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
voidsetRX(void){
30
31
TCCR0=(1<<CS02);//Normal mode - pre clk/256 -->62,5khz
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().
Flo schrieb:> Testversion:
Diese Version auf einen mega8 @3.6864 MHz gespielt mit PD2 als Ausgabe,
schaltet alle 18.4 µs den Pin kurz auf low.
so well...
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...
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.
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
> 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?
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