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