Forum: Mikrocontroller und Digitale Elektronik Servo Ansteuern. wo liegt mein fehler?


von Huber M. (michael_h784)


Lesenswert?

Mahlzeit;

Also ich möchte im nachfolgenden Codebeispiel, ein Servo mit zwei 
tastern nach links und nach rechts bewegen. Einen Fehler vermute ich 
darin, das die Werte im OCR1A und OCR1B und der Vorteiler auf 8mhz 
bezogen sind. Ich aber nur einen Atmega8A mit 1mhz verwende. Wie wende 
ich das ab? Das zweite ist, wenn ich eine Led an den PWM ausgang 
hänge(zu testen ob etwas kommt)und die taster unabhängig von einander 
drücke ändert sich an der Frequenz nichts, das Servo bewegt sich 
ebenfalls nicht. Wo liegt hier main Fehler. Wäre um hilfe sehr dankbar


Ich benütze

Atmel studio 6.2

avr isp mk2 original

Atmega8A

/*
 * Servo_steuern.c
 *
 * Created: 04.08.2016 11:28:38
 *  Author: Huber
 */
#define F_CPU 1000000UL
#include <util/delay.h>

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

//impuls starten
ISR(TIMER1_COMPA_vect)
{
  PORTB|= (1<<PB1);
}

//impuls beenden
ISR(TIMER1_COMPB_vect)
{
  PORTB &= ~(1<<PB1);
}

int main(void)
{   // Servo Ausgang definieren

  DDRB |= (1<<PB1);

  // Eingänge taster definieren

  PORTD |= (1<<PD2) | (1<<PD3);

  // Timer für Servosteuerung konfigurieren

  TCCR1B |= (1<<WGM12)|(1<<CS11);// CTC modus+ Prescaler 8 (f_CPU /8 = 
)
  TIMSK  |=  (1<<OCIE1A)| (1<<OCIE1B); // Timer interrups für 
vergleichswerte
  OCR1A  |= 25000;        // Vergleichsregister periode von max 25 ms
  OCR1B  |= 1400;  //Vergleichsregister Position des Servos nach 
Programmstart
                   //die genaue position muss experimentiel ermittelt 
werden..
  sei();



    while(1)
    {  // Servohorn nach recht bewegen

        if (!(PINB&(1<<PB3)))
        {
      if(OCR1B < 2500) OCR1B++;
      _delay_ms(1);
    }
    // Servohorn nach links bewegen

    if (!(PINB&(1<<PB2)))
    {
      if(OCR1B > 750 )OCR1B--;
      _delay_ms(1);
    }


    }
}

: Verschoben durch Moderator
von Eric B. (beric)


Lesenswert?

Huber M. schrieb:
> // Eingänge taster definieren
>
>   PORTD |= (1<<PD2) | (1<<PD3);
...
>         if (!(PINB&(1<<PB3)))
...
>     if (!(PINB&(1<<PB2)))

PIND statt PINB, vielleicht?

Und das hier:
https://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten

von Huber M. (michael_h784)


Lesenswert?

Danke, habe ich das tatsächlich nicht gesehen.

so wie nachfolgend funktioniert es jetzt soweit. könnte mir noch jemand 
bitte erklären, oder die Formel zeigen wie ich die Pulsbreite bzw. die 
werte von OCR1A und OCR1B berechnen kann. denn das habe ich jetzt mehr 
oder weniger nach glück eingestellt.


/*
 * Servo_steuern.c
 *
 * Created: 04.08.2016 11:28:38
 *  Author: Huber
 */
#define F_CPU 1000000UL
#include <util/delay.h>

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

//impuls starten
ISR(TIMER1_COMPA_vect)
{
  PORTB|= (1<<PB1);
}

//impuls beenden
ISR(TIMER1_COMPB_vect)
{
  PORTB &= ~(1<<PB1);
}

int main(void)
{   // Servo Ausgang definieren

  DDRB |= (1<<PB1);

  // Eingänge taster definieren

  PORTD |= (1<<PD2) | (1<<PD3);

  // Timer für Servosteuerung konfigurieren

  TCCR1B |= (1<<WGM12)|(1<<CS11);// CTC modus+ Prescaler 8 (f_CPU /8 = 
)
  TIMSK  |=  (1<<OCIE1A)| (1<<OCIE1B); // Timer interrups für 
vergleichswerte
  OCR1A  |= 1562;        // Vergleichsregister periode von max 25 ms
  OCR1B  |= 160;  //Vergleichsregister Position des Servos nach 
Programmstart
                   //die genaue position muss experimentiel ermittelt 
werden..
  sei();



    while(1)
    {  // Servohorn nach recht bewegen

        if (!(PIND&(1<<PD3)))
        {
      if(OCR1B < 1562) OCR1B++;
      _delay_ms(1);
    }
    // Servohorn nach links bewegen

    if (!(PIND&(1<<PD2)))
    {
      if(OCR1B > 80 )OCR1B--;
      _delay_ms(1);
    }


    }
}

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.