Forum: Mikrocontroller und Digitale Elektronik AT90 Servo-Pulsgenerator pulst ungleichmäßig


von Mechatronk (Gast)


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
  }

von Jetzt Los (Gast)


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.

von Mechatronk (Gast)


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

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.