AT90 Servo-Pulsgenerator pulst ungleichmäßig

Gast #4443984
Lesenswert?

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
  }
Gast #4444351
Lesenswert?

> .. void sleep(uint32_t i)

> ..ISR(TIMER0_COMP_vect)  // 2ms-timer interrupt
> ...


Der Timer unterbricht den Delay. Und dauernd wird an den Interrupt 
Registern rumgemacht. Das war's dann. So wird's nie was.
Gast #4445236
Lesenswert?

Der Timer macht doch garnichts während des Delays, oder?
Was spricht dagegen an den Registern rumzumachen wenn man das verhalten 
ändern will?
Ich versuche das ganze heute nochmal mit den eingebauten PWM-Einheiten, 
erscheint mir momentan sinniger.

Grüße

Andi

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren