Okay dann hier alles, was es dazu braucht. Da ich vorher alles sorgfältig gelesen habe, kann ich keinen Fehler an einem falschen Buchstaben feststellen. Aber ich hab ja auch nur 2 Augen. =)
RP6ControlServoLib.h:
	Code:
	/* ****************************************************************************
 *                           _______________________
 *                           \| RP6  ROBOT SYSTEM |/
 *                            \_-_-_-_-_-_-_-_-_-_/             >>> RP6 CONTROL
 * ----------------------------------------------------------------------------
 * ------------------------ [c]2008 - Dirk ------------------------------------
 * ****************************************************************************
 * File: RP6ControlServoLib.h
 * Version: 1.0
 * Target: RP6 CONTROL - ATMEGA32 @16.00MHz
 * Author(s): Dirk
 * ****************************************************************************
 * Description:
 * This is the RP6ControlServoLib header file.
 * You have to include this file, if you want to use the library
 * RP6ControlServoLib.c in your own projects.
 *
 * ****************************************************************************
 * THE CHANGELOG CAN BE FOUND AT THE END OF THIS FILE!
 * ****************************************************************************
 */
 
/*****************************************************************************/
// Includes:
#include "RP6ControlLib.h"         // The RP6 Control Library. 
                                // Always needs to be included!
/*****************************************************************************/
// Defines:
// Servo constants:
#define SERVO1                0b00000001
#define SERVO2                0b00000010
#define SERVO3                0b00000100
#define SERVO4                0b00001000
#define SERVO5                0b00010000
#define SERVO6                0b00100000
#define SERVO7                0b01000000
#define SERVO8                0b10000000
// Servo movement limits (depending on servo type):
// Standard Servos need an impulse every 20ms (50Hz). This impulse must have
// a length of 1ms (0.7 .. 1ms) to move the servo lever to the left touch
// and a length of 2ms (2 .. 2.3ms) for moving it to the right touch. In the
// middle position the servo needs an impulse length of 1.5ms (1.3 .. 1.6ms).
// If you want to modify the following constants for a certain servo type,
// you must adapt the LEFT_TOUCH constant first (values ~70 .. 100 = ~0.7 ..
// 1ms at 100kHz) by using a servo position value (servoX_position) of zero.
// After that you have two "screws" to adjust the servo movement limits:
// First you may change the RIGHT_TOUCH constant. If you choose a higher
// value than 255, you will use 16-bit values. Higher values mean a longer
// impulse length, but longer impulses than 2.3ms do not make sense.
// Second you may alter the Timer 1 frequency constant (F_TIMER1).
// A higher frequency leads to smaller steps of the servo movement. This of
// course reduces the impulse length and may be compensated again by a higher
// RIGHT_TOUCH constant. As a possible range of Timer 1 frequency values you
// may use 50kHz (20us) .. 105.263kHz (9.5us).
// HINT: If you alter F_TIMER1, you'll have to adapt LEFT_TOUCH and
//       RIGHT_TOUCH again as you can see in the following table!
//     Steps ->        9.5        10        12.5    15        17.5    20    [us]
//  ------------------------------------------------------------------
//  LEFT_TOUCH        74        71        57        47        41        35
//  RIGHT_TOUCH        169        162        129        107        92        80
//  F_TIMER1        105263    100000    80000    66667    57143    50000 [Hz]
#define LEFT_TOUCH            71//22 //ES-05: 22    alter miniservo: 32         // Left servo touch      (~0.7ms)
#define RIGHT_TOUCH            162//220//ES-05_ 220    alter miniservo: 235     // Right servo touch     (~2.3ms)
#define MIDDLE_POSITION (RIGHT_TOUCH  / 2) // Middle position (~1.5ms)
#define PULSE_REPETITION    17            // Pulse repetition freq. (~50Hz)
#define F_TIMER1            100000        // Timer 1 frequency     (100kHz)
// Servo ports:
#define SERVO1_PULSE_ON        (PORTC |= IO_PC2)    // PC2
#define SERVO1_PULSE_OFF    (PORTC &= ~IO_PC2)
#define SERVO2_PULSE_ON        (PORTC |= IO_PC3)    // PC3
#define SERVO2_PULSE_OFF    (PORTC &= ~IO_PC3)
#define SERVO3_PULSE_ON        (PORTC |= IO_PC4)    // PC4
#define SERVO3_PULSE_OFF    (PORTC &= ~IO_PC4)
#define SERVO4_PULSE_ON        (PORTC |= IO_PC5)    // PC5
#define SERVO4_PULSE_OFF    (PORTC &= ~IO_PC5)
#define SERVO5_PULSE_ON        (PORTC |= IO_PC6)    // PC6
#define SERVO5_PULSE_OFF    (PORTC &= ~IO_PC6)
#define SERVO6_PULSE_ON        (PORTC |= IO_PC7)    // PC7
#define SERVO6_PULSE_OFF    (PORTC &= ~IO_PC7)
#define SERVO7_PULSE_ON        (PORTD |= IO_PD5)    // PD5
#define SERVO7_PULSE_OFF    (PORTD &= ~IO_PD5)
#define SERVO8_PULSE_ON        (PORTD |= IO_PD6)    // PD6
#define SERVO8_PULSE_OFF    (PORTD &= ~IO_PD6)
// -----------------------------------------------------------
// Other possible ports for connecting Servos to RP6Control:
//#define SERVOx_PULSE_ON        (PORTA |= ADC6)        // PA6
//#define SERVOx_PULSE_OFF    (PORTA &= ~ADC6)
//#define SERVOx_PULSE_ON        (PORTA |= ADC7)        // PA7
//#define SERVOx_PULSE_OFF    (PORTA &= ~ADC7)
// -----------------------------------------------------------
/*****************************************************************************/
// Variables:
uint16_t servo1_position;        // Servo 1 position [0..RIGHT_TOUCH]
uint16_t servo2_position;        // Servo 2 position [0..RIGHT_TOUCH]
uint16_t servo3_position;        // Servo 3 position [0..RIGHT_TOUCH]
uint16_t servo4_position;        // Servo 4 position [0..RIGHT_TOUCH]
uint16_t servo5_position;        // Servo 5 position [0..RIGHT_TOUCH]
uint16_t servo6_position;        // Servo 6 position [0..RIGHT_TOUCH]
uint16_t servo7_position;        // Servo 7 position [0..RIGHT_TOUCH]
uint16_t servo8_position;        // Servo 8 position [0..RIGHT_TOUCH]
/*****************************************************************************/
// Functions:
void initSERVO(uint8_t servos);
void startSERVO(void);
void stopSERVO(void);
void pulseSERVO(void);
void task_SERVO(void);
/******************************************************************************
 * Additional info
 * ****************************************************************************
 * Changelog:
 * - v. 1.0 (initial release) 31.12.2008 by Dirk
 *
 * ****************************************************************************
 */
