1 | //ICC-AVR application builder : 13.04.2010 16:15:44
|
2 | // Target : m48
|
3 | // Crystal: 8.0000Mhz
|
4 |
|
5 | #include <iom48v.h>
|
6 | #include <macros.h>
|
7 |
|
8 |
|
9 | unsigned int RulInt = 9;
|
10 | unsigned int WarnInt = 49;
|
11 |
|
12 | unsigned int f_1sec;
|
13 | unsigned char f_100ms;
|
14 |
|
15 |
|
16 | //------------------------------------------------------------------------------
|
17 | // Port-Zuweisung
|
18 | //------------------------------------------------------------------------------
|
19 |
|
20 | /* PORT B */
|
21 | //#define PB7
|
22 | //#define PB6
|
23 | #define jump2 PB5
|
24 | #define jump1 PB4
|
25 | #define servo3 PB3
|
26 | #define servo2 PB2
|
27 | #define servo1 PB1
|
28 | #define pin_taster PB0
|
29 |
|
30 | /* PORT C */
|
31 | #define poti1 PC7
|
32 | #define reset PC6
|
33 | #define pinnchen PC5
|
34 | //#define PC4
|
35 | //#define PC3
|
36 | #define sound1 PC2
|
37 | #define poti3 PC1
|
38 | #define poti2 PC0
|
39 |
|
40 | /* PORT D */
|
41 | #define ziel_led PD7
|
42 | #define pump1 PD6
|
43 | #define pump2 PD5
|
44 | #define R_LED4 PD4
|
45 | #define R_LED3 PD3
|
46 | #define R_LED2 PD2
|
47 | #define sound2 PD1
|
48 | #define R_LED1 PD0
|
49 |
|
50 |
|
51 |
|
52 | void port_init(void)
|
53 | {
|
54 | PORTB = 0xF1;
|
55 | DDRB = 0x0E;
|
56 | PORTC = 0x43;
|
57 | DDRC = 0xBC;
|
58 | PORTD = 0x00;
|
59 | DDRD = 0xFF;
|
60 | }
|
61 | //TIMER1 initialize - prescale:64
|
62 | // WGM: 0) Normal, TOP=0xFFFF
|
63 | // desired value: 100mSec
|
64 | // actual value: 100,000mSec (0,0%)
|
65 | void timer1_init(void)
|
66 | {
|
67 | TCCR1B = 0x00; //stop
|
68 | TCNT1H = 0xCF; //setup
|
69 | TCNT1L = 0x2C;
|
70 | OCR1AH = 0x30;
|
71 | OCR1AL = 0xD4;
|
72 | OCR1BH = 0x30;
|
73 | OCR1BL = 0xD4;
|
74 | ICR1H = 0x30;
|
75 | ICR1L = 0xD4;
|
76 | TCCR1A = 0x00;
|
77 | TCCR1B = 0x03; //start Timer
|
78 | }
|
79 | #pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF
|
80 | void timer1_ovf_isr(void)
|
81 | {
|
82 | static unsigned int t1;
|
83 | //TIMER1 has overflowed
|
84 | TCNT1H = 0xCF; //reload counter high value
|
85 | TCNT1L = 0x2C; //reload counter low value
|
86 | if(t1) {t1=9; f_1sec=1;}
|
87 | else --t1;
|
88 |
|
89 | }
|
90 |
|
91 |
|
92 | //----------------------------------------------------------------------------//
|
93 | // Servo
|
94 | //----------------------------------------------------------------------------//
|
95 |
|
96 | // Bei dieser Funktion werden jeweils 2000x 10usec gezählt um 20milisec für das PPM-Signal zu erzeugen.
|
97 |
|
98 | volatile unsigned char servo1pos; //(98,7 =1msec bis 197,5 = 2msec)
|
99 | volatile unsigned char servo2pos; //(98,7 =1msec bis 197,5 = 2msec)
|
100 | volatile unsigned char servo3pos; //(98,7 =1msec bis 197,5 = 2msec)
|
101 |
|
102 | void servoweg(void)
|
103 | {
|
104 | static int count1;
|
105 | static int count2;
|
106 | static int count3;
|
107 | //----Servo 1-----------------------------------------------------------------//
|
108 |
|
109 | if(count1>servo1pos) {PORTB &= ~(1<<servo1);}
|
110 | else PORTB|=(1<<servo1);
|
111 |
|
112 | if(count1<2000+servo1pos)count1++;
|
113 | else count1=0;
|
114 | //----Servo 2-----------------------------------------------------------------//
|
115 |
|
116 | servo2pos = 20;
|
117 | if(count2>servo2pos) {PORTB&=~(1<<servo2);}
|
118 | else PORTB|=(1<<servo2);
|
119 |
|
120 | if(count2<2000+servo2pos)count2++;
|
121 | else count2=0;
|
122 | //----Servo 3-----------------------------------------------------------------//
|
123 |
|
124 | if(count3>servo3pos)PORTB&=~(1<<servo3);
|
125 | else PORTB|=(1<<servo3);
|
126 |
|
127 | if(count3<2000+servo3pos)count3++;
|
128 | else count3=0;
|
129 |
|
130 |
|
131 | }
|
132 |
|
133 | //TIMER2 initialize - prescale:1
|
134 | // WGM: Normal
|
135 | // desired value: 10uSec
|
136 | // actual value: 10,000uSec (0,0%)
|
137 | void timer2_init(void)
|
138 | {
|
139 | TCCR2B = 0x00; //stop
|
140 | ASSR = 0x00; //set async mode
|
141 | TCNT2 = 0xB0; //setup
|
142 | OCR2A = 0x50;
|
143 | OCR2B = 0x00;
|
144 | TCCR2A = 0x00;
|
145 | TCCR2B = 0x01; //start
|
146 | }
|
147 | #pragma interrupt_handler timer2_ovf_isr:iv_TIM2_OVF
|
148 | void timer2_ovf_isr(void)
|
149 | {
|
150 | static unsigned int t2;
|
151 | TCNT2 = 0xB0; //reload counter value
|
152 |
|
153 | //servoweg(); //HIER IST DER ÜBELTÄTER
|
154 |
|
155 | if(t2) {t2=9; f_100ms=1;}
|
156 | else --t2;
|
157 | }
|
158 | //ADC initialize
|
159 | // Conversion time: 6uS
|
160 | void adc_init(void)
|
161 | {
|
162 | ADCSRA = 0x00; //disable adc
|
163 | ADMUX = 0x00; //select adc input 0
|
164 | ACSR = 0x80;
|
165 | ADCSRB = 0x00;
|
166 | ADCSRA = 0x01;
|
167 | }
|
168 |
|
169 | unsigned char taster = 0;
|
170 | //----------------------------------------------------------------------------//
|
171 | // Tasterabfrage
|
172 | //----------------------------------------------------------------------------//
|
173 | void funkt_tast(void)
|
174 | {
|
175 | static char rw = 0;
|
176 | if(taster == 0 && !(PINB & (1<<pin_taster))) //Taster wird gedrueckt (steigende Flanke)
|
177 | {
|
178 | taster = 1;
|
179 | rw = 1;
|
180 | }
|
181 | else if (taster == 1 && !(PINB & (1<<pin_taster))) //Taster wird gehalten
|
182 | {
|
183 | taster = 2;
|
184 | rw = 0;
|
185 | }
|
186 | else if (taster == 2 && (PINB & (1<<pin_taster))) //Taster wird losgelassen (fallende Flanke)
|
187 | {
|
188 | taster = 3;
|
189 | rw = 0;
|
190 | }
|
191 | else if (taster == 3 && (PINB & (1<<pin_taster))) //Taster losgelassen
|
192 | {
|
193 | taster = 0;
|
194 | rw = 0;
|
195 | }
|
196 |
|
197 |
|
198 |
|
199 | }
|
200 | unsigned char i = 0;
|
201 |
|
202 | unsigned int result;
|
203 | unsigned int poti_1;
|
204 | unsigned int poti_2;
|
205 | unsigned int poti_3;
|
206 | unsigned int batt;
|
207 |
|
208 |
|
209 | //----------------------------------------------------------------------------//
|
210 | // AD-Wandlung
|
211 | //----------------------------------------------------------------------------//
|
212 | void ad(void)
|
213 | {
|
214 | // Dummy-Readout
|
215 | ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1); // ADC aktivieren, Frequenzvorteiler: setzen auf 64 (8 MHz / 64 = 125 kHz) und ADC aktivieren
|
216 | ADMUX |= (1<<REFS0) | (1<<REFS1); // interne Referenzspannung nutzen
|
217 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
|
218 | while(!(ADCSRA & (1<<ADIF))); // auf Abschluss der Konvertierung warten (ADIF-bit)
|
219 | result = ADC; // ADC muss einmal gelesen werden,
|
220 | // sonst wird Ergebnis der nächsten Wandlung
|
221 | // nicht übernommen.
|
222 |
|
223 | //ADC-Messung mit arithmetischen Mittel aus 4 Messungen
|
224 | result = 0;
|
225 | for (i=0;i<4;i++)
|
226 | {
|
227 | ADCSRA |= (1<<ADSC); // Messung ausfuehren
|
228 | while ( ADCSRA & (1<<ADSC) ); // Konvertierung abwarten
|
229 | result += ADC; // aufaddieren zur Mittelwertbildung (ADC auslesen der zwei Bits
|
230 | }
|
231 | ADCSRA &= ~(1<<ADEN); // ADC ausschalten
|
232 |
|
233 | result /= 4; //
|
234 |
|
235 |
|
236 | }
|
237 |
|
238 | //----------------------------------------------------------------------------//
|
239 | // AD-Wandlung für Poti 1-3 und Batterie
|
240 | //----------------------------------------------------------------------------//
|
241 | void adc(void)
|
242 | {
|
243 | //Poti 1
|
244 | ADMUX = 0x00;// Kanal waehlen (ADC0)
|
245 | ad();
|
246 | result /= 4;//auf 8 Bit reduzieren
|
247 | poti_1 = result;
|
248 | OCR0A = poti_1;
|
249 | // Poti 2
|
250 | ADMUX = 0x01;// Kanal waehlen (ADC1)
|
251 | ad();
|
252 | result /= 4;//auf 8 Bit reduzieren
|
253 | poti_2 = result;
|
254 | OCR0B = poti_2;
|
255 | //Poti 3
|
256 | ADMUX = 0x07;// Kanal waehlen (ADC7)
|
257 | ad();
|
258 | result /= 4;//auf 8 Bit reduzieren
|
259 | poti_3 = result;
|
260 | OCR0A = poti_3;
|
261 |
|
262 | //Batteriespannung
|
263 | ADMUX = 0x02;// Kanal waehlen (ADC2)
|
264 | ad();
|
265 | batt = result;
|
266 |
|
267 |
|
268 |
|
269 | }
|
270 |
|
271 |
|
272 | //----------------------------------------------------------------------------//
|
273 | // Akkuwarnung
|
274 | //----------------------------------------------------------------------------//
|
275 |
|
276 | void warn(void)
|
277 | {
|
278 | static unsigned int delay;
|
279 | if (delay>WarnInt)
|
280 | {
|
281 | delay=0;
|
282 | adc();
|
283 | if (poti_3>40)//if (batt < 500) Momentan noch auf einem Poti gelegt
|
284 | {PORTC ^= (1<<pinnchen);}
|
285 | else {PORTC |= (1<<pinnchen);}
|
286 | }
|
287 | else delay++;
|
288 | }
|
289 |
|
290 | //----------------------------------------------------------------------------//
|
291 | // RundUmLicht
|
292 | //----------------------------------------------------------------------------//
|
293 | unsigned char blink_state = 0;
|
294 | unsigned char countLED = 0;
|
295 | void rul(void)
|
296 | {
|
297 | switch (blink_state)
|
298 | {
|
299 |
|
300 | case 0: // R_LED1 ein
|
301 | {
|
302 | PORTD &= ~((1<<R_LED2) | (1<<R_LED3) | (1<<R_LED4));
|
303 | PORTD |= (1<<R_LED1);
|
304 | break;
|
305 | }
|
306 | case 1: // R_LED2 ein
|
307 | {
|
308 | PORTD &= ~((1<<R_LED1) | (1<<R_LED3) | (1<<R_LED4));
|
309 | PORTD |= (1<<R_LED2);
|
310 | break;
|
311 | }
|
312 | case 2: // R_LED3 ein
|
313 | {
|
314 | PORTD &= ~((1<<R_LED1) | (1<<R_LED2) | (1<<R_LED4));
|
315 | PORTD |= (1<<R_LED3);
|
316 | break;
|
317 | }
|
318 | case 3: // R_LED4 ein
|
319 | {
|
320 | PORTD &= ~((1<<R_LED1) | (1<<R_LED2) | (1<<R_LED3));
|
321 | PORTD |= (1<<R_LED4);
|
322 | break;
|
323 | }
|
324 | }
|
325 | countLED++;
|
326 | if (countLED>RulInt) //Hier stellt man die Drehzahl der Rundumleuchte ein
|
327 | {
|
328 | countLED=0;
|
329 | blink_state++;
|
330 | }
|
331 | if (blink_state>3) {blink_state=0; // Lauflicht neustarten
|
332 | }
|
333 | }
|
334 |
|
335 |
|
336 | ////////////////////////////////////////////////////////////////////////////////
|
337 | // Hauptprogramm
|
338 | ////////////////////////////////////////////////////////////////////////////////
|
339 | void main(void)
|
340 | {
|
341 | //stop errant interrupts until set up
|
342 | CLI(); //disable all interrupts
|
343 | port_init();
|
344 | timer1_init();
|
345 | timer2_init();
|
346 | adc_init();
|
347 |
|
348 | MCUCR = 0x00;
|
349 | EICRA = 0x00; //extended ext ints
|
350 | EIMSK = 0x00;
|
351 |
|
352 | TIMSK0 = 0x00; //timer 0 interrupt sources
|
353 | TIMSK1 = 0x01; //timer 1 interrupt sources
|
354 | TIMSK2 = 0x01; //timer 2 interrupt sources
|
355 |
|
356 | PCMSK0 = 0x00; //pin change mask 0
|
357 | PCMSK1 = 0x00; //pin change mask 1
|
358 | PCMSK2 = 0x00; //pin change mask 2
|
359 | PCICR = 0x00; //pin change enable
|
360 | PRR = 0x00; //power controller
|
361 | SEI(); //re-enable interrupts
|
362 | //all peripherals are now initialized
|
363 |
|
364 | while(1)
|
365 | {
|
366 | if(f_1sec)
|
367 | {
|
368 | f_1sec=0;
|
369 | rul(); // RundUmLicht
|
370 | }
|
371 | if(f_100ms)
|
372 | {
|
373 | f_100ms=0;
|
374 | adc(); // AD-Wandlung aller 4 Kanäle (3x Poti, 1x Batteriespannung)
|
375 | warn(); // Unterspannungswarnung
|
376 | funkt_tast(); // Taster
|
377 | if (taster == 1) PORTD |= (1<<ziel_led); // LED an
|
378 | if (taster == 0) PORTD &= ~(1<<ziel_led);// LED aus
|
379 | }
|
380 | }return;
|
381 | }
|