Probleme mit Uart und ISR

Gast #2614411
Lesenswert?

Hallo erstmal,

um direkt zum Problem zu kommen:

Ich habe einen Atmega16, den auf einer Platine und soweit funktioniert 
auch alles.
Mein Ziel war es, 8 Servomotoren zu steuern und diese über UART zu 
regeln.

16 Mhz Quarz
Baudrate ist 38400
Servos werden von 2 Timern gesteuert.

Nun zum Problem:

Wenn ich per serieller Schnittstelle was an den Controller schicke und 
der soll mir das einfach zurückschicken bricht er nach 2 Zeichen ab. 
Schätze die Timer ISR verhindert weiteres Empfangen.
Aber diese ISR wird nur alle 16 ms aufgerufen. Wenn ich die Timer 
ausstelle funktioniert auch alles.
Wie kann ich das vereinbaren?

Danke schonmal
1
#include <avr/io.h> 
2
#define F_CPU 16000000UL /* evtl. bereits via Compilerparameter definiert */
3
#define BAUD 38400UL
4
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
5
#include <avr/delay.h>
6
#include <stdlib.h>
7
#include <avr/interrupt.h> 
8
#include <string.h>
9

10

11
char s[4];
12
char buffer[10];
13
volatile uint8_t uart_str_count=0;
14
volatile uint8_t servo=0;
15
volatile uint8_t servo_count=0;
16
volatile uint8_t uart_str_complete = 0;
17
volatile uint8_t servopos[8];
18
uint8_t servo0=0;
19

20
void servo_init()
21
{
22
  //Timer 1
23
  OCR1A = F_CPU /100000; //alle 10 µs IRQ
24
  TIMSK|=(1<<OCIE1A) | (1<<TOIE0) ;
25
  TCCR0 =(1<<CS02)|(1<<CS00) ; // CTC Modus  //Prescale=8, CTC mode
26
  
27
  
28
  
29
  DDRD=0xFF;
30
  DDRC |= (1<<PC0) | (1<<PC1);
31
  servopos[0]=180; //links oben oben
32
  servopos[1]=180; //rechts oben unten
33
  servopos[2]=70; // links unten unten
34
  servopos[3]=80; //links oben unten
35
  servopos[4]=190;//rechts oben oben
36
  servopos[5]=80;//links unten oben
37
  servopos[6]=160;//rechts unten unten
38
  servopos[7]=110;//rechts unten oben
39
  
40
};
41

42
ISR(TIMER0_OVF_vect)
43
{
44
//Timer 0
45

46
TCCR1B |= (1<<WGM12) | (1<<CS10);
47
}
48

49
ISR(TIMER1_COMPA_vect)
50
{
51
  
52
  static long count;
53
  uint8_t temp=0;
54
  
55
  if(servopos[0]>count) temp |=(1<<PD2);
56
  if(servopos[1]>count) temp |=(1<<PD3);
57
  if(servopos[2]>count) temp |=(1<<PD4);
58
  if(servopos[3]>count) temp |=(1<<PD5);
59
  if(servopos[4]>count) temp |=(1<<PD6);
60
  if(servopos[5]>count) temp |=(1<<PD7);
61
  if(servopos[6]>count) PORTC |=(1<<PC0);
62
  else PORTC &=~(1<<PC0);
63
  if(servopos[7]>count) PORTC |=(1<<PC1);
64
  else PORTC &=~(1<<PC1);
65

66

67
  
68
  PORTD = temp;
69
    if(count<2000)count++; // Die Impulse sollten alle 2ms gesendet werden
70
    else{
71
  count=0;
72
  TCCR1B =0;
73
  }
74
  
75
};
76

77
void uart_init(void)   
78
{
79
   UBRRH = UBRR_VAL>>8;
80
   UBRRL = UBRR_VAL;
81
   /* evtl. verkuerzt falls Register aufeinanderfolgen (vgl. Datenblatt)
82
      UBRR = UBRR_VALUE;
83
   */
84

85
 UCSRB = (1 << RXEN) | (1 << TXEN) |(1<<RXCIE);
86
 UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
87

88
}
89

90
void adc_init(void){
91

92
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
93
  ADMUX=0 | (0<<REFS1) | (1<<REFS0);
94

95
}
96

97
int uart_putc(unsigned char c)
98
{
99
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
100
    {
101
    }                             
102
 
103
    UDR = c;                      /* sende Zeichen */
104
    return 0;
105
}
106

107
uint8_t uart_getc(void)
108
{
109
    while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
110
        ;
111
    return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
112
}
113

114
void uart_puts (char *st)
115
{
116
    while (*st)
117
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
118
        uart_putc(*st);
119
        st++;
120
    }
121
  //uart_putc(' ');
122
}
123

124

125

126

127
int main(void){
128

129
  servo_init();
130
  adc_init();
131
  uart_init();
132
  //DDRD |= (1<<PD0);
133
  sei();
134
  
135
  
136
while(1){
137
  
138
  if(uart_str_complete==1){
139
  uart_puts(buffer);
140
  uart_str_complete=0;
141
  
142
  }
143
  //PORTD |=(1<<PD0);
144
  ADCSRA |= (1<<ADSC);
145
    while(ADCSRA & (1<<ADSC));
146
    uint16_t c= ADCW;
147
    if(atoi(s)<=c-2 || atoi(s)>=c+2){
148
    itoa(c,s,10);
149
    //uart_puts(s);
150
    }
151
  }
152
  
153
  //PORTD &= ~(1<<PD0);
154
  
155

156
return 0;
157
}
158

159
ISR(USART_RXC_vect)
160

161
  {
162
 if (servo==1)servoSteuer();
163
 else{
164
 unsigned char nextChar;
165

166
  // Daten aus dem Puffer lesen
167
  nextChar = UDR;
168

169
 if (nextChar=='s'){
170
 servo=1;
171
 
172
 }else{
173

174
    if( uart_str_complete == 0 ) {
175
    // Daten werden erst in uart_string geschrieben, wenn nicht String-Ende/max Zeichenlänge erreicht ist/string gerade verarbeitet wird
176
    if( nextChar != '\n' &&
177
        nextChar != '\r' &&
178
        uart_str_count < 9 ) {
179
      buffer[uart_str_count] = nextChar;
180
      uart_str_count++;
181
    }
182
    else {
183
      buffer[uart_str_count] = '\0'; 
184
      uart_str_count=0;
185
    uart_str_complete=1;
186
    
187
         }
188
  }
189
  }
190
  }
191
}
192

193
void servoSteuer(void){
194

195
  uint8_t nextChar;
196
  
197
  // Daten aus dem Puffer lesen
198
  nextChar = UDR;
199
  uart_putc(nextChar);
200
  
201
  if(nextChar !='s'){
202
   if(
203
       nextChar != '\r'){
204
      
205
    
206
      
207
      servopos[servo_count]=nextChar;
208
      servo_count++;
209
      
210
      
211
    
212
    }else{
213
    servo_count=0;
214
    servo=0;
215
    }
216
    
217
  }
218
}
#2614424
Lesenswert?

Wieso schaltest du hier
1
ISR(TIMER1_COMPA_vect)
2
{
3
  ....
4

5
  if(count<2000)count++; // Die Impulse sollten alle 2ms gesendet werden
6
    else{
7
  count=0;
8
  TCCR1B =0;

den Timer ab?

Der Timer muss weiterlaufen!


Der ganze Code ist extrem unübersichtlich. Straffe den erst mal und sorg 
für eine saubere Formatierung.
Gast #2614428
Lesenswert?

Oh entschuldige, ich habe die Antwort nicht gesehen.
Naja ich schalte ihn ab wenn die 2ms rum sind, damit nicht unnötig CPU 
leistung flöten geht.
Der wird ja wieder eingeschaltet wenn der Timer0 ISR kommt.
ich formatier das mal schöner
Gast #2614441
Lesenswert?

so nochmal neu der Code:

[c}#include <avr/io.h>
#define F_CPU 16000000UL /* evtl. bereits via Compilerparameter 
definiert */
#define BAUD 38400UL
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
#include <avr/delay.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <string.h>


char s[4];
char buffer[10];
volatile uint8_t uart_str_count=0;
volatile uint8_t servo=0;
volatile uint8_t servo_count=0;
volatile uint8_t uart_str_complete = 0;
volatile uint8_t servopos[8];
uint8_t servo0=0;

void servo_init()
{
  //Timer 1
  OCR1A = F_CPU /100000; //alle 10 µs IRQ
  TIMSK|=(1<<OCIE1A) | (1<<TOIE0) ;
  TCCR0 =(1<<CS02)|(1<<CS00) ; // CTC Modus  //Prescale=8, CTC mode



  DDRD=0xFF;
  DDRC |= (1<<PC0) | (1<<PC1);
  servopos[0]=180; //links oben oben
  servopos[1]=180; //rechts oben unten
  servopos[2]=70; // links unten unten
  servopos[3]=80; //links oben unten
  servopos[4]=190;//rechts oben oben
  servopos[5]=80;//links unten oben
  servopos[6]=160;//rechts unten unten
  servopos[7]=110;//rechts unten oben

}

ISR(TIMER0_OVF_vect)
{
  //Timer 0

  TCCR1B |= (1<<WGM12) | (1<<CS10);
}

ISR(TIMER1_COMPA_vect)
{

  static long count;
  uint8_t temp=0;

  if(servopos[0]>count) temp |=(1<<PD2);
  if(servopos[1]>count) temp |=(1<<PD3);
  if(servopos[2]>count) temp |=(1<<PD4);
  if(servopos[3]>count) temp |=(1<<PD5);
  if(servopos[4]>count) temp |=(1<<PD6);
  if(servopos[5]>count) temp |=(1<<PD7);
  if(servopos[6]>count) PORTC |=(1<<PC0);
  else PORTC &=~(1<<PC0);
  if(servopos[7]>count) PORTC |=(1<<PC1);
  else PORTC &=~(1<<PC1);



  PORTD = temp;

    if(count<2000)count++; // Die Impulse sollten alle 2ms gesendet 
werden
    else{
      count=0;
      TCCR1B =0;
      TCCR0 =(1<<CS02)|(1<<CS00);
      }

}



void uart_init(void)
{
  UBRRH = UBRR_VAL>>8;
  UBRRL = UBRR_VAL;
  UCSRB = (1 << RXEN) | (1 << TXEN) |(1<<RXCIE);
  UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);

}



void adc_init(void)
{

  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
  ADMUX=0 | (0<<REFS1) | (1<<REFS0);

}



int uart_putc(unsigned char c)
{
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
    {}

    UDR = c;                      /* sende Zeichen */
    return 0;
}




uint8_t uart_getc(void)
{
    while (!(UCSRA & (1<<RXC)));   // warten bis Zeichen verfuegbar

    return UDR;                   // Zeichen aus UDR an Aufrufer 
zurueckgeben
}




void uart_puts (char *st)
{
    while (*st)
    {   /* so lange *s != '\0' also ungleich dem 
"String-Endezeichen(Terminator)" */
        uart_putc(*st);
        st++;
    }
  //uart_putc(' ');
}




int main(void){

  servo_init();
  adc_init();
  uart_init();
  sei();


while(1){

  if(uart_str_complete==1){
  uart_puts(buffer);
  uart_str_complete=0;

  }
  ADCSRA |= (1<<ADSC);
    while(ADCSRA & (1<<ADSC));
    uint16_t c= ADCW;
    if(atoi(s)<=c-2 || atoi(s)>=c+2){
    itoa(c,s,10);
    //uart_puts(s);
    }
  }
  return 0;
}




ISR(USART_RXC_vect)
{

  if (servo==1)servoSteuer();

  else{

    unsigned char nextChar;

    // Daten aus dem Puffer lesen
    nextChar = UDR;

    if (nextChar=='s'){
    servo=1;

    }else{

      if( uart_str_complete == 0 ) {

      if( nextChar != '\n' &&
        nextChar != '\r' &&
        uart_str_count < 9 ) {
        buffer[uart_str_count] = nextChar;
        uart_str_count++;
        }
      else {
        buffer[uart_str_count] = '\0';
        uart_str_count=0;
        uart_str_complete=1;
        }
      }
      }
  }
}



void servoSteuer(void){

  uint8_t nextChar;
  nextChar = UDR;
  uart_putc(nextChar);

  if(nextChar !='s'){
    if(nextChar != '\r'){

      servopos[servo_count]=nextChar;
      servo_count++;

    }else{
      servo_count=0;
      servo=0;
      }

    }
}
[/c]
rausnehmen kann ich leider nichts, da ich nicht weiß wo das Problem 
liegt
Gast #2614446
Lesenswert?

arg Tippfehler
kann das ein Moderator löschen oder so?
danke
hier richtig:
1
#include <avr/io.h> 
2
#define F_CPU 16000000UL /* evtl. bereits via Compilerparameter definiert */
3
#define BAUD 38400UL
4
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
5
#include <avr/delay.h>
6
#include <stdlib.h>
7
#include <avr/interrupt.h> 
8
#include <string.h>
9

10

11
char s[4];
12
char buffer[10];
13
volatile uint8_t uart_str_count=0;
14
volatile uint8_t servo=0;
15
volatile uint8_t servo_count=0;
16
volatile uint8_t uart_str_complete = 0;
17
volatile uint8_t servopos[8];
18
uint8_t servo0=0;
19

20
void servo_init()
21
{
22
  //Timer 1
23
  OCR1A = F_CPU /100000; //alle 10 µs IRQ
24
  TIMSK|=(1<<OCIE1A) | (1<<TOIE0) ;
25
  TCCR0 =(1<<CS02)|(1<<CS00) ; // CTC Modus  //Prescale=8, CTC mode
26
  
27
  
28
  
29
  DDRD=0xFF;
30
  DDRC |= (1<<PC0) | (1<<PC1);
31
  servopos[0]=180; //links oben oben
32
  servopos[1]=180; //rechts oben unten
33
  servopos[2]=70; // links unten unten
34
  servopos[3]=80; //links oben unten
35
  servopos[4]=190;//rechts oben oben
36
  servopos[5]=80;//links unten oben
37
  servopos[6]=160;//rechts unten unten
38
  servopos[7]=110;//rechts unten oben
39
  
40
}
41

42
ISR(TIMER0_OVF_vect)
43
{
44
  //Timer 0
45

46
  TCCR1B |= (1<<WGM12) | (1<<CS10);
47
}
48

49
ISR(TIMER1_COMPA_vect)
50
{
51
  
52
  static long count;
53
  uint8_t temp=0;
54
  
55
  if(servopos[0]>count) temp |=(1<<PD2);
56
  if(servopos[1]>count) temp |=(1<<PD3);
57
  if(servopos[2]>count) temp |=(1<<PD4);
58
  if(servopos[3]>count) temp |=(1<<PD5);
59
  if(servopos[4]>count) temp |=(1<<PD6);
60
  if(servopos[5]>count) temp |=(1<<PD7);
61
  if(servopos[6]>count) PORTC |=(1<<PC0);
62
  else PORTC &=~(1<<PC0);
63
  if(servopos[7]>count) PORTC |=(1<<PC1);
64
  else PORTC &=~(1<<PC1);
65

66

67
  
68
  PORTD = temp;
69
  
70
    if(count<2000)count++; // Die Impulse sollten alle 2ms gesendet werden
71
    else{
72
      count=0;
73
      TCCR1B =0;
74
      TCCR0 =(1<<CS02)|(1<<CS00);
75
      }
76
  
77
}
78

79

80

81
void uart_init(void)   
82
{
83
  UBRRH = UBRR_VAL>>8;
84
  UBRRL = UBRR_VAL;
85
  UCSRB = (1 << RXEN) | (1 << TXEN) |(1<<RXCIE);
86
  UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
87

88
}
89

90

91

92
void adc_init(void)
93
{
94

95
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
96
  ADMUX=0 | (0<<REFS1) | (1<<REFS0);
97

98
}
99

100

101

102
int uart_putc(unsigned char c)
103
{
104
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
105
    {}                             
106
 
107
    UDR = c;                      /* sende Zeichen */
108
    return 0;
109
}
110

111

112

113

114
uint8_t uart_getc(void)
115
{
116
    while (!(UCSRA & (1<<RXC)));   // warten bis Zeichen verfuegbar
117
   
118
    return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
119
}
120

121

122

123

124
void uart_puts (char *st)
125
{
126
    while (*st)
127
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
128
        uart_putc(*st);
129
        st++;
130
    }
131
  //uart_putc(' ');
132
}
133

