1 | /*****************************************************
|
2 | This program was produced by the
|
3 | CodeWizardAVR V2.05.2 Evaluation
|
4 | Automatic Program Generator
|
5 | © Copyright 1998-2011 Pavel Haiduc, HP InfoTech s.r.l.
|
6 | http://www.hpinfotech.com
|
7 |
|
8 | Project : RC-Panzer
|
9 | Version : 1
|
10 | Date : 07.07.2011
|
11 | Author : Sascha Albrecht
|
12 | Company : Modellfreunde Thüringen
|
13 | Comments:
|
14 |
|
15 |
|
16 | Chip type : ATmega168
|
17 | Program type : Application
|
18 | AVR Core Clock frequency: 16,001000 MHz
|
19 | Memory model : Small
|
20 | External RAM size : 0
|
21 | Data Stack size : 256
|
22 | *****************************************************/
|
23 |
|
24 | #include <mega168.h>
|
25 |
|
26 | //Achtung: PWM-Signal ist invertiert! - damit liegt Fall vor Rise
|
27 | unsigned int pwm1rise; //steigende Flanke
|
28 | unsigned int pwm1fall; //fallende Flanke
|
29 | unsigned int pwm1time; //berechneter Zeitwert des PWM-(High)-Signals
|
30 | unsigned int pwm1last = 1; //merkt sich den letzten Zustand des Pins (um zu prüfen, ob er geändert wurde)
|
31 | unsigned int pwm1flag = 0;
|
32 | unsigned int pwm2rise;
|
33 | unsigned int pwm2fall;
|
34 | unsigned int pwm2time;
|
35 | unsigned int pwm2last = 1;
|
36 | unsigned int pwm2flag = 0;
|
37 | unsigned int pwm3rise;
|
38 | unsigned int pwm3fall;
|
39 | unsigned int pwm3time;
|
40 | unsigned int pwm3last = 1;
|
41 | unsigned int pwm3flag = 0;
|
42 | unsigned int pwm4rise;
|
43 | unsigned int pwm4fall;
|
44 | unsigned int pwm4time;
|
45 | unsigned int pwm4last = 1;
|
46 | unsigned int pwm4flag = 0;
|
47 |
|
48 |
|
49 |
|
50 | // Pin change 0-7 interrupt service routine
|
51 | interrupt [PC_INT0] void pin_change_isr0(void)
|
52 | {
|
53 | int time_h, time_l;
|
54 | time_l = TCNT1L;
|
55 | time_h = TCNT1H;
|
56 |
|
57 | if(PIND.2 != pwm1last)
|
58 | {
|
59 | if(pwm1last == 1)
|
60 | {
|
61 | pwm1fall = ((int)time_h << 8) + time_l;
|
62 | pwm1last = 0;
|
63 | }
|
64 | else
|
65 | {
|
66 | pwm1rise = ((int)time_h << 8) + time_l;
|
67 | pwm1last = 1;
|
68 | pwm1flag = 1;
|
69 | }
|
70 | }
|
71 |
|
72 | if(PIND.4 != pwm2last)
|
73 | {
|
74 | if(pwm2last == 1)
|
75 | {
|
76 | pwm2fall = ((int)time_h << 8) + time_l; //Achtung: Signal ist invertiert -> Fall kommt vor Rise!
|
77 | pwm2last = 0;
|
78 | }
|
79 | else
|
80 | {
|
81 | pwm2rise = ((int)time_h << 8) + time_l;
|
82 | pwm2last = 1;
|
83 | pwm2flag = 1;
|
84 | }
|
85 | }
|
86 | }
|
87 |
|
88 | // Pin change 8-14 interrupt service routine
|
89 | interrupt [PC_INT1] void pin_change_isr1(void)
|
90 | {
|
91 | int time_h, time_l;
|
92 | time_l = TCNT1L;
|
93 | time_h = TCNT1H;
|
94 |
|
95 | if(PIND.7 != pwm3last)
|
96 | {
|
97 | if(pwm3last == 1)
|
98 | {
|
99 | pwm3fall = ((int)time_h << 8) + time_l;
|
100 | pwm3last = 0;
|
101 | }
|
102 | else
|
103 | {
|
104 | pwm3rise = ((int)time_h << 8) + time_l;
|
105 | pwm3last = 1;
|
106 | pwm3flag = 1;
|
107 | }
|
108 | }
|
109 |
|
110 | if(PINB.0 != pwm4last)
|
111 | {
|
112 | if(pwm4last == 1)
|
113 | {
|
114 | pwm4fall = ((int)time_h << 8) + time_l; //Achtung: Signal ist invertiert -> Fall kommt vor Rise!
|
115 | pwm4last = 0;
|
116 | }
|
117 | else
|
118 | {
|
119 | pwm4rise = ((int)time_h << 8) + time_l;
|
120 | pwm4last = 1;
|
121 | pwm4flag = 1;
|
122 | }
|
123 | }
|
124 |
|
125 | //Dient nur zur Überprüfung, ob die ISR ausgeführt wird, oder nicht
|
126 | //if(PINC.5)
|
127 | // PORTC.5 = 0;
|
128 | //else
|
129 | PORTC.5 = 1; //Der Ausgang sollte jett HI sein, sobald die ISR einmal ausgeführt wurde
|
130 | }
|
131 |
|
132 | // Standard Input/Output functions
|
133 | #include <stdio.h>
|
134 |
|
135 | // Declare your global variables here
|
136 |
|
137 | void main(void)
|
138 | {
|
139 | // Declare your local variables here
|
140 |
|
141 | // Crystal Oscillator division factor: 1
|
142 | #pragma optsize-
|
143 | CLKPR=0x80;
|
144 | CLKPR=0x00;
|
145 | #ifdef _OPTIMIZE_SIZE_
|
146 | #pragma optsize+
|
147 | #endif
|
148 |
|
149 | // Input/Output Ports initialization
|
150 | // Port B initialization
|
151 | // Func7=Out Func6=In Func5=In Func4=Out Func3=Out Func2=Out Func1=Out Func0=In
|
152 | // State7=0 State6=T State5=T State4=0 State3=0 State2=0 State1=0 State0=P
|
153 | PORTB=0x01;
|
154 | DDRB=0x9E;
|
155 |
|
156 | // Port C initialization
|
157 | // Func6=In Func5=Out Func4=In Func3=In Func2=Out Func1=Out Func0=Out
|
158 | // State6=T State5=0 State4=T State3=T State2=0 State1=0 State0=0
|
159 | PORTC=0x00;
|
160 | DDRC=0x27;
|
161 |
|
162 | // Port D initialization
|
163 | // Func7=In Func6=Out Func5=Out Func4=In Func3=Out Func2=In Func1=Out Func0=In
|
164 | // State7=P State6=0 State5=0 State4=P State3=0 State2=P State1=0 State0=T
|
165 | PORTD=0x94;
|
166 | DDRD=0x6A;
|
167 |
|
168 | // Timer/Counter 0 initialization
|
169 | // Clock source: System Clock
|
170 | // Clock value: 16001,000 kHz
|
171 | // Mode: Fast PWM top=0xFF
|
172 | // OC0A output: Non-Inverted PWM
|
173 | // OC0B output: Non-Inverted PWM
|
174 | TCCR0A=0xA3;
|
175 | TCCR0B=0x01;
|
176 | TCNT0=0x00;
|
177 | OCR0A=0x30;
|
178 | OCR0B=0xA0;
|
179 |
|
180 | // Timer/Counter 1 initialization
|
181 | // Clock source: System Clock
|
182 | // Clock value: 2000,125 kHz
|
183 | // Mode: Fast PWM top=ICR1
|
184 | // OC1A output: Non-Inv.
|
185 | // OC1B output: Non-Inv.
|
186 | // Noise Canceler: Off
|
187 | // Input Capture on Falling Edge
|
188 | // Timer1 Overflow Interrupt: Off
|
189 | // Input Capture Interrupt: Off
|
190 | // Compare A Match Interrupt: Off
|
191 | // Compare B Match Interrupt: Off
|
192 | TCCR1A=0xA2;
|
193 | TCCR1B=0x1A;
|
194 | TCNT1H=0x00;
|
195 | TCNT1L=0x00;
|
196 | //ICR1H=0x9C; //20ms Periode
|
197 | //ICR1L=0x40;
|
198 | ICR1H=0xAB; //22ms Periode
|
199 | ICR1L=0xE0;
|
200 | OCR1AH=0x0B;
|
201 | OCR1AL=0xB8;
|
202 | OCR1BH=0x0F;
|
203 | OCR1BL=0xA0;
|
204 |
|
205 | // Timer/Counter 2 initialization
|
206 | // Clock source: System Clock
|
207 | // Clock value: 16001,000 kHz
|
208 | // Mode: Fast PWM top=0xFF
|
209 | // OC2A output: Non-Inverted PWM
|
210 | // OC2B output: Non-Inverted PWM
|
211 | ASSR=0x00;
|
212 | TCCR2A=0xA3;
|
213 | TCCR2B=0x01;
|
214 | TCNT2=0x00;
|
215 | OCR2A=0x30;
|
216 | OCR2B=0xA0;
|
217 |
|
218 | // External Interrupt(s) initialization
|
219 | // INT0: Off
|
220 | // INT1: Off
|
221 | // Interrupt on any change on pins PCINT0-7: On
|
222 | // Interrupt on any change on pins PCINT8-14: On
|
223 | // Interrupt on any change on pins PCINT16-23: Off
|
224 | EICRA=0x00;
|
225 | EIMSK=0x00;
|
226 | PCICR=0x03;
|
227 | PCMSK0=0x28;
|
228 | PCMSK1=0x60;
|
229 | PCIFR=0x03;
|
230 |
|
231 | // Timer/Counter 0 Interrupt(s) initialization
|
232 | TIMSK0=0x00;
|
233 |
|
234 | // Timer/Counter 1 Interrupt(s) initialization
|
235 | TIMSK1=0x00;
|
236 |
|
237 | // Timer/Counter 2 Interrupt(s) initialization
|
238 | TIMSK2=0x00;
|
239 |
|
240 | // USART initialization
|
241 | // Communication Parameters: 8 Data, 1 Stop, No Parity
|
242 | // USART Receiver: On
|
243 | // USART Transmitter: On
|
244 | // USART0 Mode: Asynchronous
|
245 | // USART Baud Rate: 19200
|
246 | UCSR0A=0x00;
|
247 | UCSR0B=0x18;
|
248 | UCSR0C=0x06;
|
249 | UBRR0H=0x00;
|
250 | UBRR0L=0x33;
|
251 |
|
252 | // Analog Comparator initialization
|
253 | // Analog Comparator: Off
|
254 | // Analog Comparator Input Capture by Timer/Counter 1: Off
|
255 | ACSR=0x80;
|
256 | ADCSRB=0x00;
|
257 | DIDR1=0x00;
|
258 |
|
259 | // ADC initialization
|
260 | // ADC disabled
|
261 | ADCSRA=0x00;
|
262 |
|
263 | // SPI initialization
|
264 | // SPI disabled
|
265 | SPCR=0x00;
|
266 |
|
267 | // TWI initialization
|
268 | // TWI disabled
|
269 | TWCR=0x00;
|
270 |
|
271 | // Global enable interrupts
|
272 | #asm("sei")
|
273 |
|
274 | while (1)
|
275 | {
|
276 | if(pwm1flag == 1)
|
277 | {
|
278 | //if(pwm1fall > pwm1rise) //für den Fall, dass zwischen pwmXfall und pwmXrise ein TimerOverflow stattgefunden hat
|
279 | // pwm1time = ((int)(((int)ICR1H << 8) + ICR1L)) - pwm1fall + pwm1rise;
|
280 | //else
|
281 | pwm1time = pwm1rise - pwm1fall; //Zeit berechnen
|
282 |
|
283 | if(pwm1time >= 1800 && pwm1time <= 4200) //nur Werte zwischen 900us und 2100us sind gültig!
|
284 | {
|
285 | #asm("cli")
|
286 | //OCR1AH = pwm1time >> 8; //setze den PWM-Ausgang mit der eingelesenen Zeit
|
287 | //OCR1AL = pwm1time & 0xFF; //-"- --> nur zum Test!
|
288 | #asm("sei")
|
289 | }
|
290 | pwm1flag = 0;
|
291 | }
|
292 |
|
293 | if(pwm2flag == 1)
|
294 | {
|
295 | pwm2time = pwm2rise - pwm2fall; //Zeit berechnen
|
296 | if(pwm2time >= 1800 && pwm2time <= 4200) //nur Werte zwischen 900us und 2100us sind gültig!
|
297 | {
|
298 | #asm("cli")
|
299 | //OCR1BH = pwm2time >> 8; //setze den PWM-Ausgang mit der eingelesenen Zeit
|
300 | //OCR1BL = pwm2time & 0xFF; //-"- --> nur zum Test!
|
301 | #asm("sei")
|
302 | }
|
303 | pwm2flag = 0;
|
304 | }
|
305 |
|
306 | if(pwm3flag == 1)
|
307 | {
|
308 | pwm3time = pwm3rise - pwm3fall; //Zeit berechnen
|
309 | if(pwm3time >= 1800 && pwm3time <= 4200) //nur Werte zwischen 900us und 2100us sind gültig!
|
310 | {
|
311 | #asm("cli")
|
312 | OCR1AH = pwm3time >> 8; //setze den PWM-Ausgang mit der eingelesenen Zeit
|
313 | OCR1AL = pwm3time & 0xFF; //-"- --> nur zum Test!
|
314 | #asm("sei")
|
315 | }
|
316 | pwm3flag = 0;
|
317 | }
|
318 |
|
319 | if(pwm4flag == 1)
|
320 | {
|
321 | pwm4time = pwm4rise - pwm4fall; //Zeit berechnen
|
322 | if(pwm4time >= 1800 && pwm4time <= 4200) //nur Werte zwischen 900us und 2100us sind gültig!
|
323 | {
|
324 | #asm("cli")
|
325 | OCR1BH = pwm4time >> 8; //setze den PWM-Ausgang mit der eingelesenen Zeit
|
326 | OCR1BL = pwm4time & 0xFF; //-"- --> nur zum Test!
|
327 | #asm("sei")
|
328 | }
|
329 | pwm4flag = 0;
|
330 | }
|
331 | }
|
332 | }
|