Forum: Mikrocontroller und Digitale Elektronik Timer funktioniert nicht


von Sebastian (Gast)


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

von dummy (Gast)


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

von spess53 (Gast)


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

von Seba (Gast)


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

von michael (Gast)


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

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.