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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.