Servosteuerung.c


1
// Steuerung zweier Servos über einen ATmega162 und dessen Timer1
2
// Setzen der Portpins durch das Overflow-Interrupt
3
// Rücksetzen der Portpins durch die Output-Compare-Interrupts.
4
// Servo1 an PORTE 0, Servo 2 an PORTE 1
5
// Multi-Switch-Ausgänge (LEDs) an PORTD
6
// Multi-Switch-Eingang auf PORTE 0
7
// 15.Oktober 2005
8
9
#include <avr/io.h>
10
#include <avr/interrupt.h>
11
#include <avr/signal.h>
12
13
#define Startwert 0x0E66
14
#define Endwert 0x1CCC
15
#define Mittelwert 0x1599
16
#define teiler (Endwert-Startwert)/8
17
18
#define baud 19200
19
#define fosc 3686411  // 3,686MHz
20
#define ubrval  (fosc/(16L*baud))-1
21
22
#define two_ms 2*fosc/1000L
23
#define one_ms 1*fosc/1000L
24
#define hundert_mikro 1*fosc/10000L
25
26
#define sync_lower 0x0F00
27
#define sync_upper 0x1D00
28
#define ein_lower 0x1500
29
#define ein_upper 0x1CFF
30
#define aus_lower 0x1500
31
#define aus_upper 0x1800
32
33
#define BufferMax 255
34
35
volatile unsigned int Servo1, Servo2;  // Reload-Werte
36
volatile unsigned int inkrement1, inkrement2; // Änderungswerte
37
volatile unsigned char umsch1, umsch2; // Richtungsangabe
38
volatile unsigned char dec,dec0;  // Refresh
39
volatile unsigned char overflow;  // byte wird bei Überlauf gesetzt, bei ICP steigend gelöscht als Übertrag
40
volatile unsigned int icp_rise,icp_fall,icp; // Werte des InputCapture für die jeweilige Flanke
41
volatile unsigned int teil; // Anzeige
42
volatile unsigned int icpmin, icpmax;
43
volatile unsigned char portwert, newicp, bitcount;
44
45
volatile unsigned char Buffer[BufferMax]; 
46
volatile unsigned char Buffercount, send;
47
48
void initRS232(void)
49
{
50
  UBRR1H = (unsigned char) (ubrval >> 8);
51
  UBRR1L = (unsigned char) ubrval;
52
  UCSR1B = ((1<<RXEN1) | (1<< RXCIE1) | (1<<TXEN1) | (1<<UDRIE1));
53
  UCSR1C = ((1<<UCSZ11) | (1<<UCSZ10) | (1<<URSEL1));
54
  
55
}
56
57
58
SIGNAL(SIG_USART1_DATA)
59
{
60
  UDR1 = Buffer[send++];
61
  if   (Buffer[send-1] == 0xFF) UCSR1B = ((1<<RXEN1) | (1<< RXCIE1) | (1<<TXEN1));
62
}
63
64
SIGNAL(SIG_USART1_RECV)
65
{
66
  volatile unsigned char Zeichen;
67
  Zeichen = UDR1;
68
}
69
70
71
SIGNAL(SIG_OVERFLOW1)
72
{
73
  PORTE = 0x06; // beide Servos "einschalten"
74
  /*if (PORTD & 0x04)
75
  {
76
    PORTD &= ~0x04;
77
  }
78
  else
79
  {
80
    PORTD |= 0x04;
81
  }*/
82
  overflow++;
83
  dec--;
84
  if (dec == 0) 
85
  {
86
    dec = dec0;
87
    if (umsch1 == 0) 
88
    {
89
      Servo1 += inkrement1;
90
    }
91
    else
92
    {
93
      Servo1 -= inkrement1;
94
    }
95
    
96
    if ((Servo1 < Startwert) || (Servo1 >= Endwert)) umsch1 = ~umsch1;
97
    
98
    if (umsch2 == 0)
99
    {
100
      Servo2 += inkrement2;
101
    }
102
    else
103
    {
104
      Servo2 -= inkrement2;
105
    }
106
  
107
    if ((Servo2 < Startwert) || (Servo2 > Endwert)) umsch2 = ~umsch2;
108
109
    OCR1A = Servo1;
110
    OCR1B = Servo2;
111
  }
112
}
113
114
SIGNAL(SIG_OUTPUT_COMPARE1A)
115
{
116
  PORTE &= ~0x02;  // Servo 1 ausschalten
117
}
118
119
SIGNAL(SIG_OUTPUT_COMPARE1B)
120
{
121
  PORTE &= ~0x04; // Servo 2 ausschalten
122
}
123
124
SIGNAL (SIG_INPUT_CAPTURE1)
125
{
126
  if (TCCR1B & (1<<ICES1))
127
  {
128
    // ICES1 == 1, rising edge
129
    icp_rise = ICR1;
130
    TCCR1B &= ~(1<<ICES1); // ICES1 löschen
131
  }
132
  else
133
  {
134
    // ICES1 == 0, falling Edge
135
    icp_fall = ICR1;
136
    TCCR1B |= (1<<ICES1);  // ICES1 setzen
137
    icp = icp_fall - icp_rise;
138
    newicp = 1;
139
  }
140
}
141
142
int main(void)
143
{
144
  DDRD = 0xFF;  // alle Pins als Ausgang
145
  PORTD = 0xFF;  // alle LEDs aus (STK500)
146
  
147
  DDRE = 0x06;  // zwei Pins als Ausgang
148
  PORTE = 0x01;  // low am Ausgang. Pull-Up einschalten
149
150
  Servo1 = Mittelwert;
151
  Servo2 = Startwert;
152
  
153
  OCR1A = Servo1;
154
  OCR1B = Servo2;
155
  
156
  inkrement1 = 0x25;
157
  inkrement2 = 0x12;
158
  
159
  dec0 = 1;
160
  dec = dec0;
161
  
162
  umsch1 = 0;
163
  umsch2 = 0;
164
  
165
  icpmin = 0xFFFF;
166
  icpmax = 0x0000;
167
  
168
  send = 0;
169
  Buffercount = 0;
170
  
171
  TIMSK = ((1<<TOIE1) | (1<<OCIE1A) | (1<<OCIE1B) | (1<<TICIE1));
172
  
173
  sei();
174
    
175
  TCCR1B = ((1<<CS10) | (1<<ICNC1) | (1<<ICES1));
176
  
177
  for(;;)
178
  {
179
    if (newicp != 0)
180
    {
181
      newicp = 0;
182
      if ((icp >= one_ms) && (icp <= two_ms)) overflow = 0;
183
        
184
      if (icp < icpmin) icpmin = icp;
185
      if (icp > icpmax) icpmax = icp;
186
      
187
      if ((Buffercount == 0) && (((icp>>8) == 0x0E) || ((icp>>8) == 0x1E)))
188
      {
189
        Buffer[Buffercount++] = '!';
190
      }
191
      
192
      if ((Buffercount < 100) && (Buffercount >0))
193
      {
194
        //Buffer[Buffercount++] = (unsigned char) ((icp>>12) & 0x0F);
195
        //Buffer[Buffercount++] = (unsigned char) ((icp>>8) & 0x0F);
196
        //Buffer[Buffercount++] = (unsigned char) ((icp>>4) & 0x0F);
197
        //Buffer[Buffercount++] = (unsigned char) ((icp) & 0x0F);
198
        //Buffer[Buffercount++] = '!';
199
200
        if (icp > sync_upper) // FC-16
201
          {
202
            // Sync
203
            Buffer[Buffercount++] = 'S';
204
          }
205
          else
206
          {
207
            if (icp > ein_lower) //FC-16
208
            {
209
              // einschalten
210
              Buffer[Buffercount++] = 'E';
211
            }
212
            else
213
            {
214
              Buffer[Buffercount++] = 'A';
215
            }
216
            Buffer[Buffercount++] = (unsigned char) ((icp>>12) & 0x0F);
217
            Buffer[Buffercount++] = (unsigned char) ((icp>>8) & 0x0F);
218
            Buffer[Buffercount++] = (unsigned char) ((icp>>4) & 0x0F);
219
            Buffer[Buffercount++] = (unsigned char) ((icp) & 0x0F);
220
          }
221
222
      }
223
      if ((Buffercount >= 100) && (Buffercount <= 211))
224
      {
225
        initRS232();
226
        Buffer[Buffercount++] = 'M';
227
        Buffer[Buffercount++] = (unsigned char) ((icpmax>>12) & 0x0F);
228
        Buffer[Buffercount++] = (unsigned char) ((icpmax>>8) & 0x0F);        
229
        Buffer[Buffercount++] = (unsigned char) ((icpmax>>4) & 0x0F);
230
        //Buffer[Buffercount++] = (unsigned char) ((icpmax) & 0x0F);
231
        Buffer[Buffercount++] = 'm';
232
        Buffer[Buffercount++] = (unsigned char) ((icpmin>>12) & 0x0F);
233
        Buffer[Buffercount++] = (unsigned char) ((icpmin>>8) & 0x0F);        
234
        Buffer[Buffercount++] = (unsigned char) ((icpmin>>4) & 0x0F);
235
        //Buffer[Buffercount++] = (unsigned char) ((icpmin) & 0x0F);
236
        Buffer[Buffercount++] = 'U';
237
        Buffer[Buffercount++] = (unsigned char) ((one_ms>>12) & 0x0F);
238
        Buffer[Buffercount++] = (unsigned char) ((one_ms>>8) & 0x0F);        
239
        Buffer[Buffercount++] = (unsigned char) ((one_ms>>4) & 0x0F);
240
        //Buffer[Buffercount++] = (unsigned char) ((one_ms) & 0x0F);
241
        Buffer[Buffercount++] = 'O';
242
        Buffer[Buffercount++] = (unsigned char) ((two_ms>>12) & 0x0F);
243
        Buffer[Buffercount++] = (unsigned char) ((two_ms>>8) & 0x0F);        
244
        Buffer[Buffercount++] = (unsigned char) ((two_ms>>4) & 0x0F);
245
        //Buffer[Buffercount++] = (unsigned char) ((two_ms) & 0x0F);
246
        Buffer[Buffercount++] = 'H';
247
        Buffer[Buffercount++] = (unsigned char) ((hundert_mikro>>12) & 0x0F);
248
        Buffer[Buffercount++] = (unsigned char) ((hundert_mikro>>8) & 0x0F);        
249
        Buffer[Buffercount++] = (unsigned char) ((hundert_mikro>>4) & 0x0F);
250
        //Buffer[Buffercount++] = (unsigned char) ((hundert_mikro) & 0x0F);
251
        Buffer[Buffercount++] = 0xFF;
252
        
253
        //PORTD = ~0xFF;
254
        Buffercount = 212;
255
      }
256
      
257
      //F-14
258
      /*
259
      if (icp < 0x1000) 
260
      {  // Sync
261
        bitcount = 0;
262
        PORTD = ~portwert;
263
      }
264
      else
265
      {
266
        if (icp < 0x1800) 
267
        {
268
          portwert |= (1<<bitcount); // einschalten
269
        }
270
        else
271
        {
272
          portwert &= ~(1<<bitcount);
273
        }
274
        bitcount++; // nächstes Bit
275
      }  */
276
      
277
      // FC-16
278
      /*
279
      if (icp > sync_upper) 
280
      {  // Sync
281
        bitcount = 0;
282
        PORTD = ~portwert;
283
      }
284
      else
285
      {
286
        if (icp > ein_lower) 
287
        {
288
          portwert |= (1<<bitcount); // einschalten
289
        }
290
        else
291
        {
292
          portwert &= ~(1<<bitcount);
293
        }
294
        bitcount++; // nächstes Bit
295
      }  
296
      */
297
      
298
      // universal
299
      if ((icp < sync_lower) || (icp > sync_upper))
300
      {
301
        // Sync
302
        bitcount = 0;
303
        PORTD = ~portwert;
304
        //overflow = 0;
305
      }
306
      else
307
      {
308
        if (( icp < ein_upper) && (icp > ein_lower))
309
        {
310
          // einschalten
311
          portwert |= (1<<bitcount);
312
        }
313
        else
314
        {
315
          portwert &= ~(1<<bitcount);
316
        }
317
        bitcount++;
318
      }
319
      if (overflow > 10) PORTD=0x00;  // Alle Verbraucher ausschalten
320
    }
321
  }
322
}