ASURO Library  2.80
ultrasonic.c
gehe zur Dokumentation dieser Datei
1 /****************************************************************************/
18 /*****************************************************************************
19 * *
20 * This program is free software; you can redistribute it and/or modify *
21 * it under the terms of the GNU General Public License as published by *
22 * the Free Software Foundation; either version 2 of the License, or *
23 * any later version. *
24 * *
25 *****************************************************************************/
26 
27 #include "asuro.h"
28 #include "ultrasonic.h"
29 
34 void InitUltrasonics(void)
35 {
36  // Change Oscillator-frequency of Timer 2
37  // to 40kHz, no toggling of IO-pin:
38  cli();
39 #if defined(__AVR_ATmega168__)
40  // fast PWM, set OC2A on compare match, clear OC2A at bottom, clk/1
41  TCCR2A = _BV(WGM21);
42  TCCR2B = _BV(CS20);
43  // interrupt on timer overflow
44  TIMSK2 &= ~_BV(TOIE2);
45  TIMSK2 |= _BV(OCIE2A);
46 #else
47  TCCR2 = _BV(WGM21) | _BV(CS20);
48  TIMSK &= ~_BV(TOIE2);
49  TIMSK |= _BV(OCIE2); // OCIE2: Timer/Counter2 Output Compare Match Interrupt Enable
50 #endif
51  // 40kHz carrier/timer
52  OCR2 = 100;
53 
54  ADCSRA = 0; // deactivate ADC
55  ACSR |= _BV(ACIS1); // Comparator Interrupt on Falling Output Edge
56 
57  ADMUX = 0x03; // connect ADC3-input with comparator
58 #if defined(__AVR_ATmega168__)
59  ADCSRB |= _BV(ACME); // connect ADC multiplexer to comparator
60 #else
61  SFIOR |= _BV(ACME); // connect ADC multiplexer to comparator
62 #endif
63  DDRD &= ~_BV(6); // use Port D Pin 6 as input (AIN0)
64  sei();
65 }
66 
71 void RestoreAsuro(void)
72 {
73  cli();
74 #if defined(__AVR_ATmega168__)
75  // fast PWM, set OC2A on compare match, clear OC2A at bottom, clk/1
76  TCCR2A = _BV(WGM20) | _BV(WGM21) | _BV(COM2A0) | _BV(COM2A1);
77  TCCR2B = _BV(CS20);
78  TIMSK2 &= ~_BV(OCIE2A);
79  // interrupt on timer overflow
80  TIMSK2 |= _BV(TOIE2);
81 #else
82  TCCR2 = _BV(WGM20) | _BV(WGM21) | _BV(COM20) | _BV(COM21) | _BV(CS20);
83  TIMSK &= ~_BV(OCIE2); // OCIE2: Timer/Counter2 Output Compare Match Interrupt Disable
84  // interrupt on timer overflow
85  TIMSK |= _BV(TOIE2);
86 #endif
87  // 36kHz carrier/timer
88  OCR2 = 0x91; // duty cycle for 36kHz
89 
90  ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1); // clk/64
91  ACSR &= ~_BV(ACIS1);
92 
93  if(autoencode) {
94  EncoderInit();
95  }
96  sei();
97  Sleep(1);
98 }
99 
103 int Chirp(void)
104 {
105  unsigned int sleeptime = 0, dist = 0;
106 
107  InitUltrasonics();
108 
109  // chirpen:
110  count36kHz = 0;
111 
112  while(count36kHz != 20) {
113  OCR2 = 100 + 20 / 2 - count36kHz;
114  }
115 
116 #if defined(__AVR_ATmega168__)
117  TCCR2A = _BV(WGM21);
118  TCCR2B = _BV(CS20);
119 #else
120  TCCR2 = _BV(WGM21) | _BV(CS20);
121 #endif
122  OCR2 = 100;
123 
124  // analyse echoes:
125  while(TRUE) {
126  Sleep(1);
127  sleeptime++;
128 
129  if((ACSR & _BV(ACI))) {
130  dist = (unsigned int) ((long) ((344L * ((sleeptime * 1000L) / 72L) / 10000L) / 2L));
131  ACSR |= _BV(ACI);
132  break;
133  }
134 
135  ACSR |= _BV(ACI);
136 
137  if(sleeptime > 3500) {
138  return -1;
139  }
140  }
141 
142  RestoreAsuro();
143  return dist;
144 }
145