134

135

136

137
int main(void){
138

139
  servo_init();
140
  adc_init();
141
  uart_init();
142
  sei();
143
  
144
  
145
while(1){
146
  
147
  if(uart_str_complete==1){
148
  uart_puts(buffer);
149
  uart_str_complete=0;
150
  
151
  }
152
  ADCSRA |= (1<<ADSC);
153
    while(ADCSRA & (1<<ADSC));
154
    uint16_t c= ADCW;
155
    if(atoi(s)<=c-2 || atoi(s)>=c+2){
156
    itoa(c,s,10);
157
    //uart_puts(s);
158
    }
159
  }
160
  return 0;
161
}
162

163

164

165

166
ISR(USART_RXC_vect)
167
{
168

169
  if (servo==1)servoSteuer();
170

171
  else{
172

173
    unsigned char nextChar;
174

175
    // Daten aus dem Puffer lesen
176
    nextChar = UDR;
177

178
    if (nextChar=='s'){
179
    servo=1;
180
 
181
    }else{
182

183
      if( uart_str_complete == 0 ) {
184
  
185
      if( nextChar != '\n' &&
186
        nextChar != '\r' &&
187
        uart_str_count < 9 ) {
188
        buffer[uart_str_count] = nextChar;
189
        uart_str_count++;
190
        }
191
      else {
192
        buffer[uart_str_count] = '\0'; 
193
        uart_str_count=0;
194
        uart_str_complete=1;
195
        }  
196
      }
197
      }
198
  }
199
}
200

