Rev 54 | Rev 56 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
28 | walter | 1 | //############################################################################ |
51 | walter | 2 | // - PWM CTRL |
3 | // - Main |
||
28 | walter | 4 | // - ATMEGA8 mit 8MHz |
5 | // - Nur für den privaten Gebrauch |
||
6 | // - Keine Garantie auf Fehlerfreiheit |
||
7 | // - Kommerzielle Nutzung nur mit meiner Zustimmung |
||
8 | // - walter Meyer @ www.freakware.de |
||
9 | // - 11.12.2007 |
||
10 | // - Make sure Fuses are programmed for internal 8 MHz RC Oscilator |
||
11 | //############################################################################*/ |
||
12 | |||
13 | #include "main.h" |
||
14 | #include "uart.h" |
||
15 | #include "twislave.h" |
||
16 | |||
55 | walter | 17 | volatile unsigned int PPM_SIGNAL = 1500; |
18 | volatile unsigned char PPM_NEW = 0; |
||
28 | walter | 19 | volatile unsigned char TMR1OvF = 0; |
51 | walter | 20 | volatile unsigned int TMR1MS; |
55 | walter | 21 | volatile unsigned char CH0; |
22 | volatile unsigned char CH1; |
||
23 | volatile unsigned char CH2; |
||
24 | volatile unsigned char CH3; |
||
25 | volatile unsigned char CH4; |
||
26 | volatile unsigned char CH5; |
||
52 | walter | 27 | |
28 | |||
55 | walter | 29 | /*##############################################################################*/ |
28 | walter | 30 | SIGNAL(SIG_OVERFLOW1) |
31 | { |
||
32 | TMR1OvF++; |
||
33 | } |
||
34 | |||
35 | |||
36 | SIGNAL(SIG_INPUT_CAPTURE1) |
||
37 | { |
||
38 | static unsigned int pos_ICR; |
||
39 | static unsigned int ppm; |
||
40 | |||
41 | if ((TCCR1B & (1<<ICES1)) != 0) //rising edge |
||
42 | { |
||
43 | TCCR1B &= ~(1<<ICES1); //set falling egde |
||
44 | TMR1OvF = 0; |
||
45 | pos_ICR = ICR1; |
||
46 | } |
||
47 | else //falling edge |
||
48 | { |
||
49 | TCCR1B |= (1<<ICES1); //set rising egde |
||
50 | ppm = (ICR1 - pos_ICR + (int) TMR1OvF * 65536); |
||
51 | if ((ppm > 600) && (ppm < 2400)) |
||
52 | { |
||
53 | if (ppm > 2100) ppm = 2100; |
||
54 | if (ppm < 900) ppm = 900; |
||
55 | walter | 55 | ppm = (PPM_SIGNAL * 3 + ppm) / 4; |
56 | PPM_SIGNAL = ppm; |
||
57 | if (PPM_NEW < 50) PPM_NEW++; |
||
28 | walter | 58 | } |
59 | |||
60 | } |
||
61 | |||
62 | } |
||
63 | |||
55 | walter | 64 | /*##############################################################################*/ |
28 | walter | 65 | SIGNAL(SIG_OVERFLOW0) |
66 | { |
||
52 | walter | 67 | // this function is called every 32us, |
68 | // it is very important that it's execution time is as short as possible |
||
69 | // currently it's about 20us |
||
70 | |||
71 | static unsigned char counter = 254; |
||
72 | static unsigned char ms1 = 0; |
||
55 | walter | 73 | static unsigned char ch0_tmp = 0; |
74 | static unsigned char ch1_tmp = 0; |
||
75 | static unsigned char ch2_tmp = 0; |
||
76 | static unsigned char ch3_tmp = 0; |
||
77 | static unsigned char ch4_tmp = 0; |
||
78 | static unsigned char ch5_tmp = 0; |
||
28 | walter | 79 | unsigned char PORTB_BAK; |
80 | unsigned char PORTD_BAK; |
||
81 | |||
82 | PORTB_BAK = PORTB; |
||
83 | PORTD_BAK = PORTD; |
||
84 | |||
51 | walter | 85 | if (counter++ == 254) |
28 | walter | 86 | { |
55 | walter | 87 | PORTB_BAK LEDON (CH0_B | CH1_B | CH2_B); //new cycle, output on |
88 | PORTD_BAK LEDON (CH3_D | CH4_D | CH5_D); // |
||
89 | ch0_tmp = CH0; |
||
90 | ch1_tmp = CH1; |
||
91 | ch2_tmp = CH2; |
||
92 | ch3_tmp = CH3; |
||
93 | ch4_tmp = CH4; |
||
94 | ch5_tmp = CH5; |
||
51 | walter | 95 | counter = 0; |
28 | walter | 96 | } |
97 | |||
55 | walter | 98 | if (ch0_tmp == counter) PORTB_BAK LEDOFF CH0_B; //channel value reached, output off |
99 | if (ch1_tmp == counter) PORTB_BAK LEDOFF CH1_B; // |
||
100 | if (ch2_tmp == counter) PORTB_BAK LEDOFF CH2_B; // |
||
101 | if (ch3_tmp == counter) PORTD_BAK LEDOFF CH3_D; // |
||
102 | if (ch4_tmp == counter) PORTD_BAK LEDOFF CH4_D; // |
||
103 | if (ch5_tmp == counter) PORTD_BAK LEDOFF CH5_D; // |
||
51 | walter | 104 | |
105 | PORTB = PORTB_BAK; |
||
106 | PORTD = PORTD_BAK; |
||
54 | walter | 107 | |
51 | walter | 108 | if (ms1++ == 32) |
28 | walter | 109 | { |
51 | walter | 110 | ms1=0; |
111 | TMR1MS++; |
||
28 | walter | 112 | } |
51 | walter | 113 | |
28 | walter | 114 | |
115 | |||
116 | |||
51 | walter | 117 | } |
28 | walter | 118 | |
119 | |||
55 | walter | 120 | /*##############################################################################*/ |
51 | walter | 121 | unsigned int SetDelay (unsigned int t) |
122 | { |
||
55 | walter | 123 | unsigned char hi_byte; |
124 | unsigned char lo_byte; |
||
28 | walter | 125 | |
55 | walter | 126 | hi_byte = (TMR1MS >> 8); |
127 | lo_byte = (TMR1MS & 0xff); |
||
128 | if (hi_byte != (TMR1MS >> 8)) hi_byte = (TMR1MS >> 8); |
||
28 | walter | 129 | |
55 | walter | 130 | return(((hi_byte << 8) | lo_byte) + t + 1); |
51 | walter | 131 | } |
28 | walter | 132 | |
133 | |||
55 | walter | 134 | /*##############################################################################*/ |
51 | walter | 135 | char CheckDelay(unsigned int t) |
136 | { |
||
55 | walter | 137 | unsigned char hi_byte; |
138 | unsigned char lo_byte; |
||
51 | walter | 139 | |
55 | walter | 140 | hi_byte = (TMR1MS >> 8); |
141 | lo_byte = (TMR1MS & 0xff); |
||
142 | if (hi_byte != (TMR1MS >> 8)) hi_byte = (TMR1MS >> 8); |
||
51 | walter | 143 | |
55 | walter | 144 | return(((t - ((hi_byte << 8) | lo_byte)) & 0x8000) >> 9); |
28 | walter | 145 | } |
146 | |||
147 | |||
148 | |||
149 | /*##############################################################################*/ |
||
51 | walter | 150 | void StartPWM(void) |
28 | walter | 151 | { |
55 | walter | 152 | //Timer 0 Config |
28 | walter | 153 | TCCR0 = (0<<CS02)|(0<<CS01)|(1<<CS00); // (@8MHz) = 1/8us Clk = 256/8 = 32us overflow |
154 | TIMSK setbit (1<<TOIE0); // enable Int |
||
155 | |||
156 | } |
||
157 | |||
158 | |||
159 | /*##############################################################################*/ |
||
160 | void StartPPM(void) |
||
161 | { |
||
162 | |||
55 | walter | 163 | //Timer1 Config |
28 | walter | 164 | TCCR1A = (0<<COM1A1)|(0<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)| |
165 | (0<<FOC1A) |(0<<FOC1B) |(0<<WGM10) |(0<<WGM11); |
||
166 | TCCR1B = (1<<ICNC1)|(1<<ICES1)|(0<<WGM13)| |
||
167 | (0<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10); //ICP_POS_FLANKE |
||
168 | |||
169 | // interrupts |
||
170 | TIMSK |= (1<<TICIE1)|(1<<TOIE1); //ICP_INT_ENABLE and TIMER1_INT_ENABLE |
||
171 | |||
172 | } |
||
173 | |||
174 | |||
52 | walter | 175 | /*##############################################################################*/ |
54 | walter | 176 | unsigned int GetPPM(void) |
28 | walter | 177 | { |
178 | //this routines seems to be nesseccary, as reading a 16 bit value |
||
179 | //on a 8 bit machine is not atomic, so if an interrupt apears between reading |
||
180 | //low and high byte of the 16 bit value a wrong result is possible |
||
181 | |||
54 | walter | 182 | unsigned char temp_hi; |
183 | unsigned char temp_lo; |
||
28 | walter | 184 | |
55 | walter | 185 | temp_hi = (PPM_SIGNAL >> 8); |
186 | temp_lo = (PPM_SIGNAL & 0xff); |
||
187 | if (temp_hi != (PPM_SIGNAL >> 8)) temp_hi = (PPM_SIGNAL >> 8); |
||
54 | walter | 188 | return( (temp_hi << 8) | temp_lo); |
28 | walter | 189 | |
190 | } |
||
191 | |||
192 | |||
193 | /*##############################################################################*/ |
||
194 | // MAIN |
||
195 | /*##############################################################################*/ |
||
196 | int main (void) |
||
197 | { |
||
54 | walter | 198 | |
55 | walter | 199 | #define STEP 256 |
200 | #define MUL 1 |
||
201 | #define REDUCE 5 |
||
54 | walter | 202 | |
55 | walter | 203 | #define EEPADRSIG 0x00 |
204 | #define EEPADRMIN 0x20 |
||
205 | #define EEPADRMAX 0x22 |
||
206 | #define EEPSIGATURE 0x55aa |
||
54 | walter | 207 | |
53 | walter | 208 | unsigned int ppm; |
55 | walter | 209 | signed int color; |
54 | walter | 210 | unsigned int setupdly; |
211 | unsigned int ppmtodly; |
||
55 | walter | 212 | unsigned int flashdly; |
213 | unsigned char setup; |
||
54 | walter | 214 | unsigned int lmax; |
215 | unsigned int lmin; |
||
216 | unsigned int max; |
||
217 | unsigned int min; |
||
55 | walter | 218 | unsigned long temp1; |
219 | unsigned long temp2; |
||
28 | walter | 220 | |
54 | walter | 221 | |
55 | walter | 222 | |
51 | walter | 223 | DDRB = (CH0_B|CH1_B|CH2_B); |
224 | PORTB = 0x00; |
||
225 | |||
226 | DDRC = (ledred); |
||
28 | walter | 227 | PORTC = 0x00; |
51 | walter | 228 | |
229 | DDRD = (ledgreen|CH3_D|CH4_D|CH5_D); |
||
28 | walter | 230 | PORTD = 0x00; |
231 | |||
55 | walter | 232 | CH0 = 0; |
233 | CH1 = 0; |
||
234 | CH2 = 0; |
||
235 | CH3 = 0; |
||
236 | CH4 = 0; |
||
237 | CH5 = 0; |
||
28 | walter | 238 | |
54 | walter | 239 | lmax = 0x0000; |
240 | lmin = 0xffff; |
||
241 | |||
242 | StartUART(); |
||
28 | walter | 243 | StartPPM(); |
51 | walter | 244 | //StartI2C(); |
28 | walter | 245 | StartPWM(); |
246 | sei(); |
||
247 | |||
51 | walter | 248 | |
249 | |||
55 | walter | 250 | if (eeprom_read_word(EEPADRSIG) != EEPSIGATURE) //check eep if signature is there |
54 | walter | 251 | { |
55 | walter | 252 | min = 1100; //default min |
253 | max = 1900; //default max |
||
254 | eeprom_write_word(EEPADRMIN, min); //no, write initial min |
||
255 | eeprom_write_word(EEPADRMAX, max); //and max values |
||
256 | eeprom_write_word(EEPADRSIG, EEPSIGATURE); //along with eep signature |
||
54 | walter | 257 | } |
258 | else |
||
259 | { |
||
55 | walter | 260 | min = eeprom_read_word(EEPADRMIN); //signature ok |
261 | max = eeprom_read_word(EEPADRMAX); //read min and max |
||
54 | walter | 262 | } |
51 | walter | 263 | |
55 | walter | 264 | setup = 0; //reset setup toggle counter |
54 | walter | 265 | setupdly = SetDelay(3000); |
266 | ppmtodly = SetDelay(5000); |
||
55 | walter | 267 | flashdly = SetDelay(100); |
28 | walter | 268 | |
269 | while (1) |
||
270 | { |
||
51 | walter | 271 | |
55 | walter | 272 | if (PPM_NEW > 20) //ppm Signal ok |
54 | walter | 273 | { |
274 | PORTC clrbit ledred; |
||
55 | walter | 275 | ppm = GetPPM(); |
276 | ppmtodly = SetDelay(500); //reset timeout |
||
277 | if (lmax < ppm) lmax=ppm; //update impulse max |
||
278 | if (lmin > ppm) lmin=ppm; //and min boundarys |
||
54 | walter | 279 | } |
280 | else |
||
281 | { |
||
55 | walter | 282 | PORTC setbit ledred; //ppm signal not ok |
283 | ppm = min; //set ppm to minimum |
||
54 | walter | 284 | } |
285 | |||
55 | walter | 286 | |
287 | if (CheckDelay(ppmtodly)) //timeout |
||
54 | walter | 288 | { |
55 | walter | 289 | ppmtodly = SetDelay(5000); |
290 | PPM_NEW = 0; //set ppm signal not ok |
||
291 | } |
||
292 | |||
293 | |||
294 | if (setup < 6) |
||
295 | { |
||
296 | if ((ppm > 1600) && ((setup&1)==0)) setup++; // |
||
297 | if ((ppm < 1400) && ((setup&1)==1)) setup++; // |
||
298 | |||
299 | if (CheckDelay(flashdly)) //setup timeout reached |
||
300 | { |
||
301 | CH0 = CH0 ^ 0xff; |
||
302 | CH1 = CH1 ^ 0xff; |
||
303 | CH2 = CH2 ^ 0xff; |
||
304 | flashdly = SetDelay(250); |
||
305 | } |
||
306 | |||
54 | walter | 307 | } |
28 | walter | 308 | |
55 | walter | 309 | if (setup == 6) //if stick is toggled 6 times |
310 | { //within setup timeout |
||
311 | PORTD setbit ledgreen; //store ppm min and max |
||
312 | eeprom_write_word(EEPADRMIN, lmin); //in eeprom |
||
313 | eeprom_write_word(EEPADRMAX, lmax); |
||
314 | min = lmin; |
||
54 | walter | 315 | max = lmax; |
55 | walter | 316 | setupdly = SetDelay(2000); |
317 | |||
318 | if (CheckDelay(flashdly)) //setup timeout reached |
||
319 | { |
||
320 | CH0 = CH0 ^ 0xff; |
||
321 | CH1 = CH1 ^ 0xff; |
||
322 | CH2 = CH2 ^ 0xff; |
||
323 | flashdly = SetDelay(25); |
||
324 | } |
||
325 | |||
54 | walter | 326 | } |
55 | walter | 327 | |
328 | if (CheckDelay(setupdly)) //setup timeout reached |
||
54 | walter | 329 | { |
55 | walter | 330 | setup = 7; //lockdown setup |
54 | walter | 331 | PORTD clrbit ledgreen; |
332 | } |
||
53 | walter | 333 | |
54 | walter | 334 | //printf("ppm: %d / min: %d / max: %d\n",ppm,lmin,lmax); |
335 | |||
55 | walter | 336 | |
337 | |||
338 | if (setup = 7) |
||
51 | walter | 339 | { |
54 | walter | 340 | |
55 | walter | 341 | temp1 = (STEP * (long)40000 * (long)6) / ((max-REDUCE) - (min+REDUCE)); |
342 | temp2 = ((ppm - (min+REDUCE)) * temp1); |
||
343 | color = temp2 / 40000; |
||
54 | walter | 344 | |
55 | walter | 345 | if (color < 0) color = 0; |
346 | if (color > (STEP * 6)) color = (STEP * 6); |
||
347 | |||
348 | // Farbablauf: rot > Violett > blau > tuerkis > gruen > gelb > |
||
349 | if ((color >= (STEP * 0)) && (color < (STEP * 1))) |
||
350 | { |
||
351 | CH0 = MUL * ((color - (STEP * 0))); //fade in red > red (red only) |
||
352 | CH1 = 0; |
||
353 | CH2 = 0; |
||
354 | } |
||
355 | if ((color >= (STEP * 1)) && (color < (STEP * 2))) |
||
356 | { |
||
357 | CH0 = ((STEP-1) * MUL); |
||
358 | CH1 = 0; |
||
359 | CH2 = MUL * ((color - (STEP * 1))); //fade in blue > purple (red + blue) |
||
360 | } |
||
361 | if ((color >= (STEP * 2)) && (color < (STEP * 3))) |
||
362 | { |
||
363 | CH0 = MUL * ((STEP - 1) - (color - (STEP * 2))); //fade out red > blue (blue only) |
||
364 | CH1 = 0; |
||
365 | CH2 = ((STEP-1) * MUL); |
||
366 | } |
||
367 | if ((color >= (STEP * 3)) && (color < (STEP * 4))) |
||
368 | { |
||
369 | CH0 = 0; |
||
370 | CH1 = MUL * ((color - (STEP * 3))); //fade in green > cyan (blue + green) |
||
371 | CH2 = ((STEP-1) * MUL); |
||
372 | } |
||
373 | if ((color >= (STEP * 4)) && (color < (STEP * 5))) |
||
374 | { |
||
375 | CH0 = 0; |
||
376 | CH1 = ((STEP-1) * MUL); |
||
377 | CH2 = MUL * ((STEP - 1) - (color - (STEP * 4))); //fade out blue > green (green only) |
||
378 | } |
||
379 | if ((color >= (STEP * 5)) && (color < (STEP * 6))) |
||
380 | { |
||
381 | CH0 = MUL * ((color - (STEP * 5))); //fade in red > yellow (green + red) |
||
382 | CH1 = ((STEP-1) * MUL); |
||
383 | CH2 = 0; |
||
384 | } |
||
385 | if (color >= (STEP * 6)) |
||
386 | { |
||
387 | CH0 = ((STEP-1) * MUL); //fade in red > yellow (green + red) |
||
388 | CH1 = ((STEP-1) * MUL); |
||
389 | CH2 = 0; |
||
390 | } |
||
391 | } |
||
51 | walter | 392 | |
393 | |||
28 | walter | 394 | } |
395 | |||
396 | } |
||
52 | walter | 397 |