Forum: Compiler & IDEs servo ansteuern mit attiny2313


von Kostja (Gast)


Lesenswert?

Hallo,
ich probiere ein servo(Hitec 40Hz) anzuschteuern, ohne erfolg, mit 
volgende code:

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

uint16_t ImpulsZaehler1=0;
uint8_t  a=64;  //mitte 1,6ms


// Timer interrupt 4000Hz (4Mhz Quarz)
void Teimer0_ON(void){
TCCR0B |= (1<<CS00);
OCR0B  = 156;
TIMSK |= (1<<TOIE0);
sei();
}


ISR(TIMER0_OVF_vect){
    if (ImpulsZaehler1<1000){
      ImpulsZaehler1++;
    }
}



int main(void){
  cli();
  Teimer0_ON();
  while(1){
    if ( ImpulsZaehler1<a ) {
    PORTB = PINB ^ ( 1 << PB1 );
    }
    else{
    PORTB &= ~(PINB ^ ( 1 << PB1) );
    }
    if(ImpulsZaehler1==1000){
    ImpulsZaehler1=0;
    }
    if ( PINA & (1<<PA1) ) {
      a=42;  1,05ms min
    }
  }
}

Kann mir jemand sagen wieso das nicht hin haut?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Vielleicht beschreibst du ja noch, was du gemessen hast, was passiert,
was du erwarten würdest, das passieren soll, und was deiner meinung
nach nicht funktioniert?

von johnny.m (Gast)


Lesenswert?

Eine auffällige Sache ist schon mal, dass ImpulsZaehler1 nicht volatile 
deklariert ist. Da diese Variable aber sowohl in der ISR als auch im 
Hauptprogramm bearbeitet wird, treten da wahrscheinlich recht seltsame 
Effekte auf. Also vor die Deklaration ein "volatile", dann bekommt das 
Hauptprogramm auch mit, wenn sich in der Variable was ändert.

Ansonsten ist v.a. das Hauptprogramm ziemlich konfus, was durch die 
völlig fehlende Kommentierung nicht unbedingt besser wird...

von Ale (Gast)


Lesenswert?

if(ImpulsZaehler1==1000){
    ImpulsZaehler1=0;

Muss in Interrupt sein.

Du wirst keine OVF Int haben, weil bei CTC, wenn OCR0B == TCNT0 die 
Counter wird Reset, wenn ich verstehe richtig was du wolltest. (hat die 
2313 keine PWM ?).

und macht ImpulsZähler volatile.

von Karl H. (kbuchegg)


Lesenswert?

>    PORTB = PINB ^ ( 1 << PB1 );

Das wird wohl so nichts werden.

Im übrigen sehe ich nicht, wo du Port B mal als
Ausgang definierst.

Eigentlich ist an diesem Code so gut wie gar nichts
richtig.
Das Einzige was stimmt ist:
Du aktivierst den Overflow Interrupt und hast auch
einen Handler dafür.

von Kostja (Gast)


Lesenswert?

Hallo das habe ich soweit zusammen. Ein Problem habe ich aber noch und 
zwar wen das Programm ISR(SIG_OUTPUT_COMPARE0B){} startet wird der TCNT0 
Register nicht angehalten so das wen ich den wert von OCR0B ändere das 
kein Einfluss auf die Frequenz hat! habe ich da was vergessen?
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

volatile uint16_t ImpulsZaehler1=0;
uint16_t  a=50;  //mitte 1,6ms


// Timer interrupt 4000Hz (4Mhz Quarz)
void Teimer0B_ON(void){
TCCR0B |= (1<<CS00) | (1<<WGM02);
OCR0B  = 1;
TIMSK |= (1<<OCIE0B);
sei();
}


ISR(SIG_OUTPUT_COMPARE0B){
    if (ImpulsZaehler1<100){
      ImpulsZaehler1++;
    }
    if(ImpulsZaehler1==100){
    ImpulsZaehler1=0;
    }
}



int main(void){
  Teimer0B_ON();
  DDRD = (1 << DDB6);
  while(1){
    if ( ImpulsZaehler1<a ) {
    PORTD &= ~(PIND ^ ( 1 << PD6) );
    }
    else{
    PORTD = PIND ^ ( 1 << PD6 );
    }
    /*if ( PINB & (1<<PB0) ) {
      a=42;  //1,05ms min
    }*/
  }
}

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.