201

202

203
void servoSteuer(void){
204

205
  uint8_t nextChar;
206
  nextChar = UDR;
207
  uart_putc(nextChar);
208
  
209
  if(nextChar !='s'){
210
    if(nextChar != '\r'){
211
      
212
      servopos[servo_count]=nextChar;
213
      servo_count++;
214
      
215
    }else{
216
      servo_count=0;
217
      servo=0;
218
      }  
219
    
220
    }
221
}
Gast #2614464
Lesenswert?

Christian schrieb:
> OCR1A = F_CPU /100000; //alle 10 µs IRQ

Gibt bei 16 MHz gerade einmal 160 Befehle zwiischen 2 Timerinterrupts.
Das wird dir die komplette Prozessorzeit aufbrauchen.

Du musst deine Servoroutine optimieren, am besten verteilst du alle 
Servopulse über eine Servoperiode. Dafür gibts hier irgendwo ein sehr 
gutes Beispiel.
Gast #2614476
Lesenswert?

ja aber der Timer1 läuft doch nur alle 18 ms mal 2 ms lang mehr net das 
hiese ich habe kurz 2 ms volle auslastung und dann wieder nix dachte das 
wäre ok.
Aber ich bin immer für bessere Lösungen offen
Gast #2615514
Lesenswert?

