diff options
Diffstat (limited to 'source/ct-Bot/mcu/motor-low.c')
-rw-r--r-- | source/ct-Bot/mcu/motor-low.c | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/source/ct-Bot/mcu/motor-low.c b/source/ct-Bot/mcu/motor-low.c new file mode 100644 index 0000000..98e5f9f --- /dev/null +++ b/source/ct-Bot/mcu/motor-low.c @@ -0,0 +1,242 @@ +/* + * c't-Bot + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your + * option) any later version. + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307, USA. + * + */ + +/*! @file motor-low.c + * @brief Low-Level Routinen fuer die Motorsteuerung des c't-Bots + * @author Benjamin Benz (bbe@heise.de) + * @date 01.12.05 +*/ +#ifdef MCU + +#include "ct-Bot.h" + +#include <avr/io.h> +#include <avr/interrupt.h> +#ifndef NEW_AVR_LIB + #include <avr/signal.h> +#endif +#include <stdlib.h> + +#include "global.h" +#include "motor.h" +#include "timer.h" +#include "sensor.h" +#include "display.h" +#include "motor-low.h" + +//Drehrichtung der Motoren +#define BOT_DIR_L_PIN (1<<6) // PC7 +#define BOT_DIR_L_PORT PORTC +#define BOT_DIR_L_DDR DDRC + +#define BOT_DIR_R_PIN (1<<7) // PC6 +#define BOT_DIR_R_PORT PORTC +#define BOT_DIR_R_DDR DDRC + +#define PWM_L OCR1A +#define PWM_R OCR1B + +#define PWM_CLK_0 (_BV(CS02) | _BV(CS00)) /*!< Prescaler fuer PWM 0 = 1024*/ +//#define PWM_CLK_2 (_BV(CS22) | _BV(CS21) |_BV(CS20)) /*!< Prescaler fuer PWM 2 =1024 */ + +int16 motor_left; /*!< zuletzt gestellter Wert linker Motor */ +int16 motor_right; /*!< zuletzt gestellter Wert rechter Motor */ + + +void pwm_0_init(void); +void pwm_1_init(void); +// void pwm_2_init(void); // Kollidiert mit Timer2 fuer IR-Fernbedienung + +/*! + * Initialisiert alles fuer die Motosteuerung + */ +void motor_low_init(){ + BOT_DIR_L_DDR|=BOT_DIR_L_PIN; + BOT_DIR_R_DDR|=BOT_DIR_R_PIN; + + pwm_0_init(); + pwm_1_init(); +// pwm_2_init(); // Kollidiert mit Timer2 fuer IR-Fernbedienung + bot_motor(0,0); +} + +/*! + * unmittelbarere Zugriff auf die beiden Motoren + * normalerweise NICHT verwenden!!!!! + * @param left Speed links + * @param right Speed rechts +*/ +void bot_motor(int16 left, int16 right){ + // Vorzeichenbehaftete PWM-Werte sichern + motor_left=left; + motor_right=right; + + PWM_L = 255-abs(left); + PWM_R = 255-abs(right); + + if (left > 0 ){ + BOT_DIR_L_PORT |= BOT_DIR_L_PIN; + direction.left= DIRECTION_FORWARD; + } else + BOT_DIR_L_PORT &= ~BOT_DIR_L_PIN; + + if (left < 0 ) + direction.left= DIRECTION_BACKWARD; + + + if (right <= 0 ) // Einer der Motoren ist invertiert, da er ja in die andere Richtung schaut + BOT_DIR_R_PORT |= BOT_DIR_R_PIN; + else { + BOT_DIR_R_PORT &= ~BOT_DIR_R_PIN; + direction.right= DIRECTION_FORWARD; + } + if (right < 0 ) + direction.right= DIRECTION_BACKWARD; +} + +/*! + * Stellt die Servos + * Sinnvolle Werte liegen zwischen 8 und 16 + */ +void servo_low(uint8 servo, uint8 pos){ + if (servo== SERVO1) { + if (pos == SERVO_OFF) { + #ifdef __AVR_ATmega644__ + TCCR0B &= ~PWM_CLK_0 ; // PWM aus + #else + TCCR0 &= ~PWM_CLK_0 ; // PWM aus + #endif + } else { + #ifdef __AVR_ATmega644__ + TCCR0B |= PWM_CLK_0; // PWM an + OCR0A=pos; + #else + TCCR0 |= PWM_CLK_0; // PWM an + OCR0=pos; + #endif + } + + } + +// if (servo== SERVO2) { +// if (pos == 0) { +// TCCR2 &= ~ (_BV(CS22) | _BV(CS21) | _BV(CS20)); // PWM an +// } else { +// TCCR2 |= PWM_CLK_2; // PWM an +// OCR2=pos; +// } +// } + +} + +/*! + * Interrupt Handler for Timer/Counter 0 + */ +#ifdef __AVR_ATmega644__ + SIGNAL (TIMER0_COMPA_vect){ +#else + SIGNAL (SIG_OUTPUT_COMPARE0){ +#endif +} + +/*! + * Timer 0: Kontrolliert den Servo per PWM + * PWM loescht bei erreichen. daher steht in OCR0 255-Speed!!! + * initilaisiert Timer 0 und startet ihn + */ +void pwm_0_init(void){ + + DDRB |= (1<<3); // PWM-Pin als Output + TCNT0 = 0x00; // TIMER0 vorladen + + #ifdef __AVR_ATmega644__ + TCCR0A = _BV(WGM00) | // Normal PWM + _BV(COM0A1); // Clear on Compare , Set on Top + //PWM_CLK_0; + + OCR0A = 8; + #else + TCCR0 = _BV(WGM00) | // Normal PWM + _BV(COM01) ; // Clear on Compare , Set on Top + + OCR0 = 8; // PWM loescht bei erreichen. daher steht in OCR0 255-Speed!!! + #endif + // TIMSK |= _BV(OCIE0); // enable Output Compare 0 overflow interrupt + //sei(); // enable interrupts +} + +// ---- Timer 1 ------ + +/*! + * Interrupt Handler for Timer/Counter 1A + */ +SIGNAL (SIG_OUTPUT_COMPARE1A){ +} + +/*! + * Interrupt Handler for Timer/Counter 1B + */ +SIGNAL (SIG_OUTPUT_COMPARE1B){ +} + +/*! + * Timer 1: Kontrolliert die Motoren per PWM + * PWM loescht bei erreichen. daher steht in OCR1A/OCR1B 255-Speed!!! + * initilaisiert Timer 0 und startet ihn + */ +void pwm_1_init(void){ + DDRD |= 0x30 ; // PWM-Pins als Output + TCNT1 = 0x0000; // TIMER1 vorladen + + TCCR1A = _BV(WGM10) | // Fast PWM 8 Bit + _BV(COM1A1) |_BV(COM1A0) | // Clear on Top, Set on Compare + _BV(COM1B1) |_BV(COM1B0); // Clear on Top, Set on Compare + + TCCR1B = _BV(WGM12) | + _BV(CS12) | _BV(CS10); // Prescaler = 1024 +// _BV(CS10); // Prescaler = 1 + + OCR1A = 255; // PWM loescht bei erreichen. daher steht in OCR1A 255-Speed!!! + OCR1B = 255; // PWM loescht bei erreichen. daher steht in OCR1B 255-Speed!!! + + // TIMSK|= _BV(OCIE1A) | _BV(OCIE1B); // enable Output Compare 1 overflow interrupt + // sei(); // enable interrupts +} + +/*! + * Timer 0: Kontrolliert den Servo per PWM + * PWM loescht bei erreichen. daher steht in OCR0 255-Speed!!! + * initilaisiert Timer 0 und startet ihn + */ +/* Kollidiert derzeit mit Timer2 fuer IR +void pwm_2_init(void){ + DDRD |= 0x80; // PWM-Pin als Output + TCNT2 = 0x00; // TIMER0 vorladen + + TCCR2 = _BV(WGM20) | // Normal PWM + _BV(COM21); // Clear on Top, Set on Compare +// _BV(CS22) | _BV(CS21) |_BV(CS20); // Prescaler = 1024 + + OCR2 = 8; // PWM löscht bei erreichen. daher steht in OCR0 255-Speed!!! + // TIMSK |= _BV(OCIE0); // enable Output Compare 0 overflow interrupt + //sei(); // enable interrupts +} +*/ + +#endif |