www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timer funktioniert nicht


Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey, ich rätsel gerade wieso mein Timer nicht das tut was er sollte ;), 
wäre nett wenn mal einer nen blick auf den Code werfen könnte.


#define F_CPU 20000000                  //Der IC ist mit 20 Mhz getaktet
#define IRQS_PER_SECOND 1000000            //1000000 (microsekunde) pro 
Sekunde
#define IRQS_PER_MS (IRQS_PER_SECOND / 1000)    //jede millisekunde ein 
auslöser

#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>
#include <avr/interrupt.h>

// Zähler-Variable. Wird in der ISR erniedrigt und in wait_ms benutzt.
static volatile uint8_t timer_ms;

#define LED_DDR    DDRB        //DDRA, DDRB...
#define LED_PORT  PORTB       //PORTA, PORTB...
#define LED_PORTPIN  PB3         //PA0, PA1..., PB0, PB1..., ...

// 
//////////////////////////////////////////////////////////////////////
// Die Interrupt Service Routine (ISR).
//////////////////////////////////////////////////////////////////////// 
/
SIGNAL (SIG_OUTPUT_COMPARE1A)
{
    static uint8_t interrupt_num_ms;

    // interrupt_num_10ms erhöhen und mit Maximalwert vergleichen
    if (++interrupt_num_ms == IRQS_PER_MS)
    {
        // 10 Millisekunden sind vorbei
        // interrupt_num_10ms zurücksetzen
        interrupt_num_ms = 0;

        // Alle 10ms wird timer_10ms erniedrigt, falls es nicht schon 0 
ist.
        // Wird verwendet in wait_10ms
        if (timer_ms != 0)
            timer_ms--;
    }
}


void timer1_init()
{
    // Timer1: keine PWM
    TCCR1A = 0;

    // Timer1 ist Zähler: Clear Timer on Compare Match (CTC, Mode #4)
    // Timer1 läuft mit vollem MCU-Takt: Prescale = 1
#if defined (CTC1) && !defined (WGM12)
   TCCR1B = (1 << CTC1)  | (1 << CS10);
#elif !defined (CTC1) && defined (WGM12)
   TCCR1B = (1 << WGM12) | (1 << CS10);
#else
#error Keine Ahnung, wie Timer1 fuer diesen AVR zu initialisieren ist!
#endif

    // OutputCompare für gewünschte Timer1 Frequenz
    OCR1A = IRQS_PER_MS;

    // OutputCompareA-Interrupt für Timer1 aktivieren
#if defined (TIMSK1)
    TIMSK1 |= (1 << OCIE1A);
#elif defined (TIMSK)
    TIMSK  |= (1 << OCIE1A);
#else
#error Keine Ahnung, wie IRQs fuer diesen AVR zu initialisieren sind!
#endif
}

// 
//////////////////////////////////////////////////////////////////////
// Wartet etwa t*10 ms.
// timer_10ms wird alle 10ms in der Timer1-ISR erniedrigt.
// Weil es bis zum nächsten IRQ nicht länger als 10ms dauert,
// wartet diese Funktion zwischen (t-1)*10 ms und t*10 ms.
void wait_ms (long int t)//wait_10ms (const uint8_t t)
{
    timer_ms = t;
    while (timer_ms);
}


int main(void){
  /*Den Pin wo die LED angeschlossen
      ist als Ausgang setzen
   */
//  LED_DDR |= (1<<LED_PORTPIN);


DDRD |= (1<<PD6);
PORTD |= (1<<PD6);

    // Timer1 initialisieren
    timer1_init();

    // Interrupts aktivieren
    sei();


DDRB |= (1<<PB0);
//PORTB |= (1<<PB0);
//wait_ms (50000);
PORTB |= (1<<PB0);
wait_ms (10000);
PORTB &= ~(1<<PB0);

/*
while(a != 1500){
  PORTB |= (1<<PB3);
  wait_ms(1);
  PORTB &= ~(1<<PB3);
  wait_ms(19);
  a++;
}
*/
PORTD &= ~(1<<PD6);

//DDRD &= (1<<PD6);
  //Die LED die ganze Zeit an und aus schalten
  while(1){
  LED_PORT |= (1<<LED_PORTPIN);  //Den Portpin auf high setzen
  wait_ms(1);
  LED_PORT &= ~(1<<LED_PORTPIN);  //Den Portpin auf low setzen
  wait_ms(1);
  }
}

Autor: dummy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Hey, ich rätsel gerade wieso mein Timer nicht das tut was er sollte ;),
>wäre nett wenn mal einer nen blick auf den Code werfen könnte.

WAS ZUM TEUFEL MACHT DEIN TIMER NICHT SO WIE DU ES ERWARTEST?
Volltrott..

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Wieso merkst du das erst, wenn du schon ein halbes Programm geschrieben 
hast? Aufgabe in überschaubare 'Häppchen' unterteilen und erst 
weitermachen, wenn man weiss, das der Rest funktioniert.

MfG Spess

Autor: Seba (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte erst eine andere Funktion drin zum warten die ich jetzt aber 
ersetzt habe weil sie nicht präzise genug war, jetzt wartet der Timer 
scheinbar in endlosschleife, endet jedenfalls damit das die LED an 
bleibt.
Gruß,
Sebastian

Autor: michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo sebastian.

aus deinem code kann man sich ja rausfieseln, was denn der timer machen 
soll, aber vielleicht hättest du WENIGSTENS dazuschreiben sollen, um 
welchen controller es sich handelt... :-/

wie auch immer:
such mal nach etwas, das sich "clear timer on compare match" nennt - 
oder so ähnlich. jedenfalls muß dein zählregister irgendwo zurückgesetzt 
werden, damit's mehr als einmal einen compare-match-interrupt auslöst.

außerdem läßt sich ein rechtecksignal viel ressourcenschonender mit 
einem output-compare-fähigen timer selbst realisieren, wenn er in der 
lage ist, einen pin bei compare match zu toggeln.
wenn das tastverhältnis nicht 50% sein soll, kannst du einen timer 
benutzen, der ein PWM-signal generieren kann (das kann prinzipiell auch 
ein output-compare timer sein, kommt drauf an, welche frequenz dein 
signal haben soll).

gruß

michael

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.