PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Einbindung asuro.c



DanielSun
11.01.2007, 17:45
Servus erst einmal,

wie wird eigentlich die asuro.c eingebunden? Meiner Meinung nach im makefile unter "SRC += asuro.c" . Wenn ich nun eine andere Datei einbinden will beispielsweise "xy.c" muss ich doch eigentlich nur obigen Eintrag ändern in "SRC += xy.c" . Aber irgentwie klappt es nicht. Ich bekomme dann nur einen Rucksack voller Fehlermeldungen, so an die 100.

Und ja alle Funktionen die ich noch nutze sind natürlich auch in der "xy.c" mit drin.

Was ist eigentlich der Unterschied zwischen ner *.c und *.h Datei. In der asuro.h sind doch nur alle verfügbaren Funktionen aufgeführt und die Symbolnamen auf die entsprechenden Pins geroutet. Das im Makefile verschiedene Compilereinstellungen und Hardwaredefinitionen gesetzt werden is mir schon klar, aber sonst verstehe ich nur Bahnhof... 8-[

Grüßle,

Der DanielSun

m.a.r.v.i.n
11.01.2007, 21:40
Hi,

soweit stimmt das, die Sourcefiles müssen aber alle im gleichen Verzeichnis wie das makefile stehen. Tun sie das nicht muß man den Pfad mit angeben, oder man fügt noch folgende Zeile im Makefile ein mit den Pfadangaben.

VPATH==../../lib

FÜr eine Einführung in C empfiehlt sich:
https://www.roboternetz.de/wissen/index.php/C-Tutorial

DanielSun
12.01.2007, 22:46
Servus,

so ähnlich hab ich mir das auch vorgestellt. Nur ich kriegs einfach nicht hin. Hab jetzt schon meine veränderten Dateien als asuro.c und asuro.h gespeichert. Aber irgentwie passt da was nicht zusammen. Hier unten mal ein kleiner Auszug meiner unendlichen Fehlerliste.


asuro.c:337: error: syntax error before numeric constant
asuro.c:337: warning: type defaults to `int' in declaration of `Msleep'
asuro.c:337: warning: function declaration isn't a prototype
asuro.c:337: error: conflicting types for 'Msleep'
asuro.c:290: error: previous definition of 'Msleep' was here

Und hier noch dazu der Code aller Dateien.

asuro.c

#include "asuro.h"
#include "string.h"
#include <i2cmaster.h>
#include <twimaster.h>
#define us_l 0xE0 // device address of left SRF08, see label (default 0xE0)
#define us_r 0xE2 // device address of right SRF08, see label (default 0xE0)

//Distance to Object
unsigned char dist_l;
unsigned char dist_r;

/*! \brief Counter fuer 36kHz.\n
* Wird in derInterrupt Funktion SIG_OVERFLOW2 hochgezaehlt\n
* und in der Sleep() Funktion abgefragt.
* \see Sleep
*/
volatile unsigned char count36kHz;
/*! \brief Sytemzeit.\n
* Wird in der Interrupt Funktion SIG_OVERFLOW2 hochgezaehlt\n
* und in der Gettime() Funktion verwendet.
* \see Gettime
*/
volatile unsigned long timebase;
/*! \brief Odometrie Sensor Abfrage im Interrupt Betrieb.\n
* Wird in der Interrupt Funktion SIG_ADC abgefragt,\n
* in der Encoder_Init() und Encoder_Start() Funktion gesetzt\n
* und in der Encoder_Stop() Funktion geloescht .
* \see Encoder_Init, Encoder_Start, Encoder_Stop
*/
volatile int autoencode=FALSE;

volatile unsigned int incr_left;
volatile unsigned int incr_right;
/*! \brief Werte der Inkrementalgeber über Int0/1.\n
* Wird in der Interrupt Funktion SIG_INCR_L und SIG_INCR_R abgefragt,\n
* \see
*/

/*!
* \func SIG_OVERFLOW2
* \brief Interrupt Funktion: Timer2 Overflow
* uses timer2 (36kHz for IR communication)
*/
SIGNAL (SIG_OVERFLOW2)
{
TCNT2 += 0x25;
count36kHz ++;
if (!count36kHz) timebase ++;
}

//Ansteuerung Inkrementalgeber
/*!
* \func SIG_INTERRUPT0
* \brief Interrupt Funktion: INT0
*/
SIGNAL (SIG_INTERRUPT0)
{
incr_left++;

}

/*!
* \func SIG_INTERRUPT1
* \brief Interrupt Funktion: INT1
*/
SIGNAL (SIG_INTERRUPT1)
{
incr_right++;

}

/*SIGNAL (SIG_OVERFLOW0) //Regelalgorithmus in ISR
{


}
*/
void IncrInit (void)
{
DDRD |= (0 << PD2) | (0 << PD3); // Input for Int0/1 => no RED StatusLed
PORTD |= (1 << PD2) | (1 << PD3);
MCUCR |= (1 << ISC10) | (1 << ISC00); //any logical change cause interrupt
GICR |= (1 << INT0) |(1 << INT1); // Enable external Interrupt 0/1
sei();
}

// neue Zeitfunktion
unsigned long Gettime(void)
{
return ((timebase*256)+count36kHz)/36;
}

/* Init function Processor will be initalized to work correctly */
void Init (void)
{
//-------- seriell interface programmed in boot routine and already running -------
// prepare 36kHz for IR - Communication
TCCR2 = (1 << WGM20) | (1 << WGM21) | (1 << COM20) | (1 << COM21) | (1 << CS20);
OCR2 = 0x91; // duty cycle for 36kHz
TIMSK |= (1 << TOIE2); // 36kHz counter for sleep

// prepare RS232
UCSRA = 0x00;
UCSRB = 0x00;
UCSRC = 0x86; // No Parity | 1 Stop Bit | 8 Data Bit
UBRRL = 0xCF; // 2400bps @ 8.00MHz

// I/O Ports
DDRB = IRTX | LEFT_DIR | PWM | GREEN_LED;
DDRD = RIGHT_DIR | FRONT_LED | ODOMETRIE_LED | RED_LED;

// for PWM (8-Bit PWM) on OC1A & OC1B
TCCR1A = (1 << WGM10) | (1 << COM1A1) | (1 << COM1B1);
// tmr1 running on MCU clock/8
TCCR1B = (1 << CS11);

// A/D Conversion
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // clk/64


FrontLED(OFF);
BackLED(ON,ON);
BackLED(OFF,OFF);
StatusLED(GREEN);

MotorDir(FWD,FWD);
MotorSpeed(0,0);

}

/* Set motor speed */
inline void MotorSpeed(unsigned char left_speed, unsigned char right_speed)
{
OCR1A = left_speed;
OCR1B = right_speed;
}

/* Set motor direction */
inline void MotorDir(unsigned char left_dir, unsigned char right_dir)
{
PORTD = (PORTD &~ ((1 << PD4) | (1 << PD5))) | left_dir;
PORTB = (PORTB &~ ((1 << PB4) | (1 << PB5))) | right_dir;
}

/* Status LED (OFF,GREEN,YELLOW,RED)*/
/* example code set StatusLED GREEN */
/* StatusLED(GREEN); */
inline void StatusLED(unsigned char color)
{
if (color == OFF) {GREEN_LED_OFF; RED_LED_OFF;}
if (color == GREEN) {GREEN_LED_ON; RED_LED_OFF;}
if (color == YELLOW) {GREEN_LED_ON; RED_LED_ON;}
if (color == RED) {GREEN_LED_OFF; RED_LED_ON;}
}

/* Front LED */
/* example code FrontLED ON */
/* FrontLED(ON); */
inline void FrontLED(unsigned char status)
{
PORTD = (PORTD &~(1 << PD6)) | (status << PD6);
}

/* function for Break LEDs */
/* example code right LED On left LED Off */
/* BackLED(OFF,ON); */
void BackLED(unsigned char left, unsigned char right)
{
if (left || right) {
PORTD &= ~(1 << PD7); // Wheel LED OFF
DDRC |= (1 << PC0) | (1 << PC1); // Output => no odometrie
PORTC |= (1 << PC0) | (1 << PC1);
}
if (!left) PORTC &= ~(1 << PC1);
if (!right) PORTC &= ~(1 << PC0);
}
int Batterie(void)
{
ADMUX = (1 << REFS0) | (1 << REFS1) | BATTERIE; // internal 2.56V reference with external capacitor
ADCSRA |= (1 << ADSC); // Start conversion
while (!(ADCSRA & (1 << ADIF))); // wait for conversion complete
ADCSRA |= (1 << ADIF); // clear ADCIF
return ADCL + (ADCH << 8);
}
/* function to read out line follow phototransistors (left,rigth) */
void LineData(unsigned int *data)
{
int ec_bak=autoencode;
autoencode=FALSE;

ADMUX = (1 << REFS0) | IR_LEFT; // AVCC reference with external capacitor
Sleep(10);
ADCSRA |= (1 << ADSC); // Start conversion
while (!(ADCSRA & (1 << ADIF))); // wait for conversion complete
ADCSRA |= (1 << ADIF); // clear ADCIF
data[0] = ADCL + (ADCH << 8);

ADMUX = (1 << REFS0) | IR_RIGHT; // AVCC reference with external capacitor
Sleep(10);
ADCSRA |= (1 << ADSC); // Start conversion
while (!(ADCSRA & (1 << ADIF))); // wait for conversion complete
ADCSRA |= (1 << ADIF); // clear ADCIF
data[1] = ADCL + (ADCH << 8);

autoencode=ec_bak;
}



/* function for serial communication */
void SerWrite(unsigned char *data,unsigned char length)
{
unsigned char i = 0;
UCSRB = 0x08; // enable transmitter
while (length > 0) {
if (UCSRA & 0x20) { // wait for empty transmit buffer
UDR = data[i++];
length --;
}
}
while (!(UCSRA & 0x40));
for (i = 0; i < 0xFE; i++)
for(length = 0; length < 0xFE; length++);
}

void SerRead(unsigned char *data, unsigned char length,unsigned int timeout)
{
unsigned char i = 0;
unsigned int time = 0;
UCSRB = 0x10; // enable receiver
/* non blocking */
if (timeout != 0) {
while (i < length && time++ < timeout) {
if (UCSRA & 0x80) {
data[i++] = UDR;
time = 0;
}
}
if (time > timeout) data[0] = 'T';
}
/* blocking */
else {
while (i < length) {
if (UCSRA & 0x80)
data[i++] = UDR;
}
}
}




/* uses 36kHz timer => Sleep(x) = x/36kHz [sec] */
void Sleep(unsigned char time36kHz)
{
unsigned char ziel=(time36kHz+count36kHz) & 0x00FF;
while (count36kHz != ziel);
}


/************************************************** *************************
* void PrintInt(int wert)
*
* last modification:
* Ver. Date Author Comments
* ------- ---------- -------------- ---------------------------------
* 2.60 28.09.2005 m.a.r.v.i.n strlen instead fixed length
************************************************** *************************/
void PrintInt(int wert)
{
char text[16]=" ";
itoa(wert,text,10);
SerWrite(text,strlen(text));
}

void Msleep(int dauer)
{
int z;
for(z=0;z<dauer;z++) Sleep(36);
}

//i2c-Communication
void init_us(void)
{


i2c_init(); // initialize I2C library

//---us_l---
// set range
i2c_start_wait(us_l+I2C_WRITE); // set device address and write mode
i2c_write(0x02); // write Register 2 (range)
i2c_write(0x18); // write 0x18 range=1m

// set gain
i2c_write(0x01); // write Register 1 (gain)
i2c_write(0x05); // write 0x05 gain=110
i2c_stop(); // set stop conditon = release bus

//---us_r---
// set range
i2c_start_wait(us_r+I2C_WRITE); // set device address and write mode
i2c_write(0x02); // write Register 2 (range)
i2c_write(0x18); // write 0x18 range=1m

// set gain
i2c_write(0x01); // write Register 1 (gain)
i2c_write(0x05); // write 0x05 gain=110
i2c_stop(); // set stop conditon = release bus
}

unsigned char us_l(void)
{

// write command to SRF08 and start measurement
//Start
i2c_start_wait(us_l+I2C_WRITE); // set device address and write mode
i2c_write(0x00); // write Register 0 (commands)
//Messung
i2c_write(0x51); // write command: measurement in cm
i2c_stop(); // set stop conditon = release bus

//Wait for Measurement
Msleep(65);

// read measurement from Register 3
i2c_start_wait(us_lI2C_WRITE); // set device address and write mode
i2c_write(0x03); // write address = 3->read from Register 3
i2c_rep_start(us_l+I2C_READ); // set device address and read mode
//Slave send Data
dist_l = i2c_readNak(); //distance left
i2c_stop();
return dist_l;
}

unsigned char us_r(void)
{

// write command to SRF08 and start measurement
//Start
i2c_start_wait(us_r+I2C_WRITE); // set device address and write mode
i2c_write(0x00); // write Register 0 (commands)
//Messung
i2c_write(0x51); // write command: measurement in cm
i2c_stop(); // set stop conditon = release bus

//Wait for Measurement
Msleep(65);

// read measurement from Register 3
i2c_start_wait(us_r+I2C_WRITE); // set device address and write mode
i2c_write(0x03); // write address = 3->read from Register 3
i2c_rep_start(us_r+I2C_READ); // set device address and read mode
//Slave send Data
dist_r = i2c_readNak(); //distance right
i2c_stop();
return dist_r;
}



asuro.h

#ifndef HTW_ASURO_H
#define HTW_ASURO_H

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>

#define FALSE 0
#define TRUE 1

#define OFF 0
#define ON 1

#define GREEN 1
#define RED 2
#define YELLOW 3

/* neue Funktionen und Variablen*/
#define LEFT 0
#define RIGHT 1

/* --- Globale Variablen -----------------------------------*/
/*!



/*!
* gibt die aktuelle Zeit zurueck
* \return aktuelle Zeit in Millisekunden
*/
unsigned long Gettime(void);

// Wartefunktion in ms
void Msleep(int dauer);


//Ausgabe eines Integer Wertes als String ueber die serielle Schnittstelle.
void PrintInt(int wert);


//gibt den Wert der Batteriespannung zurueck
//return A/D Wandler Wert (Wertebereich 0..1023)
int Batterie(void);


/*! Initialisiert die Hardware (Ports, A/D Wandler, Serielle Schnittstelle, PWM)
* Die Init Funktion, muss von jeden Programm beim Start aufgerufen werden */
void Init(void);

//Setzen der Status LED.StatusLED(GREEN)
inline void StatusLED(unsigned char color);

//Setzen der Front LED, FrontLED(ON)
inline void FrontLED(unsigned char status);

//Setzen der Back LEDs BackLED(OFF,ON)
void BackLED(unsigned char left, unsigned char right);

//Setze Motor Richtung MotorDir(BREAK,RWD) FWD,RWD,BREAK,FREE
inline void MotorDir(unsigned char left_dir, unsigned char right_dir);

//Setze Motor Geschwindigkeit. 0= Stop, 255=Vollgas
inline void MotorSpeed(unsigned char left_speed, unsigned char right_speed);

//Ausgabe von Zeichen ueber die serielle Schnittstelle
void SerWrite(unsigned char *data,unsigned char length);

//Einlesen von Zeichen ueber die serielle Schnittstelle
void SerRead(unsigned char *data, unsigned char length, unsigned int timeout);

//Linienfolger Daten auslesen. Photosensoren links und rechts
void LineData(unsigned int *data);

//Wartefunktion
void Sleep(unsigned char time36kHz);

//Initialisierung der Incrementalgeber
void IncrInit(void);

//Initialisierung der Ultraschallsensoren
void init_us(void);

//Messfunktionen
unsigned char us_l(void);
unsigned char us_r(void);

/* ----------- END ------------ */


/* --------------- INTERNAL ------------- */
#define GREEN_LED_ON PORTB |= GREEN_LED /*!< Gruene Status LED an */
#define GREEN_LED_OFF PORTB &= ~GREEN_LED /*!< Gruene Status LED aus */
#define RED_LED_ON PORTD |= RED_LED /*!< Rote Status LED an */
#define RED_LED_OFF PORTD &= ~RED_LED /*!< Rote Status LED aus */

#define FWD (1 << PB5) /*!< Motor vorwaerts */
#define RWD (1 << PB4) /*!< Motor rueckwaerts */
#define BREAK 0x00 /*!< Motor bremsen */
#define FREE (1 << PB4) | (1 << PB5) /*!< Motor freilaufend */

#define IRTX (1 << PB3) /*!< PB3 Port fuer Infrarot Transmitter LED */
#define GREEN_LED (1 << PB0) /*!< PB0 Port fuer Gruene Status LED */
#define RED_LED (1 << PD2) /*!< PD2 Port fuer Rote Status LED */

#define PWM (1 << PB1) | (1 << PB2) /*!< PB1, PB2 Ports fuer Pulsweitenmodulation der Motor Geschwindigkeit */
#define RIGHT_DIR (1 << PB4) | (1 << PB5) /*!< PB4, PB5 Ports fuer Drehrichtung rechter Motor */
#define LEFT_DIR (1 << PD4) | (1 << PD5) /*!< PD4, PD5 Ports fuer Drehrichtung linker Motor */

//#define SWITCHES (1 << PD3) /* PD3 Port fuer Tastsensor */
//#define SWITCH_ON PORTD |= SWITCHES /* Tastsensor an */
//#define SWITCH_OFF PORTD &= ~SWITCHES /* Tastsensor aus */

#define BATTERIE (1 << MUX0) | (1 << MUX2) /*!< ADC5 A/D Wandler Port fuer Batterie Abfrage */
//#define SWITCH (1 << MUX2) /*!< ADC4 A/D Wandler Port fuer Tastsensor */
#define IR_LEFT (1 << MUX0) | (1 << MUX1) /*!< ADC3 A/D Wandler Port fuer Linienfolger Fototransistor links */
#define IR_RIGHT (1 << MUX1) /*!< ADC2 A/D Wandler Port fuer Linienfolger Fototransistor rechts */
#define FRONT_LED (1 << PD6) /*!< PD6 Port fuer Front LED */




#endif /* HTW_ASURO_H */



und meine test.c (ne kleine Ausweichsteuerung)

/************************************************** *******************************************
Programm Ausweichmanöver
Ver. 1

************************************************** ********************************************/

#include "asuro.h"

int main(void) {
unsigned char dist_l;
unsigned char dist_r;
int diff;
Init();
IncrInit();
init_us();
MotorDir(FWD,FWD);
MotorSpeed(179,179);
StatusLED(GREEN);
while (1){
us_l();
us_r();
//Ausgabe der Messwerte
SerWrite("\rL: ",4);
PrintInt(dist_l);
SerWrite("\t\tR: \n",4);
PrintInt(dist_r);
if (dist_l || dist_r<60)
{
//diff=dist_l-dist_r;
MotorSpeed(200,160);
}
if (dist_l || dist_r<30)
{
MotorSpeed(200,0);
}
if ((dist_l || dist_r)==0)
{
MotorSpeed(179,179);
}
}//End while
}//End main

Unser Modifizierter Asuro besitzt weder Kollisionstaster noch Odometriesensoren. Dafür haben wir zwei Ultraschallsensoren (SRF08 mit I2C) angebaut und lesen die Motorinkremente mittels Gabellichtschranken an INT0 und INT1 aus. Zum Schluss noch ein Bildchen des Ganzen.

http://DanielSun.da.ohost.de/Robot_021.jpg


schon mal Danke im Vorraus.

DanielSun

m.a.r.v.i.n
13.01.2007, 10:25
Hi,

Naja, das klingt ja erst mal nur nach ganz normalen Syntaxfehlern im Programmcode. So ist z.B us_l und us_r zum einen als Define für die I2C Adressen deklariert und an anderer Stelle als Funktionsname. Das geht natürlich nicht. Die anderen Fehler sind evtl. nur Folgefehler.

BTW. Sieht gut aus euer Projekt

DanielSun
13.01.2007, 16:23
Ok,

Danke marvin wusste nicht, dass das ein Problem ist. Ich dachte die Defines werden sofort vom Compiler ersetzt durch die dazugehörigen Werte. Jetzt hab ich ausser n paar Warnungen wegen "/*" im Kommentar keine Fehlermeldungen.

Zwei kleine Fragen noch:

1. Was ist der Unterschied zwischen ner *.c und ner *.h Datei, im Prinzip werden doch beide dazugelinkt?

2. Wozu enthält die asuro.c diese /brief und /see Kommandos im Kommentar? Sind das so ne Art help-Anweisungen z.B. fürs AVRStudio?

Grüßle

Der DanielSun...

m.a.r.v.i.n
13.01.2007, 23:39
1. Die *.c Dateien werden dazugelinkt und enthalten die Funktionen. Die *.h Dateien werden von *.c Dateien included und enthalten nur die Prototypen für die Funktionen. Eine *h. Datei kann von mehreren *.c Quellen included werden.

2. die /brief und /see Kommentare sind für das doxygen Tool, damit wird die Dokumentation erstellt.