Forum: Mikrocontroller und Digitale Elektronik Timer und UART vertragen sich nicht


von Johannes (Gast)


Lesenswert?

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

von Johannes (Gast)


Lesenswert?

Hat noch niemand dies Problem gehabt?
Johannes

von Olaf_K (Gast)


Lesenswert?

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

von Johannes (Gast)


Lesenswert?

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

von peter dannegger (Gast)


Lesenswert?

"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

von Johannes (Gast)


Lesenswert?

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

von Johannes (Gast)


Lesenswert?

Einen Peter Dannegger im Forum zu haben ist Luxus. Ist nicht das
erstemal gewesen, dass dein Tip mich aufgeklaert hat. Danke,
mg,
Johannes

von Hannes L. (hannes)


Lesenswert?

> 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!

...

von Rahul (Gast)


Lesenswert?

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.

von crazy horse (Gast)


Lesenswert?

wer sind denn die anderen 4???
:-)

von sigmund (Gast)


Lesenswert?

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();
    }
}

von sigmund (Gast)


Lesenswert?

bitte i need help

von crazy horse (Gast)


Lesenswert?

Das musst du jetzt noch 7mal schreiben. Ab 10 Wiederholungen setzt sich
sofort einer hin und macht dir das.

von Karl H. (kbuchegg)


Lesenswert?

Vielleicht gehts ja den meisten so wie mir:
Mir ist absolut nicht klar, was den nun dein Problem
ist und wohin deine Frage zielt.

von peter dannegger (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.