ikarus_177
05.07.2009, 13:04
Hallo,
ich überarbeite gerade die Soft & Hardware meines Bots, und bin im Zuge dieser "Generalüberholung" auf C umgestiegen.
Als erstes wollte ich mein Bascom-Programm zur Servoansteuerung, das auch recht gut funktioniert, nach C umlegen (der altbekannte Weg mit 16-Bit Timer und der Generierung der Impulse nacheinander). Dazu muss meine ISR ja auf einige Variablen im Hauptprogramm zugreifen können (Vektor für die Impulslängen der Servos).
Laut mikrocontroller.net - Tutorial Abschnitt "Datenaustausch mit Interrupt-Routinen" (http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Datenaustausch_mit_Interrupt-Routinen) habe ich diese Variablen mit "volatile" versehen. Trotzdem meckert der Compiler weiterhin, diese Variablen seien in der ISR nicht definiert.
Vielleicht kann jemand damit was anfangen? Wo könnte der Hund begraben liegen?
Hier der ungetestete Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
/* -------------------------------------------------------------------------- */
/* Präprozessoranweisungen: */
/* -------------------------------------------------------------------------- */
#define SERVOPORT PORTA
#define DATENRICHTUNG DDRA
#define SERVO1 1
#define SERVO2 2
#define SERVO3 3
/* -------------------------------------------------------------------------- */
/* Funktionsprototypen: */
/* -------------------------------------------------------------------------- */
void init_Servo(void);
/* -------------------------------------------------------------------------- */
/* Beginn der Hauptfunktion: */
/* -------------------------------------------------------------------------- */
int main (void)
{
/* -------------------------------------------------------------------------- */
/* Definition von notwendigen Variablen: */
/* -------------------------------------------------------------------------- */
volatile uint16_t Servo[4] = {0}; //Pulslängen der Servos
volatile uint8_t iCounter = 0;
volatile uint8_t dServo = 0; //Dummyvariable für Verzögerungszeit
init_Servo();
return (0);
}
/* -------------------------------------------------------------------------- */
/* Funktionsdefinitionen: */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Initialisieren des Timers und setzen der verwendeten Pins als Ausgang: */
/* -------------------------------------------------------------------------- */
void init_Servo ()
{
//Setzen der Servopins als Ausgang:
DATENRICHTUNG |= (1 << SERVO1) | (1 << SERVO2) | (1 << SERVO3);
//Setzen der Ausgänge auf log. 0 (Anfangszustand)
SERVOPORT &= ~((1 << SERVO1) | (1 << SERVO2) | (1 << SERVO3));
//Konfigurieren des Timers:
TIMSK |= (1 << TOIE1); //Overflow-Interrupt aktivieren
TCCR1B |= (1 << CS11); //Prescale 8
sei(); //globale Interrupts aktivieren
}
/* -------------------------------------------------------------------------- */
/* Interrupt bei Überlauf von Timer1: */
/* -------------------------------------------------------------------------- */
ISR(TIMER1_OVF_vect)
{
switch (iCounter)
{
case 1: SERVOPORT &= ~(1 << SERVO1);
case 2: SERVOPORT &= ~(1 << SERVO2);
case 3: SERVOPORT &= ~(1 << SERVO3);
case 4: dServo = 0;
}
iCounter++;
if (iCounter == 4)
{
iCounter = 1;
}
switch (iCounter)
{
case 1: SERVOPORT |= (1 << SERVO1);
case 2: SERVOPORT |= (1 << SERVO2);
case 3: SERVOPORT |= (1 << SERVO3);
case 4: dServo = 1;
}
TCNT1 = 65535 - Servo[iCounter-1];
}
Ich verwende Eclipse incl. AVR-Plugin und avr-gcc unter Ubuntu.
Viele Grüße
ikarus_177
ich überarbeite gerade die Soft & Hardware meines Bots, und bin im Zuge dieser "Generalüberholung" auf C umgestiegen.
Als erstes wollte ich mein Bascom-Programm zur Servoansteuerung, das auch recht gut funktioniert, nach C umlegen (der altbekannte Weg mit 16-Bit Timer und der Generierung der Impulse nacheinander). Dazu muss meine ISR ja auf einige Variablen im Hauptprogramm zugreifen können (Vektor für die Impulslängen der Servos).
Laut mikrocontroller.net - Tutorial Abschnitt "Datenaustausch mit Interrupt-Routinen" (http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Datenaustausch_mit_Interrupt-Routinen) habe ich diese Variablen mit "volatile" versehen. Trotzdem meckert der Compiler weiterhin, diese Variablen seien in der ISR nicht definiert.
Vielleicht kann jemand damit was anfangen? Wo könnte der Hund begraben liegen?
Hier der ungetestete Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
/* -------------------------------------------------------------------------- */
/* Präprozessoranweisungen: */
/* -------------------------------------------------------------------------- */
#define SERVOPORT PORTA
#define DATENRICHTUNG DDRA
#define SERVO1 1
#define SERVO2 2
#define SERVO3 3
/* -------------------------------------------------------------------------- */
/* Funktionsprototypen: */
/* -------------------------------------------------------------------------- */
void init_Servo(void);
/* -------------------------------------------------------------------------- */
/* Beginn der Hauptfunktion: */
/* -------------------------------------------------------------------------- */
int main (void)
{
/* -------------------------------------------------------------------------- */
/* Definition von notwendigen Variablen: */
/* -------------------------------------------------------------------------- */
volatile uint16_t Servo[4] = {0}; //Pulslängen der Servos
volatile uint8_t iCounter = 0;
volatile uint8_t dServo = 0; //Dummyvariable für Verzögerungszeit
init_Servo();
return (0);
}
/* -------------------------------------------------------------------------- */
/* Funktionsdefinitionen: */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Initialisieren des Timers und setzen der verwendeten Pins als Ausgang: */
/* -------------------------------------------------------------------------- */
void init_Servo ()
{
//Setzen der Servopins als Ausgang:
DATENRICHTUNG |= (1 << SERVO1) | (1 << SERVO2) | (1 << SERVO3);
//Setzen der Ausgänge auf log. 0 (Anfangszustand)
SERVOPORT &= ~((1 << SERVO1) | (1 << SERVO2) | (1 << SERVO3));
//Konfigurieren des Timers:
TIMSK |= (1 << TOIE1); //Overflow-Interrupt aktivieren
TCCR1B |= (1 << CS11); //Prescale 8
sei(); //globale Interrupts aktivieren
}
/* -------------------------------------------------------------------------- */
/* Interrupt bei Überlauf von Timer1: */
/* -------------------------------------------------------------------------- */
ISR(TIMER1_OVF_vect)
{
switch (iCounter)
{
case 1: SERVOPORT &= ~(1 << SERVO1);
case 2: SERVOPORT &= ~(1 << SERVO2);
case 3: SERVOPORT &= ~(1 << SERVO3);
case 4: dServo = 0;
}
iCounter++;
if (iCounter == 4)
{
iCounter = 1;
}
switch (iCounter)
{
case 1: SERVOPORT |= (1 << SERVO1);
case 2: SERVOPORT |= (1 << SERVO2);
case 3: SERVOPORT |= (1 << SERVO3);
case 4: dServo = 1;
}
TCNT1 = 65535 - Servo[iCounter-1];
}
Ich verwende Eclipse incl. AVR-Plugin und avr-gcc unter Ubuntu.
Viele Grüße
ikarus_177