Forum: Mikrocontroller und Digitale Elektronik Probleme mit Uart und ISR


von Christian (Gast)


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
}

von Karl H. (kbuchegg)


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.

von Christian (Gast)


Lesenswert?

ok ein Fehler hat sich eingeschlichen in der ISR von TIMER1 da müsste er 
statt bis 2000 bis 200 zählen rein logisch. Aber das klappt dann 
garnicht mehr. :(

von Christian (Gast)


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

von Christian (Gast)


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

von Christian (Gast)


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
}

von Floh (Gast)


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.

von Christian (Gast)


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

von Christian (Gast)


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
}

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.