so habe jetzt mal bissl was geändert
die servos funktionieren so im groben alle, jedoch habe ich es bisher 
versucht die Servos auf folgende Weise zu steuern:

ich sende an die UART 's SERVOWERT SERVOWERT ....'
somit wird durch das s signalisiert, dass ich Servos anspreche und die 
Servos nehmen der Rheie nach die Werte an. Dies klappt bis Servo 3 
danach empfängt die Uart nichtsmehr. Wieso? nicht genug Zeit zwischen 
zwei Intterupts?
Wie kann ich es besser machen?
1
//
2
// Programm fuer einen ATmega16
3
//
4
#define F_CPU 16000000UL
5
 
6
#include <avr/io.h>
7
#include <avr/interrupt.h>
8
#include <util/delay.h>
9
#define BAUD 115200UL
10
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
11
#include <stdlib.h>
12
#include <string.h>
13
 
14
//
15
// Der Prescaler muss so gewählt werden, dass der Ausdruck
16
// für MILLISEC_BASE einen Wert kleiner als 128 ergibt
17
// MILLISEC_BASE ist der Timerwert, der 1 Millisekunde Zeitdauer ergeben
18
// soll.
19
//
20
#define PRESCALER      128
21
#define PRESCALER_BITS (1<<CS22) | ( 1 << CS20 )
22
 
23
#define MILLISEC_BASE  ( F_CPU / PRESCALER / 1676 )
24
#define CENTER         ( MILLISEC_BASE / 2 ) 
25
 
26
//
27
// Konfiguration der Servoleitungen
28
//
29
#define NR_SERVOS      6
30
#define SERVO_DDR      DDRD
31
#define SERVO_PORT     PORTD
32
uint8_t ServoPuls[NR_SERVOS] = { 1<<PD2, 1<<PD3, 1<<PD4, 1<<PD5,
33
                                 1<<PD6, 1<<PD7 };
34
//
35
// Werte für die Servoposition
36
// Gültige Werte laufen von 0 bis 2 * CENTER
37
// 0           ... ganz links
38
// CENTER      ... Mittelstellung
39
// 2 * CENTER  ... ganz rechts
40
//
41
volatile uint8_t ServoValue[NR_SERVOS];
42

43
char s[4];
44
char buffer[10];
45
volatile uint8_t uart_str_count=0;
46
volatile uint8_t servo=0;
47
volatile uint8_t servo_count=0;
48
volatile uint8_t uart_str_complete = 0;
49

50
void uart_init(void)   
51
{
52
   UBRRH = UBRR_VAL>>8;
53
   UBRRL = UBRR_VAL;
54
   /* evtl. verkuerzt falls Register aufeinanderfolgen (vgl. Datenblatt)
55
      UBRR = UBRR_VALUE;
56
   */
57

58
 UCSRB = (1 << RXEN) | (1 << TXEN) |(1<<RXCIE);
59
 UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
60

61
}
62

63
void adc_init(void){
64

65
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
66
  ADMUX=0 | (0<<REFS1) | (1<<REFS0);
67

68
}
69

70
int uart_putc(unsigned char c)
71
{
72
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
73
    {
74
    }                             
75
 
76
    UDR = c;                      /* sende Zeichen */
77
    return 0;
78
}
79

80
uint8_t uart_getc(void)
81
{
82
    while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
83
        ;
84
    return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
85
}
86

87
void uart_puts (char *st)
88
{
89
    while (*st)
90
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
91
        uart_putc(*st);
92
        st++;
93
    }
