-
        

Ergebnis 1 bis 2 von 2

Thema: beschleunigen mit timer

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    28.08.2004
    Ort
    Giessen
    Beiträge
    10

    beschleunigen mit timer

    Anzeige

    Hallo allerseits,

    ich versuche seit geraumer Zeit auf meinem Atmega16 mittel des timer0 eine Wartefunktion zu implementieren.

    Meine Funktion timer_set(unsigned short ms) erechnet aus dem übergebenem Parameter ms, wie oft der voreingestellte Timer durchlaufen werden muss. In meiner SIGNAL ( SIG_OVERFLOW0 ) soll aber kein spezieller Code aufgeführt werden, ausser den timer stoppen wenn er fertig ist.
    Der Timer selbst funktioniert gut aber ein Aufruf wie:

    Code:
    for (i = 160; i > 0; i--) {
       pwm ( A | B, i);
       timer_run(100);
    }
    um eine beschleunigung beider Motoren A und B zu erzeugen, funktioniert aber nicht. Ich vermute, dass der Timer gestartet wird, aber der µC parallel dazu den Rest ausführt.

    Gibt es eine Möglichkeit so eine Wartefunktion zu implementieren, ohne zb Zeiger auf Funktionen, oder eine while-Schleife mit "nop", zu benutzen?
    Denn ein _delay_ms(xyz) funktioniert, aber der µC führt Befehle erst nach dem beenden von _delay_ms aus, selbst Interrupts.

    Vielleicht gibts ja eine bessere Lösung?!

    mfg
    Martin

  2. #2
    Neuer Benutzer Öfters hier
    Registriert seit
    28.08.2004
    Ort
    Giessen
    Beiträge
    10
    Jetzt läuft der timer, zwar nicht ganz so wie ich es wollte, aber er läuft =).

    timer:
    Code:
    volatile unsigned short time;
    volatile unsigned short time_org;
    void  (*timer_func) (void);
    volatile unsigned int pause;
    volatile unsigned short counter = 0;
    volatile unsigned char reload;
    
    
    // timer 0 initialisieren
    void timer_init (void) {
        // prescale auf 1024 stellen (S.83)
        // -> 8MHz/1024 = 7812.5 Hz
        // TCCR0 = _BV (CS02) | _BV(CS00);
    
        // startwert des timers einstellen
        // von 0 bis 256 (2^8), default: 0
        // 80000 Takte fuer 10 ms / 1024 prescaler
        // -> 78,125 zaehler fuer 10 ms
        // => 256 - 78 = _178_
        reload = 178;
        TCNT0  = reload;
    
        // bei einem Überlauf des Datenregisters des Timer/Counter 0
        // ein Timer Overflow 0 Interrupt ausgeloesen (S. 83-84)
        // TIMSK = _BV(TOIE0);
    
        // Global Enable Interrupt Flag
     //   sei();
    }
    
    void timer_off (void) {
        TCCR0 = 0x00;
    }
    
    void timer_run (unsigned short ms, void (*func) (void), unsigned char count ) {
    //void timer_run (unsigned short ms) {
        timer_func = func;
        counter = count;
        time = ms/10;
    
        // alle 80 ms geht es 1 s nach
        time += time / 80;
        time_org = time;
        
        TCCR0 = _BV (CS02) | _BV(CS00);
        TIMSK = _BV(TOIE0);
    }
    overflow interrupt:
    Code:
    SIGNAL ( SIG_OVERFLOW0 ) {
        TCNT0 = reload;
        
        if (!time) {
    	    timer_func();
    	    counter--;
    	    time = time_org;
    
    	    if (counter <= 0)
    	          timer_off();
        }
        time--;  
    }
    Testfunktion (blinker):

    Code:
    void blink (void) {
        PORTB ^= (1<<PB0);
    }
    und der aufruf:
    Code:
    timer_run(1000, blink, 20);
    Der Timer führt alle 1000ms die Funktion blink() aus und wiederholt das Ganze 20 mal bis er sich selbst ausschaltet.

    Mein Frage jetzt:
    Ist das eine brauchbare Lösung? Oder ergeben sich dadurch mir noch nicht ersichtliche Nachteile?

Berechtigungen

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