/*****************************************************************************/
// EOF
 RP6ControlServoLib.c:
	Code:
	/* ****************************************************************************
 *                           _______________________
 *                           \| RP6  ROBOT SYSTEM |/
 *                            \_-_-_-_-_-_-_-_-_-_/             >>> RP6 CONTROL
 * ----------------------------------------------------------------------------
 * ------------------------ [c]2008 - Dirk ------------------------------------
 * ****************************************************************************
 * File: RP6ControlServoLib.c
 * Version: 1.0
 * Target: RP6 CONTROL - ATMEGA32 @16.00MHz
 * Author(s): Dirk
 * ****************************************************************************
 * Description:
 * This is my simple RP6 Control Servo Library for up to 8 Servos.
 *
 * COMMENT: It is a good idea to use a separate power supply for the servos!
 *
 * Servo connections:
 *         SERVO1 -> I/O Pin 7 (IO_PC2)        SERVO5 -> I/O Pin 4 (IO_PC6)
 *         SERVO2 -> I/O Pin 5 (IO_PC3)        SERVO6 -> I/O Pin 1 (IO_PC7)
 *         SERVO3 -> I/O Pin 6 (IO_PC4)        SERVO7 -> I/O Pin 9 (IO_PD5)
 *         SERVO4 -> I/O Pin 3 (IO_PC5)        SERVO8 -> I/O Pin 8 (IO_PD6)
 *
 * ****************************************************************************
 * ATTENTION: Stopwatch 8 is used for the servo task! Please do
 *            not use this stopwatch elsewhere in your program!
 *
 * ****************************************************************************
 * THE CHANGELOG CAN BE FOUND AT THE END OF THIS FILE!
 * ****************************************************************************
 */
 
/*****************************************************************************/
// Includes:
#include "RP6ControlServoLib.h"
/*****************************************************************************/
// Variables:
uint8_t usedservos;
uint8_t servo_on = FALSE;
uint16_t impulselength1 = 0;
uint16_t impulselength2 = 0;
uint16_t impulselength3 = 0;
uint16_t impulselength4 = 0;
uint16_t impulselength5 = 0;
uint16_t impulselength6 = 0;
uint16_t impulselength7 = 0;
uint16_t impulselength8 = 0;
volatile uint16_t intcounter = 0;
/*****************************************************************************/
// Functions:
/**
 * INIT SERVO
 *
 * Call this once before using the servo function.
 * Timer 1 is configured to work in "Clear Timer On
 * Compare Match Mode" (CTC). So no PWM is generated!
 * The timer runs on a fixed frequency (100kHz).
 *
 * Input:  Servos -> Used Servos
 *         Examples:
 *         - initSERVO(SERVO1 | SERVO2) -> Use only Servos 1 and 2
 *         - initSERVO(SERVO1 | SERVO6) -> Use only Servos 1 and 6
 *         - initSERVO(SERVO1 | SERVO2 | SERVO8) -> Use Servos 1, 2 and 8
 *
 */