94
  //uart_putc(' ');
95
}
96

97
 
98
ISR (TIMER2_COMP_vect) 
99
{
100
  static uint8_t ServoId = 0;
101
 
102
  //
103
  // den Puls des aktuellen Servos beenden
104
  //
105
  SERVO_PORT &= ~ServoPuls[ServoId];
106
 
107
  //
108
  // welches ist das nächste aktuelle Servo?
109
  //
110
  if( ++ServoId >= NR_SERVOS )
111
    ServoId = 0;
112
 
113
  //
114
  // die Ausgangsleitung fuer dieses Servo auf 1; den Puls beginnen
115
  //
116
  SERVO_PORT |= ServoPuls[ServoId];
117
 
118
  //
119
  // den Timer so einstellen, dass bei Pulsende, die ISR erneut aufgerufen wird
120
  //
121
  OCR2 = MILLISEC_BASE + ServoValue[ServoId];
122
}
123
 
124
void InitServo()
125
{
126
  uint8_t i;
127
 
128
  //
129
  // Die Servoleitungen auf Ausgang stellen
130
  //
131
  SERVO_DDR = ServoPuls[0] | ServoPuls[1] | ServoPuls[2] | ServoPuls[3] |
132
              ServoPuls[4] | ServoPuls[5] ;
133
 
134
  //
135
  // Alle Servos in Mittelstellung
136
  //
137
  for( i = 0; i < NR_SERVOS; ++i )
138
    ServoValue[i] = CENTER;
139
 
140
  //
141
  // Timer auf CTC Modus konfigurieren
142
  //
143
  OCR2 = MILLISEC_BASE + ServoValue[0];
144
  TIMSK |= (1<<OCIE2);
145
  TCCR2 = (1<<WGM21) | PRESCALER_BITS;  // CTC mode
146
}
147
 
148
int main(void)
149
{
150
  InitServo();
151
  adc_init();
152
  uart_init();
153
 
154
  sei();
155
 
156
  _delay_ms( 1000 );
157
 
158
  //
159
  // testweise einfach alle 8 Servos ansteuern
160
  // jedes Servo soll sich unterschiedlich schnell bewegen
161
  //
162
  while( 1 ) {
163
 
164
 
165
   
166
    _delay_ms( 40 );
167
  }
168
}
169

170
ISR(USART_RXC_vect)
171

172
  {
173
  uart_putc(UDR);
174
 if (servo==1)servoSteuer();
175
 else{
176
 unsigned char nextChar;
177

178
  // Daten aus dem Puffer lesen
179
  nextChar = UDR;
180

181
 if (nextChar=='s'){
182
 servo=1;
183
 
184
 }else{
185

186
    if( uart_str_complete == 0 ) {
187
    // Daten werden erst in uart_string geschrieben, wenn nicht String-Ende/max Zeichenlänge erreicht ist/string gerade verarbeitet wird
188
    if( nextChar != '\n' &&
189
        nextChar != '\r' &&
190
        uart_str_count < 9 ) {
191
      buffer[uart_str_count] = nextChar;
192
      uart_str_count++;
193
    }
194
    else {
195
      buffer[uart_str_count] = '\0'; 
196
      uart_str_count=0;
197
    uart_str_complete=1;
198
    
199
         }
200
  }
201
  }
202
  }
203
}
204

205
void servoSteuer(void){
206

207
  uint8_t nextChar;
208
  
209
  // Daten aus dem Puffer lesen
210
  nextChar = UDR;
211
  uart_putc(nextChar);
212
  
213
  if(nextChar !='s'){
214
   if(
215
       nextChar != '\r'){
216
      
217
    
218
      
219
      ServoValue[servo_count]=nextChar;
220
      servo_count++;
221
      
222
      
223
    
224
    }else{
225
    servo_count=0;
226
    servo=0;
227
    }
228
    
229
  }
230
}

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