Hallo,
wollte mal gerne wissen, welche werte ich im soft pwm 1
verändern muss damit ich einen servo z.B. ansteuere, um ihn 90grad
fahren zu lasse. Er soll dann auch später wieder zurückfahren.
Aber erstmal ist es wichtig ihn in verschiedene Positionen fahren zu
lassen.
Schönen Gruß
/*
Eine 8-kanalige PWM mit einfachem Lösungsansatz
ATmega32 @ 8 MHz
*/
// Defines an den Controller und die Anwendung anpassen
#define F_CPU 8000000L // Systemtakt in Hz
#define F_PWM 100 // PWM-Frequenz in Hz
#define PWM_STEPS 255 // PWM-Schritte pro
Zyklus(1..255)
#define PWM_PORT PORTD // Port für PWM
#define PWM_DDR DDRD // Datenrichtungsregister für
PWM
// ab hier nichts ändern, wird alles berechnet
#define T_PWM (F_CPU/(F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt
#if (T_PWM<(152+5))
#error T_PWM zu klein, F_CPU muss vergrössert werden oder F_PWM oder
PWM_STEPS verkleinert werden
#endif
#if PWM_STEPS > 255
#error PWM_STEPS zu gross
#endif
// includes
#include <stdint.h>
#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>
// globale Variablen
volatile uint8_t pwm_setting[8]; // Einstellungen für
die einzelnen PWM-Kanäle
// Timer 1 Output COMPARE A Interrupt
ISR(TIMER1_COMPA_vect) {
static uint8_t pwm_cnt=0;
uint8_t tmp=0, i=0, j=1;
OCR1A += (uint16_t)T_PWM;
for (; i<8; i++) {
if (pwm_setting[i] > pwm_cnt) tmp |= j;
j<<=1;
}
PWM_PORT = tmp; // PWMs aktualisieren
if (pwm_cnt==(uint8_t)(PWM_STEPS-1))
pwm_cnt=0;
else
pwm_cnt++;
}
int main(void) {
// PWM einstellen
PWM_DDR = 0xFF; // Port als Ausgang
// Timer 1 OCRA1, als variablem Timer nutzen
TCCR1B = 1; // Timer läuft mit vollem Systemtakt
TIMSK |= (1<<OCIE1A); // Interrupt freischalten
sei(); // Interrupts global einschalten
/*********************************************************************/
// nur zum Testen, im Anwendungsfall löschen
volatile uint8_t tmp;
const uint8_t t1[8]={27, 40, 3, 17, 150, 99, 5, 9};
const uint8_t t2[8]={27, 40, 3, 0, 150, 99, 5, 9};
const uint8_t t3[8]={27, 40, 3, 17, 3, 99, 3, 0};
const uint8_t t4[8]={0, 0, 0, 0, 0, 0, 0, 0};
const uint8_t t5[8]={0, 0, 0, 0, 0, 0, 0, 9};
const uint8_t t6[8]={33, 33, 33, 33, 33, 33, 33, 33};
// Messung der Interruptdauer
tmp =0;
tmp =0;
tmp =0;
// Debug
memcpy(pwm_setting, t1, 8);
memcpy(pwm_setting, t2, 8);
memcpy(pwm_setting, t3, 8);
memcpy(pwm_setting, t4, 8);
memcpy(pwm_setting, t5, 8);
memcpy(pwm_setting, t6, 8);
/*********************************************************************/
return 0;
}
@ Patrice T. (wenckstar) >wollte mal gerne wissen, welche werte ich im soft pwm 1 >verändern muss damit ich einen servo z.B. ansteuere, um ihn 90grad >fahren zu lasse. Er soll dann auch später wieder zurückfahren. Wenn gleich es möglich ist, mit dem Code des Artikels einen Servo anzusteuern, so ist es dennoch nicht sehr sinnvoll, weil hier massiv Auflösung fehlt. Such i Forum nach besseren Beispielen, da gibt es einen 20 Kanal Servo-Geber mit AVR.
Danke für eine Antwort. Was meinst Du mit I Forum??? Hast du einen Link dazu? Danke
Patrice T. schrieb: > wollte mal gerne wissen, welche werte ich im soft pwm 1 > verändern muss damit ich einen servo z.B. ansteuere, um ihn 90grad > fahren zu lasse. Dein Programm könnte so aussehen: loop set Portpin delay_us (2000) clear Portpin delay_ms (18) end loop Dann ist der Prozessor wenigstens beschäftigt.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.