void initSERVO(uint8_t servos)
{
    usedservos = servos;                // Save used Servos
    impulselength1 = 0;
    impulselength2 = 0;
    impulselength3 = 0;
    impulselength4 = 0;
    impulselength5 = 0;
    impulselength6 = 0;
    impulselength7 = 0;
    impulselength8 = 0;
    if (servos & SERVO1) {DDRC |= IO_PC2; PORTC &= ~IO_PC2;}
    if (servos & SERVO2) {DDRC |= IO_PC3; PORTC &= ~IO_PC3;}
    if (servos & SERVO3) {DDRC |= IO_PC4; PORTC &= ~IO_PC4;}
    if (servos & SERVO4) {DDRC |= IO_PC5; PORTC &= ~IO_PC5;}
    if (servos & SERVO5) {DDRC |= IO_PC6; PORTC &= ~IO_PC6;}
    if (servos & SERVO6) {DDRC |= IO_PC7; PORTC &= ~IO_PC7;}
    if (servos & SERVO7) {DDRD |= IO_PD5; PORTD &= ~IO_PD5;}
    if (servos & SERVO8) {DDRD |= IO_PD6; PORTD &= ~IO_PD6;}
// -----------------------------------------------------------
// Other possible ports for connecting Servos to RP6Control:
//    if (servos & SERVOx) {DDRA |= ADC6; PORTA &= ~ADC6;}
//    if (servos & SERVOx) {DDRA |= ADC7; PORTA &= ~ADC7;}
// -----------------------------------------------------------
    cli();
    // Timer 1: Normal port operation, mode 4 (CTC), clk/8
    TCCR1A =  (0 << COM1A1) 
            | (0 << COM1A0) 
            | (0 << COM1B1) 
            | (0 << COM1B0) 
            | (0 << FOC1A) 
            | (0 << FOC1B) 
            | (0 << WGM11) 
            | (0 << WGM10);
    TCCR1B =  (0 << ICNC1) 
            | (0 << ICES1) 
            | (0 << WGM13) 
            | (1 << WGM12) 
            | (0 << CS12) 
            | (1 << CS11) 
            | (0 << CS10);
    OCR1A = ((F_CPU/8/F_TIMER1)-1);    // 19 at 100kHz
// ------------------------------------------------------
// Possible OCR1A values (F_CPU = 16000000):
//    OCR1A = 2000000 / F_TIMER1 - 1    // F_TIMER1  (Steps)
//    OCR1A = 18;                        // 105263Hz  (9.5us)
//    OCR1A = 19;                        // 100000Hz   (10us)
//    OCR1A = 24;                        //  80000Hz (12.5us)
//    OCR1A = 29;                        //  66667Hz   (15us)
//    OCR1A = 34;                        //  57143Hz (17.5us)
//    OCR1A = 39;                        //  50000Hz   (20us)
// ------------------------------------------------------
    // Enable output compare A match interrupts:
    startSERVO();
    sei();
    startStopwatch8();                    // Needed for 20ms pulse repetition
}
/**
 * START SERVO
 *
 * If the servo function was stopped with the
 * function stopSERVO() before, it can be
 * started again with this function.
 *
 */
void startSERVO(void)
{
    TIMSK |= (1 << OCIE1A);
    servo_on = TRUE;
}
/**
 * STOP SERVO
 *
 * The servo function uses a certain amount of the
 * processor's calculating time. If the Servos are
 * not moving for a while, the Timer 1 interrupt
 * can be stopped with this function.
 *
 */
void stopSERVO(void)
{
    TIMSK &= ~(1 << OCIE1A);
    servo_on = FALSE;
}
/**
 * PULSE SERVO
 *
 * This is the servo pulse generation. This function
 * must be called every 20ms (pulse repetition).
 *
 * position = 0               : Left touch
 * position = RIGHT_TOUCH     : Right touch
 * position = MIDDLE_POSITION : Middle position
 *
 * ! Please make sure in your main program, that the !
 * ! servo position values (servoX_position) don't   !
 * ! exceed RIGHT_TOUCH!!!                           !
 *
 * COMMENT: The pulses are only started here!
 *          The pulses end in the Timer 1 ISR!
 *
 */
void pulseSERVO(void)
{
    if (servo_on) {
        intcounter = RIGHT_TOUCH;        // Avoid interference of Timer 1 ISR!
                                // (Only necessary, if pulseSERVO() is called
                                //  from outside of this library!)
        if (usedservos & SERVO1) {
            SERVO1_PULSE_ON; impulselength1 = LEFT_TOUCH + servo1_position;}
        if (usedservos & SERVO2) {
            SERVO2_PULSE_ON; impulselength2 = LEFT_TOUCH + servo2_position;}
        if (usedservos & SERVO3) {
            SERVO3_PULSE_ON; impulselength3 = LEFT_TOUCH + servo3_position;}
        if (usedservos & SERVO4) {
            SERVO4_PULSE_ON; impulselength4 = LEFT_TOUCH + servo4_position;}
        if (usedservos & SERVO5) {
            SERVO5_PULSE_ON; impulselength5 = LEFT_TOUCH + servo5_position;}
        if (usedservos & SERVO6) {
            SERVO6_PULSE_ON; impulselength6 = LEFT_TOUCH + servo6_position;}
        if (usedservos & SERVO7) {
            SERVO7_PULSE_ON; impulselength7 = LEFT_TOUCH + servo7_position;}
        if (usedservos & SERVO8) {
            SERVO8_PULSE_ON; impulselength8 = LEFT_TOUCH + servo8_position;}
        intcounter = 0;
    }
}
/**
 * TIMER1 ISR
 *
 * In this ISR the servo pulses are finished, if the
 * correct pulse length of each servo is reached.
 *
 */
ISR (TIMER1_COMPA_vect)
{
    intcounter++;
    if (intcounter == impulselength1) {SERVO1_PULSE_OFF;}
    if (intcounter == impulselength2) {SERVO2_PULSE_OFF;}
    if (intcounter == impulselength3) {SERVO3_PULSE_OFF;}
    if (intcounter == impulselength4) {SERVO4_PULSE_OFF;}
    if (intcounter == impulselength5) {SERVO5_PULSE_OFF;}
    if (intcounter == impulselength6) {SERVO6_PULSE_OFF;}
    if (intcounter == impulselength7) {SERVO7_PULSE_OFF;}
    if (intcounter == impulselength8) {SERVO8_PULSE_OFF;}
}
/**
 * SERVO TASK
 *
 * This is the servo task. The task performes the pulse repetition
 * with the help of a stopwatch.
 * At the next call of the servo task (earliest about 3ms after the
 * last servo pulse generation) the compare A match interrupt will
 * be disabled to reduce the interrupt load. It will be enabled
 * again after the next pulseSERVO() function call.
 *
 */
void task_SERVO(void)
{
    if (getStopwatch8() > 2) {TIMSK &= ~(1 << OCIE1A);}
    if (getStopwatch8() > PULSE_REPETITION) { // Pulse every ~20ms
        pulseSERVO();                    // Servo pulse generation
        if (servo_on) {TIMSK |= (1 << OCIE1A);}
        setStopwatch8(0);
    }
}
/******************************************************************************
 * Additional info
 * ****************************************************************************
 * Changelog:
 * - v. 1.0 (initial release) 31.12.2008 by Dirk
 *
 * ****************************************************************************
 */
/*****************************************************************************/
// EOF
 
RP6Control_Servo.c:
	Code:
	// Uncommented Version of RP6ControlServo.c
// written by Dirk, modyfied by Filou
// ------------------------------------------------------------------------------------------
#include "RP6ControlServoLib.h"
uint16_t pos = LEFT_TOUCH;
int main(void)
{ 
   initRP6Control();
   initLCD();
   showScreenLCD("################", "################");
   mSleep(500);
   showScreenLCD("<<RP6  Control>>", "<<LC - DISPLAY>>");
   mSleep(500);
   showScreenLCD(" Servo - Test 1 ", "  Version 1.00  ");
   mSleep(500);
   clearLCD();
   setLEDs(0b111111);
   mSleep(500);
   setLEDs(0b000000);
   
   initSERVO(SERVO1 | SERVO2);
   startStopwatch2();
   int turn=1;
   
   while(true) 
   {
        if (getStopwatch2() > 48)
        {
            servo1_position = pos;
            servo2_position = pos;
            setCursorPosLCD(0, 0);
            writeStringLCD_P("Servopos.: ");
            writeIntegerLCD(pos, DEC);
            writeStringLCD_P("   ");
            if(turn==0)
                pos=pos-4;
            if(turn==1)
                pos=pos+4;
            if (pos >= RIGHT_TOUCH &&  turn == 1)
                turn= 0;
            if (pos <= LEFT_TOUCH && turn == 0)
                turn=1;
            //pos=LEFT_TOUCH;
            setStopwatch2(0);
        }
        task_SERVO();
        mSleep(3);
    }
    return 0;
}
 Ist da Tatsächlich nur ein Buchstabe falsch?
Grüsse Filou
[EDIT]
Ist es möglich, dass der Port D mehr belastet werden kann als Port C ?? Wenn ich den Servo als Servo 8 am IO_PD6 anschliesse, stürtzt nichts mehr ab. [/EDIT]
						
					
Lesezeichen