Hallo,
ich hätte eine Frage zum folgenden Link:
http://rn-wissen.de/wiki/index.php/Servos#Siehe_auch
ISR(TIMER2_COMP_vect)
{
static int count;
if(count>servopos)SERVOPORT&=~(1<<SERVOPIN);
else SERVOPORT|=(1<<SERVOPIN);
if(count<2000)count++; // Die Impulse sollten alle 20ms gesendet
werden! 6.2.11 mic
else count=0;
};
Ich verstehe was ein Sevo ist und die wie die dieser funktioniert (f=50
Hz, Periodenlänge 20ms, Impulsbreite zwischen 1ms und 2ms, usw). Ich
komme nur nicht drauf wie die 2000 (20ms) berrechnet wurde.
if(count<2000)count++; ??????
Danke
Danke.
Ich habe nun versucht ein PWM-Signal am Pin des Controllers zu erzeugen.
Wenn ich den Pin des Controller am Oszillokop anschließe, sehe ich nur
in Strich und erkenne da keinen Impuls (Pulsbreite 10ms). Ich finde den
Fehler im Code nicht? Danke
/*----Timer2-----CTC-Modus----
8-Bit Timer: 0...255
Prescaler: 64
F_CPU/Prescaler: 16MHz/64=250000 Takte/s
Alle 1ms soll ein Interrupt ausgelöst werden
Periodenlänge 30ms
-->OCR2A=250000*1ms=249
*/
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
//globale Variable
volatile uint8_t count;
void Timer2_init(void);
int main(void)
{
//PB1 als Ausgang setzen
DDRB|=(1<<PB1);
//Pin PB1 auf High setzen
PORTB|=(1<<PB1);
Timer2_init();
while(1)
{
} return 0;
}
void Timer2_init(void)
{
//Mode 4: CTC-Modus
TCCR2A|=(1<<WGM21);
//Prescaler 64
TCCR2B|=(1<<CS22);
//Der Vergleichswert beträgt 249
OCR2A=249;
//Interrupt aktivieren
TIMSK2|=(1<<OCIE2A);
sei();
}
ISR(Timer2_COMPA_vect)
{
if(count<10)
PORTB|=(1<<PB1);
else
PORTB&=~(1<<PB1);
if(count<30)
count++;
else
count=0;
}
Versuch erstmal, in der main in einer Endlosschleife ohne
Timer-Interrupt den IO-Pin zu toggeln, mit Delay-Counterschleifen
dazwischen (den counter als globales volatile deklarieren nicht
vergessen).
Dann weißt Du schonmal, ob das Problem in der IO-Initialisierung oder im
Aufsetzen des Timer-Interrupts liegt.
Nop schrieb:> Wenn alle 10µs ein Timer-Interrupt kommt, man in jedem Interrupt um eins> hochzählt und das 2000 mal tut, dann sind das 2000*10µs = 20ms.
Wenn man alle 10µs versucht, einen Timer-Interrupt zu feuern, würde ich
erstmal ganz gründlich gucken, ob der Prozessor das vernünftig schafft
und sich nicht die Interrupts auf die Füße treten. Mindestens wenn der
µC auch noch andere Dinge erledigen soll, kann das sehr eng werden.
Wolfgang schrieb:> würde ich erstmal ganz gründlich gucken, ob der Prozessor> das vernünftig schafft
.... würde ich erst mal gucken ob das jemand überhaupt
braucht. Zum Servo-Steuern sicherlich nicht.
Chilitester schrieb:> .... würde ich erst mal gucken ob das jemand überhaupt> braucht. Zum Servo-Steuern sicherlich nicht.
Zum Steuern eines Servos würde es sicher reichen, wenn man z.B. einen
1ms System-Interrupt laufen hat, der dann für die 20ms Periodendauer
gezählt wird und einen 8-Bit Timer, quasi als Monoflop, zur Erzeugung
des Steuerimpulses.
Dann müßte man sich nur noch eine Beschäftigung für den Prozessor
überlegen, damit der sich nicht zu Tode langweilt ;-)
Ich habe zuvor mithilfe der Phasen- und Frequenkorrekte PWM (Timer1,
Hardware PWM) ein Signal erzeugt, welches am Oszilloskop zusehen ist.
Jetzt wollte ich Soft-PWM (Timer2 Interrupt) anwenden.
Dani schrieb:> Jetzt wollte ich Soft-PWM (Timer2 Interrupt) anwenden
Du hast es aber mit 2 Zeiten zu tun: 20 ms Basis, davon x ms PWM-Impuls.
Dazu brauchst du 2 Timer, einen für 20 ms und einen zweiten, der vom
ersten gestartet wird und die variablen 0..20 ms für die Impulslänge
ausgibt. Es sei denn es gibt zusätzliche Hardware wie Caption-Register.
Oder du programmierst einen Timer abwechselnd mit x ms (PWM ein) und 20
- x ms (PWM aus), das ist aber weniger genau. Man kann aber die
Verzögerung zum Wiederstarten des Timers einrechnen.
Heutige Controller verfügen ja über ganze Timer-Rudel.
Georg
Georg schrieb:> Dani schrieb:>> Jetzt wollte ich Soft-PWM (Timer2 Interrupt) anwenden>> Du hast es aber mit 2 Zeiten zu tun: 20 ms Basis, davon x ms PWM-Impuls.> Dazu brauchst du 2 Timer, einen für 20 ms und einen zweiten, der vom> ersten gestartet wird und die variablen 0..20 ms für die Impulslänge> ausgibt. Es sei denn es gibt zusätzliche Hardware wie Caption-Register.>> Oder du programmierst einen Timer abwechselnd mit x ms (PWM ein) und 20> - x ms (PWM aus), das ist aber weniger genau. Man kann aber die> Verzögerung zum Wiederstarten des Timers einrechnen.>> Heutige Controller verfügen ja über ganze Timer-Rudel.>> Georg
Ich dachte in der ISR Routine habe ich bereits shon die Zeit definiert,
in denen ein Pin auf High bzw. Low gesetzt wird.
ISR(Timer2_COMPA_vect)
{
if(count<10)
PORTB|=(1<<PB1);
else
PORTB&=~(1<<PB1);
if(count<30)
count++;
else
count=0;
}
Wenn man schon fremde Sourcen zitiert sollte man wenigstens auf die
Quelle verweisen:
https://www.proggen.org/doku.php?id=electronics:projects:legorobotWolfgang schrieb:> Wenn man alle 10µs versucht, einen Timer-Interrupt zu feuern, würde ich> erstmal ganz gründlich gucken, ob der Prozessor das vernünftig schafft> und sich nicht die Interrupts auf die Füße treten.
Bei 4MHz geht es nicht (hat Karl Heinz vor Jahren schon rausgefunden).
Bei 8MHz geht es wohl. Beim Lego Roboter sind es 16MHz.