-         

Ergebnis 1 bis 10 von 10

Thema: Timer/Counter und PWM Channles

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    05.08.2005
    Beiträge
    61

    Timer/Counter und PWM Channles

    Anzeige

    Hallo,

    mal eine Verständnisfrage: Ich benutze einen ATMEGA16
    zur Erzeugung von 4 PWM für 4 Motoren. Jetzt würde ich
    gerne noch einen Timer benutzen, zum Beispiel um noch
    eine Status-LED blinken zu lassen. Geht das jetzt überhaupt
    noch, oder blockieren meine 4 PWM jetzt alle Timer/Counter
    Kanäle, von denen der ATMEGA16 ja nur 4 Stück hat (2x8bit,
    1x16bit,1xreal_time_counter[?])???

    Sind Interupt-Routinen davon auch betroffen?

    Gruß
    RICOLA

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    02.11.2005
    Ort
    Dortmund
    Alter
    24
    Beiträge
    1.641
    Wieso Interrupt? benötigt ein Timer einen Interrupt???
    Auf jeden Fall belegen deine 4 PWMs da alle 4 Timer. Du kannst höchstens noch einen Softwaretimer machen, aber frag jemand anders, wie das funzt. C kann ich nicht so gut.
    o
    L_
    OL
    This is Schäuble. Copy Schäuble into your signature to help him on his way to Überwachungsstaat!

    http://de.youtube.com/watch?v=qV1cZ6jUeGE

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.892
    Wenn einer deiner Timer durchläuft und nicht durch einen PWM Mode automatisch wieder genullt wird, oder rückwärts läuft, kannst du den Timer Overflow Interrupt dieses Timers aktivieren und einen Zähler hochzählen.
    Wenn dieser Zähler dann einen bestimmten Wert erreicht hat kannst Du den Zustand eines Ausgangs toggeln den Zählerstand des Softwarezählers (nicht! das TCNT Register) auf 0 setzen und damit eine LED zum blinken bringen.
    Die Routine braucht nur ein paar Bytes und dürfte den Ablauf deines Programmes nicht allzusehr stören.

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    05.08.2005
    Beiträge
    61
    hallo wgrug,

    das ist genau was ich brauche! könntest du es noch ein wenig konkretisieren bitte!? In etwa so hier? Geht dann das PWM noch?

    // Initialisierung:
    TCCR2 = (1<<CS22);
    TCNT2 = 183;
    TIMSK |= (1<<TOIE2);


    SIGNAL(SIG_SIG_OVERFLOW2)
    {
    countTimer2++;
    }

    Danke und Gruß
    RICOLA

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.892
    hallo wgrug,

    das ist genau was ich brauche! könntest du es noch ein wenig konkretisieren bitte!? In etwa so hier? Geht dann das PWM noch?

    // Initialisierung:
    TCCR2 = (1<<CS22);
    TCNT2 = 183;
    TIMSK |= (1<<TOIE2);


    SIGNAL(SIG_SIG_OVERFLOW2)
    {
    countTimer2++;
    }
    Die Antwort hast Du dir mit diesem Post vermutlich schon selbst gegeben.
    Mit dem Timer 2 wird das nicht gehen wenn auf dieses Register auch noch anderweitig geschrieben wird und dadurch kein Überlauf zstande kommt?
    Es kommt auch auf den gewählten PWM Mode an.
    Diese Modes kenne ich:
    Bei manchen Modes Zählt das TCNT2 Register bis zum Comparewert hoch und wird dann Hardwaremässig genullt - CTC.
    In einem anderen PWM Mode Zählt der Zähler bis zum Comparewert vorwärts und dann wieder rückwärts.
    In wieder einem anderen Mode Zählt der Zähler bis 0xFF und dann wieder auf 0x00.
    Alle diese Modes erzeugen normalerweise keinen! Timer Overflow Interrupt und sind somit nicht geeignet.


    Das TCNT2 Register muss Hochzählen bis der Zählerstand von 0xFF wieder auf 0x00 Überläuft, nur dann wird ein Timer Overflow Interrupt erzeugt (=Fast PWM Mode + Phase Correct PWM Mode).
    Hast Du in einem deiner Timer, diesen PWM Mode eingestellt ???
    Wenn nicht wird es so nicht funktionieren.

    Eine weitere Option wäre es einen Comparematch Interrupt freizugeben und hier den Zähler hochzuzählen.
    Das hätte aber den Nachteil, das bei Extremwerten des PWM (0x00 + 0xFF) unter Umständen dieser Interrupt nicht anspricht.

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    05.08.2005
    Beiträge
    61
    hmmm, ich initialisiere den PWM-Kanal mit

    // 8bit Kanal
    TCCR0 = (1<<WGM00)|(1<<COM01)|(1<<CS01);

    ??

    Gruß
    RICOLA

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.892
    // 8bit Kanal
    TCCR0 = (1<<WGM00)|(1<<COM01)|(1<<CS01);
    Mit diesen Einstellungen wird kein Timer Overflow Interrupt generiert, wohl aber ein Comparematch Interupt.
    Du musst diesen Interrupt nur im TIMSK freigeben die Vektoren in deinem Compiler anlegen und darin die Comparematch Routine (deine blinkende Led) anlegen.

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    05.08.2005
    Beiträge
    61
    hmmm, ich lese dazu folgendes:

    When the OCIE0 bit is written to one, and the I-bit in
    the Status Register is set (one), the Timer/Counter0
    Compare Match interrupt is enabled.

    When the I-bit in SREG, OCIE0 (Timer/Counter0 Compare
    Match Interrupt Enable), and OCF0 are set (one), the
    Timer/Counter0 Compare Match Interrupt is executed.

    also folgender Code?

    TIMSK = (1<<OCIE0);
    SREG = (1<<I);
    TIFR = (1<<OCF0);

    das mit den vektoren verstehe ich aber nicht. wo lege
    ich die denn im compiler an? und wo ist die funktion, die
    jetzt von dem interrupt aufgerufen wird?

    ich finde das hier:
    No:20 Addr:$026 TIMER0 COMP Timer/Counter0 Compare Match


    DANKE!!

    Gruß
    RICOLA

  9. #9
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.892
    Mit dem I Flag im SREG gibt es ein eigenes Assembler Kommando

    #asm ("SEI");

    Wie bei deinem Compiler Interrupts angelegt werden kann ich Dir nicht sagen, sollte aber auf jeden Fall im Compiler Handbuch stehen.

    Bei Codevision geht das so:

    interrupt [EXT_INT0] void ext_int0_isr(void)
    {
    dein Code;
    }

    Ist aber bei jedem Compiler anders.

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    05.08.2005
    Beiträge
    61
    Hallo,

    war eigentlich ganz einfach, musste nur

    TIMSK |= (1<<OCIE1A);
    sei();

    eingeben und hatte dann schon den SIG_OUTPUT_COMPARE1A
    Compare Match Timer an. PWM funktionieren noch tadellos. Muss
    mir halt nur die Zeitbasis selber mit Inkrementen mitzählen.

    Danke also!

    PS: Das Anlegen der Vektoren mach avr-gcc ganz von allein!

    Gruß
    RICOLA

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •