Hallo, ich verwende einen ATMega16, WinAVR und Ponyprog. In einer Anwendung verwende ich den UART um Daten zwischen PC und uC auszutauschen. Die Kommunikation geht interruptgesteuert, also mit RXIE, TXIE usw... In einer anderen Anwendung verwende ich einen Timer mit dessen Hilfe ich ein paar Servomotoren steuere. Auch interrupt gesteuert. Beides funktioniert einzeln sehr gut. Wenn ich aber in meinem UART-Programm das Servosteuermodul einbauen will funktionierts nicht. Ich bekomme keinen Datenaustausch mehr hin. Ich hab auch schon heraus woran es ungefaehr liegt: Ich initialisiere den UART und anschliessen den Timer (interrupt flags setzen usw...). Wenn ich den Timer starte (CS-bits setzen) funktioniert es nicht mehr. Wenn ich die Zeile mit TCCR2 |= ... wie unten auskommentier funktioniert mein UART. Mit der Zeile funktioniert er nicht. //Initialization of UART UBRRH=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU)>>8); UBRRL=(uint8_t)UART_BAUD_CALC(UART_BAUD_RATE,F_CPU); UCSRB |= (1<<RXEN) | (1<<TXEN); // enable RxD & TxD UCSRB |= (1<<RXCIE) | (1<<TXCIE);// enable Rx- and Tx- interrupts //Timer2 config (8bit) TIMSK=0x00; //TCCR2 |= (1<<CS22) | (1<<CS21) | (1<<CS20); SETBIT(TIMSK, TOIE2); // overflow interrupt enable Timer2 Wo liegt da ein Zusammenhang? Wo ist das Problem? freue mich über Tips! mg, Johannes
Ohne halbwegs kompletten Quelltext wird Dir niemand helfen können. Bau am besten mal ein lauffähiges Minimalbeispiel, um den Fehler zu reproduzieren, oft findet man die Ursache dann auch selbst. Eine Vermutung: Die Timer-ISR braucht zu lange, z.B. durch Warteschleifen innerhalb der ISR, so daß die UART-Interrupts nicht schnell genug bedient werden. Was sind denn die Symptome für die fehlerhafte Übertragung? Rührt sich gar nix, oder kommt nur Datenmüll an (z.B. auch Framing-Error), oder gehen einzelne Zeichen verloren? Verwendest Du Ringpuffer für eingehende und ausgehende Daten? MfG Olaf
Hallo Olaf, die ISR fuer den Timerueberlauf hab ich noch gar nicht eingebunden. In meinem "Minimalbeispiel" hab ich einfach nur den Timer initialisiert und gestartet wie im Quelltext oben. Das hat zur Folge, dass der UART nicht mehr geht. Inzwischen hab ich mit einema nderen Timer (16bit) gearbeitet und wenn der läuft, egal ob mit oder ohne seine ISR, funzt der UART. Ich poste gerne auch den ganzen Quellcode (bitte bescheid sagen!); aber ehrlich: ich glaube kaum, dass sich jemand die Arbeit macht fuer mich in meinem Code Fehler zu suchen... mg, Johannes
"die ISR fuer den Timerueberlauf hab ich noch gar nicht eingebunden." Jo, dann gehts natürlich ab in den Wald. Bevor man einen Interrupt freigibt, muß ein Handler am entsprechenden Interruptvektor existieren !!! Für diese Regel gibt es keine Ausnahme !!! Peter
Aha! ich nehm alles wieder zurück. Das hab ich nicht gewusst. Dachte, der Timer laeuft dann vor sich hin... hmm...Compilerspezialist bin ich nicht, aber sowas koennte der ja auch merken, oder? ich nehm die Schuld aber ganz auf meinen Puckl,stell mich 5min in eine Ecke und schäme mich dreimal ganz laut! es tut jetzt vorläufig wie ich will! mg, Johannes
Einen Peter Dannegger im Forum zu haben ist Luxus. Ist nicht das erstemal gewesen, dass dein Tip mich aufgeklaert hat. Danke, mg, Johannes
> Einen Peter Dannegger im Forum zu haben ist Luxus. Ist nicht das > erstemal gewesen, dass dein Tip mich aufgeklaert hat. Danke, Dem stimme ich voll zu! ...
ich auch. Man sollte die Liste vielleicht noch verlängern (ohne Wertung in Bezug auf die Reihenfolge: Rufus, HanneS, Jörg Wunsch, OldBug, CrazyHorse. Das sind die, die mir jetzt gerade eingefallen sind.
Könnt ihr mir vielleicht sagen wann ich denn extern Interrupt auf 1 setzen soll und wann und wie??? #pragma small code symbols debug #include "bremslicht.h" unsigned int aktuellerWert; /* speichert die aktuelle negative Beschleunigung 0..100 */ unsigned int leuchtendeLEDs; /* speichert die Anzahl anleuchtenden LEDS */ float LEDratio; /* hier wird errechnet, wie viel % eine LED "repräsentiert" */ unsigned int timer0_wert; /* INT0 Verlauf über die Zeit (Input vom Accelerometer, PWM moduliert) ...----><---T1---><--------T2-----------><--T1--><----... _______ _______ | | | | | | | | _______| |_______________________| |_____________ |<--Interrupt |<--Interrupt |<--timer0 fängt an hier |<--timer0 fängt an hier hochzuzählen, weil hochzuzählen, weil GATE0=1 und INT0 high GATE0=1 und INT0 high -----------------------------Zeit-------------------------------> */ void irq_timer0(void) interrupt 1 { timer0_wert = 256*TH0 + TL0; TL0 = 0x00; TH0 = 0x00; TF0 = 0; TF1 = 0; TMOD = 0x19;//0001=vom Tim1 M0 auf1, 1001=Auslösen desTim0,dann 16Bit Zähler laufen lassen } void LEDsInit() { register int i; for (i = 0; i < ANZAHL_LEDS; i++) { LEDs[i] = 0; // schalte LED aus } MAX7300SetzeLEDs(LEDs); } void AccMeterInit() { TR0 = 0; TMOD = 0x19; TH0 = 0x00; TL0 = 0x00; ET0 = 1; EA = 1; IT0=1;// TCON = TCON | 0x11; TR0=1; } void Initialisieren() { MAX7300Init(); LEDsInit(); aktuellerWert = 0; leuchtendeLEDs = 0; LEDratio = (float) 100 / ANZAHL_LEDS; timer0_wert = 0; AccMeterInit(); } void HoleWert() { if (timer0_wert > 0 ) { aktuellerWert = (int) ((timer0_wert / TIMER1_MAX) * 100); if (aktuellerWert < 50) { aktuellerWert *= 2; } else { //positive Beschleunigung interessiert uns nicht aktuellerWert = 0; } } } void BerechneWert() { leuchtendeLEDs = (unsigned int) aktuellerWert / LEDratio; } void AusgabeWert() { register int i; if (leuchtendeLEDs > 0) { P1_6 = 1; P1_7 = 1; } else { P1_6 = 0; P1_7 = 0; } for (i = 0; i < leuchtendeLEDs; i++) { LEDs[i] = 1; //lass LED leuchten } for (i = leuchtendeLEDs; i < ANZAHL_LEDS; i++) { LEDs[i] = 0; // schalte LED aus } MAX7300SetzeLEDs(LEDs); } void main() { Initialisieren(); for (;;) //forever { HoleWert(); BerechneWert(); AusgabeWert(); } }
Das musst du jetzt noch 7mal schreiben. Ab 10 Wiederholungen setzt sich sofort einer hin und macht dir das.
Vielleicht gehts ja den meisten so wie mir: Mir ist absolut nicht klar, was den nun dein Problem ist und wohin deine Frage zielt.
Und längeren Code immer als Amhang, sonst scrollt man sich ja dämlich. Peter
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.