Forum: Mikrocontroller und Digitale Elektronik Servo 8bit Timer AVR


von J. K. (rooot)


Lesenswert?

Sg. Forumsbesucher :-)

Ich versuche einen Modellbau-Servo mit einem 8bit-Timer zu betreiben. 
Dazu wähle ich einen passenden Vorteiler, dass ich eine Zeitbasis von 
1ms habe.
in der
0. Millisekunde setze ich den Servo ausgang auf high
1. führe ich eine fast pwm aus, je nach eingestellen gradwert
2. setze ich den ausgang wieder auf low und warte bis
20 wo das ganze wieder von vorn beginnt.

das ganze habe ich mit einem AtMega16 und Timer 2 programmiert. Der 
Servo geht zirka in Mittelstellung beim einschalten. Bei einer erneuten 
Gradvorgabe stellt er sich fast auf die linke Endposition und reagiert 
nicht weiter.

Der 16-bit-Timer wird leider schon für was anderes gebraucht.

Kann das überhaupt so funktionieren oder hab ich nen Denkfehler?

MfG
J.K.

von J. K. (rooot)


Lesenswert?

1
volatile int grad=80;  
2
volatile int einstellung; 
3
volatile unsigned int hilf;  
4
volatile int counter = 0;
5
6
// Timer 2 overflow interrupt service routine
7
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
8
{
9
// Reinitialize Timer 2 value
10
TCNT2=0x06;
11
       
12
if (counter==0) {  
13
14
// OC2 output: Disconnected
15
TCCR2=0x4C;
16
PORTD.7=1;
17
18
}
19
20
21
if (counter == 1){
22
23
// OC2 output: Inverted PWM
24
//TCCR2=0x7C;
25
//non
26
TCCR2=0x6C;  
27
OCR2=einstellung;  
28
}    
29
if (counter==2){
30
// OC2 output: Disconnected
31
TCCR2=0x4C;
32
PORTD.7=0; 
33
}
34
  
35
counter++;
36
37
if (counter==20)
38
counter = 0;        
39
40
}
41
// Declare your global variables here
42
43
void main(void)
44
{
45
46
47
// Port D initialization
48
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=Out 
49
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=0 
50
PORTD=0x00;
51
DDRD=0x80;
52
53
// Timer/Counter 2 initialization
54
// Clock source: System Clock
55
// Clock value: 250,000 kHz
56
// Mode: Fast PWM top=FFh
57
// OC2 output: Disconnected
58
ASSR=0x00;
59
TCCR2=0x4C;
60
TCNT2=0x06;
61
OCR2=0x80;
62
63
64
// Timer(s)/Counter(s) Interrupt(s) initialization
65
TIMSK=0x40;
66
67
// USART initialization
68
// Communication Parameters: 8 Data, 1 Stop, No Parity
69
// USART Receiver: On
70
// USART Transmitter: On
71
// USART Mode: Asynchronous
72
// USART Baud rate: 9600
73
UCSRA=0x00;
74
UCSRB=0x18;
75
UCSRC=0x86;
76
UBRRH=0x00;
77
UBRRL=0x67;
78
79
80
// Global enable interrupts
81
#asm("sei")         
82
83
hilf=125*grad; 
84
einstellung=hilf/90 + 6;
85
86
while (1)
87
      {
88
      // Place your code here   
89
       scanf("%i",&grad);    
90
       hilf=125*grad; //grad *250 timerschritte / 180°  das ganze durch 2
91
  einstellung=hilf/90 + 6;
92
      printf("%i grad ok , %i einst\n",grad,einstellung); 
93
      
94
      
95
96
      };
97
}

von Tobias T. (tobytetzi)


Lesenswert?

Hallo,

warum führst Du in der 2.ms eine PWM aus?

Du musst doch alle 20ms einen Puls mit der Länge von 1-2ms erzeugen.
Also:
0ms: Pin an
nach maximal 2ms: Pin aus
nach 20ms: wieder von vorn

Mit welcher Frequenz läuft dein Mega?
Dann könnte man wohl eher sagen, wie es gehen soll.
Wieviele Schritte brauchst Du für das Servo?

Gruß Toby

von J. K. (rooot)


Lesenswert?

also der Mega lauft mit 16MHz.

in der 1. ms erzeugt die pwm einen impuls zwischen 0 und 1 ms
+ 1ms der "0." millisekunde = 1-2 ms

@Schritte:
naja, 100 würden reichen, jetzt sind 250

MfG
J.K

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.