00001 /****************************************************************************/ 00048 /***************************************************************************** 00049 * * 00050 * This program is free software; you can redistribute it and/or modify * 00051 * it under the terms of the GNU General Public License as published by * 00052 * the Free Software Foundation; either version 2 of the License, or * 00053 * any later version. * 00054 * * 00055 *****************************************************************************/ 00056 #include "asuro.h" 00057 #include "myasuro.h" 00058 #ifdef RC5_AVAILABLE 00059 #include "rc5.h" 00060 #endif 00061 00062 00063 /****************************************************************************/ 00117 void Init ( 00118 void) 00119 { 00120 /* 00121 Timer2, zum Betrieb mit der seriellen Schnittstelle, fuer die 00122 IR-Kommunikation auf 36 kHz eingestellt. 00123 */ 00124 TCCR2 = (1 << WGM20) | (1 << WGM21) | (1 << COM20) | (1 << COM21) | (1 << CS20); 00125 OCR2 = 0x91; // duty cycle fuer 36kHz 00126 TIMSK |= (1 << TOIE2); // 36kHz counter 00127 00128 /* 00129 Die serielle Schnittstelle wurde waerend der Boot-Phase schon 00130 programmiert und gestartet. Hier werden die Parameter auf 2400 1N8 gesetzt. 00131 */ 00132 UCSRA = 0x00; 00133 UCSRB = 0x00; 00134 UCSRC = 0x86; // 1 Stop Bit | No Parity | 8 Data Bit 00135 UBRRL = 0xCF; // 2400bps @ 8.00MHz 00136 00137 /* 00138 Datenrichtung der I/O-Ports festlegen. Dies ist durch die Beschaltung der 00139 Asuro-Hardware nicht aenderbar. 00140 Port B: Seriell Senden; Richtungsvorgabe Motor links; Takt fuer die 00141 Geschwindigkeit beider Motoren; Grueneanteil-Status-LED 00142 Port D: Richtungsvorgabe Motor rechts; Vordere LED; 00143 Odometrie-LED (Radsensor); Rotanteil-Status-LED 00144 */ 00145 DDRB = IRTX | RIGHT_DIR | PWM | GREEN_LED; 00146 DDRD = LEFT_DIR | FRONT_LED | ODOMETRIE_LED | RED_LED; 00147 00148 /* 00149 PWM-Kanaele OC1A und OC1B auf 8-Bit einstellen. 00150 Sie werden fuer die Geschwindigkeitsvorgaben der Motoren benutzt. 00151 */ 00152 TCCR1A = (1 << WGM10) | (1 << COM1A1) | (1 << COM1B1); 00153 TCCR1B = (1 << CS11); // tmr1-Timer mit MCU-Takt/8 betreiben. 00154 00155 /* 00156 Einstellungen des A/D-Wandlers auf MCU-Takt/64 00157 */ 00158 ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); 00159 00160 /* 00161 Sonstige Vorbereitungen. 00162 - Alle LED's ausschalten 00163 - Motoren stoppen und schon mal auf Vorwaerts einstellen. 00164 - Globale Variable autoencoder ausschalten. 00165 */ 00166 ODOMETRIE_LED_OFF; 00167 FrontLED (OFF); 00168 BackLED (ON, ON); 00169 BackLED (OFF, OFF); 00170 StatusLED (GREEN); 00171 00172 MotorDir (FWD, FWD); 00173 MotorSpeed (0, 0); 00174 00175 autoencode = FALSE; 00176 00177 /* 00178 Funktion zum ALLGEMEINEN ZULASSEN von Interrupts. 00179 */ 00180 sei (); 00181 } 00182 00183 00184 00185 /****************************************************************************/ 00186 /* 00187 \brief 00188 Interrupt-Funktion fuer Timer-2-Ueberlauf. 00189 00190 \param 00191 keine 00192 00193 \return 00194 nichts 00195 00196 \see 00197 count36kHz, timebase 00198 00199 \par 00200 Der zum Timer gehoerende Zaehler TCNT2 wird so justiert, dass damit die\n 00201 gewuenschten 36 kHz erreicht werden.\n 00202 Fuer die Zeitfunktionen werden die globalen Variablen count36kHz und\n 00203 timebase hochgezaehlt. 00204 00205 \par Beispiel: 00206 (Nicht vorhanden) 00207 *****************************************************************************/ 00208 SIGNAL (SIG_OVERFLOW2) 00209 { 00210 TCNT2 += 0x25; 00211 count36kHz ++; 00212 if (!count36kHz) 00213 timebase ++; 00214 #ifdef RC5_AVAILABLE 00215 if (enableRC5 && !(count36kHz % 8)) 00216 IsrRC5(); // wird alle 222.2us aufgerufen 00217 #endif 00218 } 00219 00220 00221 00222 /****************************************************************************/ 00223 /* 00224 \brief 00225 Interrupt-Funktion fuer den externen Interrupt 1. 00226 00227 \param 00228 keine 00229 00230 \return 00231 nichts 00232 00233 \see switched 00234 00235 \par 00236 Hier wird 'nur' in der globalen Variablen switched vermerkt, dass ein\n 00237 Switch (Taster) gedrueckt wurde und dieser Interrupt soeben aufgetreten ist.\n 00238 Damit dieser Interrupt aber nicht permanent aufgerufen wird, solange der\n 00239 Taster gedrueckt bleibt, wird die Funktion, dass ein Interrupt erzeugt wird,\n 00240 ueber StopSwitch() abgeschaltet.\n 00241 Nach einer Bearbeitung im eigenen Hauptprogramm, muss also die Funktion\n 00242 StartSwitch() wieder Aufgerufen werden, um einen Tastendruck wieder ueber\n 00243 einen Interrupt zu erkennen. 00244 00245 \par Beispiel: 00246 (Nicht vorhanden) 00247 *****************************************************************************/ 00248 SIGNAL (SIG_INTERRUPT1) 00249 { 00250 switched = 1; 00251 GICR &= ~(1 << INT1); // Externen Interrupt 1 sperren 00252 // StopSwitch (); 00253 } 00254 00255 00256 00257 /****************************************************************************/ 00258 /* 00259 \brief 00260 Interrupt-Funktion fuer den AD-Wandler. Kann ueber autoencode gesteuert\n 00261 die Odometrie-Zaehler in encoder hochzaehlen. 00262 00263 \param 00264 keine 00265 00266 \return 00267 nichts 00268 00269 \see 00270 Die globale Variable autoencode wird hier ausgewertet. Ist sie nicht FALSE,\n 00271 dann wird der AD-Wandler-Wert zum Zaehlen der Odometriewerte in der globalen\n 00272 Variablen encoder benutzt.\n 00273 Es wird auch der AD-Wandler-Kanal auf die 'andere' Seite der Odometrie\n 00274 umgeschaltete und der AD-Wandler neu gestartet.\n 00275 Somit wird erreicht, dass zumindest die Odometriemessung automatisch erfolgt. 00276 00277 \par Beispiel: 00278 (Nicht vorhanden) 00279 *****************************************************************************/ 00280 SIGNAL (SIG_ADC) 00281 { 00282 static unsigned char tmp [2], flag [2], toggle = FALSE; 00283 unsigned char dval, lval; 00284 00285 if (autoencode) 00286 { 00287 tmp [toggle] = ADCH; 00288 if (toggle) 00289 { 00290 ADMUX = (1 << ADLAR) | (1 << REFS0) | WHEEL_RIGHT; 00291 dval = MY_ODO_DARK_VALUE_R; 00292 lval = MY_ODO_LIGHT_VALUE_R; 00293 } 00294 else 00295 { 00296 ADMUX = (1 << ADLAR) | (1 << REFS0) | WHEEL_LEFT; 00297 dval = MY_ODO_DARK_VALUE_L; 00298 lval = MY_ODO_LIGHT_VALUE_L; 00299 } 00300 00301 if ((tmp [toggle] < dval) && (flag[toggle] == TRUE)) 00302 { 00303 encoder [toggle] ++; 00304 flag [toggle] = FALSE; 00305 } 00306 if ((tmp [toggle] > lval) && (flag [toggle] == FALSE)) 00307 { 00308 encoder [toggle] ++; 00309 flag [toggle] = TRUE; 00310 } 00311 toggle ^= 1; 00312 } 00313 } 00314