Hallo,
Ich versuche mich grad an einer Soft-PWM zur Servoansteuerung.
Board ist ein AVRCAN von Olimex mit AT90CAN128
Porblem: Der Puls wird im verlauf von ca 0.3 Sekunden um 80µS länger und
springt dann wieder auf den Sollwert. Der Servo Wackelt um ein Paar grad
mit.
Ich habe das Programm schon so weit reduziert wie möglich, so langsam
fällt mir nichts mehr ein. Wer eine Idee?
Grüße
Andi
1 | #include <avr/io.h>
|
2 | #include <avr/interrupt.h>
|
3 | #define F_CPU 16000000ULL
|
4 | #include <util/delay.h>
|
5 |
|
6 |
|
7 |
|
8 | void Reg_Init(void)
|
9 | {
|
10 |
|
11 |
|
12 | TCCR0A=0b00000101; // kein PWM,kein Compare Match , prescaler 1024 -> 2ms = 30 Pulse
|
13 | TIMSK0=0b00000000; // erstmal kein Compare Match interrupt
|
14 | OCR0A=15;
|
15 |
|
16 | }
|
17 |
|
18 |
|
19 | void sleep(uint32_t i)
|
20 | {
|
21 | while(i--)
|
22 | _delay_ms(1);
|
23 | }
|
24 |
|
25 |
|
26 | //Variablen
|
27 | void PORT_Init()
|
28 | {
|
29 | PORTA = 0b00000000;
|
30 | DDRA = 0b00000000;
|
31 |
|
32 | PORTB = 0b00000000;
|
33 | DDRB = 0b00000000;
|
34 |
|
35 | PORTC = 0b00000000;
|
36 | DDRC = 0b00000000;
|
37 |
|
38 | PORTD = 0b00000000;
|
39 | DDRD = 0b00000100;
|
40 |
|
41 | PORTE = 0b00010000;
|
42 | DDRE = 0b00010011; //Led4+servo78 set as output
|
43 |
|
44 | PORTF = 0b00000000;
|
45 | DDRF = 0b00000000;
|
46 | }
|
47 |
|
48 | void WDT_off(void)
|
49 | {
|
50 | cli();
|
51 | /* Write logical one to WDCE and WDE */
|
52 | WDTCR = (1<<WDCE) | (1<<WDE);
|
53 | /* Turn off WDT */
|
54 | WDTCR = 0x00;
|
55 | }
|
56 |
|
57 |
|
58 | int main()
|
59 | {
|
60 | WDT_off();
|
61 | PORT_Init();
|
62 | Reg_Init();
|
63 |
|
64 | sei(); // Alles Initialisiert, Interupts Freischalten
|
65 | int i;
|
66 | int j;
|
67 | while (1)
|
68 | {
|
69 | sleep(25);
|
70 | OCR0A=16;
|
71 | PORTE &=0b11101111; //LED AN
|
72 | PORTE |= 0b00000011; //SERVO PULS AN
|
73 | TCNT0=0;
|
74 | TIFR0 = 0b00000010; // Pending Interrputs löschen
|
75 | TIMSK0=0b00000010; // Compare Match 0 interrupt an
|
76 |
|
77 | }
|
78 | }
|
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 | ISR(TIMER0_COMP_vect) // 2ms-timer interrupt
|
85 | {
|
86 |
|
87 | PORTE |= 0b00010000; //LED AUS
|
88 | PORTE &=0b11111100; //SERVO PULS AUS
|
89 | TIMSK0 &=0b11111101; // Compare Match 0 interrupt aus
|
90 |
|
91 | }
|