具有多个定义的嵌入式 C 和 AVR GCC 编译问题
Embedded C, and AVR GCC compilation issue with multiple definitions
我的编译器似乎不愿意在 stepper_motor.c
中构建固件,如下所示,它抛出了这个错误,我无法解决。
我已经创建了一个 stepper_motor.c
源,其中放置了我所有的函数和变量,以及一个 stepper_motor.h
header,其中包含所有 #define
和函数原型。在 main.c
中,我只包含 stepper_motor.h
header 并使用函数。正如您从 shell 日志数据中看到的那样,它没有编译并告诉我们多次定义了 4 个 x 变量。这些用于定时器的 ISR() 例程中,因此它们也需要是易变的。
非常感谢有关此问题的任何信息。
这是我的 main.c 包括:--------
#include <avr/io.h>
#include <Hardware_Bay.h>
#include <util/delay.h>
#include <USART.h>
#include <string.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdbool.h>
#include <avr/interrupt.h>
#include <scale16.h>
#include <stepper_motor.h>
const uint8_t motor_Phases[] = {
(1 << COIL_B1), // full step
(1 << COIL_B1) | (1 << COIL_A2), // half step
(1 << COIL_A2), // full step
(1 << COIL_A2) | (1 << COIL_B2), // half step
(1 << COIL_B2), // full step
(1 << COIL_B2) | (1 << COIL_A1), // etc..
(1 << COIL_A1),
(1 << COIL_A1) | (1 << COIL_B1),
};
volatile uint8_t stepPhase = 0;
volatile uint16_t stepCounter = 0;
volatile int8_t direction = FORWARD;
ISR(TIMER0_COMPA_vect) { // Timer/Counter-0 Compare match interrupt vector enable
stepPhase += direction; // take step in right direction
stepPhase &= 0b00000111; // keep the stepPhase in range (0 - 7)
STEPPER_PORT = motor_Phases[stepPhase]; // write phase out to motor COIL-1 A/B
HALL_PORT = motor_Phases[stepPhase]; // write phase out to motor COIL-2 A/B
stepCounter ++;
}
-----------------------------header 文件-------- ------------------------------------
#ifndef STEPPER_MOTOR_H_INCLUDED
#define STEPPER_MOTOR_H_INCLUDED
#endif // STEPPER_MOTOR_H_INCLUDED
#define FORWARD 1
#define BACKWARD -1
#define TURN 200
#define MAX_DELAY 255
#define MIN_DELAY 10
#define ACCELERATION 16
#define RAMP_STEPS (MAX_DELAY - MIN_DELAY) / ACCELERATION
void stepperDrive(uint8_t number_of_steps, uint8_t delay);
void trapezoidDrive_Stepper(int16_t number_of_steps);
PS D:\Users\Arhitect\Documents\C_Programs\Physalis_Banshee\Physalis_GEO_version_3.6> make flash
avr-gcc -Wl,-Map,Physalis_GEO_version_3.6.map -Wl,--gc-sections -mmcu=atmega1284p fuse.o main.o stepper_motor.o USART.o -o Physalis_GEO_version_3.6.elf
stepper_motor.o: In function `stepperDrive':
D:\Users\Arhitect\Documents\C_Programs\Physalis_Banshee\Physalis_GEO_version_3.6/stepper_motor.c:50: multiple definition of `stepCounter'
main.o:(.bss.stepCounter+0x0): first defined here
stepper_motor.o:(.data.direction+0x0): multiple definition of `direction'
main.o:(.data.direction+0x0): first defined here
stepper_motor.o:(.rodata.motor_Phases+0x0): multiple definition of `motor_Phases'
main.o:(.rodata.motor_Phases+0x0): first defined here
stepper_motor.o: In function `stepperDrive':
D:\Users\Arhitect\Documents\C_Programs\Physalis_Banshee\Physalis_GEO_version_3.6/stepper_motor.c:50: multiple definition of `stepPhase'
main.o:(.bss.stepPhase+0x0): first defined here
make: *** [Physalis_GEO_version_3.6.elf] Error 1
PS D:\Users\Arhitect\Documents\C_Programs\Physalis_Banshee\Physalis_GEO_version_3.6>
实际上,错误消息会告诉您所有您需要知道的信息 - 您已经在两个地方定义了这些符号 - main.c 和 setpper_motor.c。
您已在 stepper_motor.c 的第 50 行定义了 stepCounter
,并且如 main.c 中所示。同样适用于 stepPase
和 motor_Phases
.
如果它们是独立的并且不应该在外部可见那么
两者都应声明为 static
,以便它们仅在
他们各自的翻译单位。
如果打算让符号引用它们是相同的对象,那么其中一个需要被声明为extern
向编译器指示它的类型和名称,但它在其他地方已 定义 ..
如果它们是独立的但 "need" 是全局的(因为你不能
想想一个更好的解决方案),那么他们就不能有相同的名字。
如果您没有在 main.c 中引用它们,那么无论如何都应该将它们从那里删除。当它们明显与步进电机控制相关并且可能应该封装在 stepper_motor.c 中时,您会在这里定义它们似乎很奇怪。
避免在第一个地方使用全局变量是一个更好的解决方案,请参阅 https://www.embedded.com/a-pox-on-globals/
我的编译器似乎不愿意在 stepper_motor.c
中构建固件,如下所示,它抛出了这个错误,我无法解决。
我已经创建了一个 stepper_motor.c
源,其中放置了我所有的函数和变量,以及一个 stepper_motor.h
header,其中包含所有 #define
和函数原型。在 main.c
中,我只包含 stepper_motor.h
header 并使用函数。正如您从 shell 日志数据中看到的那样,它没有编译并告诉我们多次定义了 4 个 x 变量。这些用于定时器的 ISR() 例程中,因此它们也需要是易变的。
非常感谢有关此问题的任何信息。
这是我的 main.c 包括:--------
#include <avr/io.h>
#include <Hardware_Bay.h>
#include <util/delay.h>
#include <USART.h>
#include <string.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdbool.h>
#include <avr/interrupt.h>
#include <scale16.h>
#include <stepper_motor.h>
const uint8_t motor_Phases[] = {
(1 << COIL_B1), // full step
(1 << COIL_B1) | (1 << COIL_A2), // half step
(1 << COIL_A2), // full step
(1 << COIL_A2) | (1 << COIL_B2), // half step
(1 << COIL_B2), // full step
(1 << COIL_B2) | (1 << COIL_A1), // etc..
(1 << COIL_A1),
(1 << COIL_A1) | (1 << COIL_B1),
};
volatile uint8_t stepPhase = 0;
volatile uint16_t stepCounter = 0;
volatile int8_t direction = FORWARD;
ISR(TIMER0_COMPA_vect) { // Timer/Counter-0 Compare match interrupt vector enable
stepPhase += direction; // take step in right direction
stepPhase &= 0b00000111; // keep the stepPhase in range (0 - 7)
STEPPER_PORT = motor_Phases[stepPhase]; // write phase out to motor COIL-1 A/B
HALL_PORT = motor_Phases[stepPhase]; // write phase out to motor COIL-2 A/B
stepCounter ++;
}
-----------------------------header 文件-------- ------------------------------------
#ifndef STEPPER_MOTOR_H_INCLUDED
#define STEPPER_MOTOR_H_INCLUDED
#endif // STEPPER_MOTOR_H_INCLUDED
#define FORWARD 1
#define BACKWARD -1
#define TURN 200
#define MAX_DELAY 255
#define MIN_DELAY 10
#define ACCELERATION 16
#define RAMP_STEPS (MAX_DELAY - MIN_DELAY) / ACCELERATION
void stepperDrive(uint8_t number_of_steps, uint8_t delay);
void trapezoidDrive_Stepper(int16_t number_of_steps);
PS D:\Users\Arhitect\Documents\C_Programs\Physalis_Banshee\Physalis_GEO_version_3.6> make flash
avr-gcc -Wl,-Map,Physalis_GEO_version_3.6.map -Wl,--gc-sections -mmcu=atmega1284p fuse.o main.o stepper_motor.o USART.o -o Physalis_GEO_version_3.6.elf
stepper_motor.o: In function `stepperDrive':
D:\Users\Arhitect\Documents\C_Programs\Physalis_Banshee\Physalis_GEO_version_3.6/stepper_motor.c:50: multiple definition of `stepCounter'
main.o:(.bss.stepCounter+0x0): first defined here
stepper_motor.o:(.data.direction+0x0): multiple definition of `direction'
main.o:(.data.direction+0x0): first defined here
stepper_motor.o:(.rodata.motor_Phases+0x0): multiple definition of `motor_Phases'
main.o:(.rodata.motor_Phases+0x0): first defined here
stepper_motor.o: In function `stepperDrive':
D:\Users\Arhitect\Documents\C_Programs\Physalis_Banshee\Physalis_GEO_version_3.6/stepper_motor.c:50: multiple definition of `stepPhase'
main.o:(.bss.stepPhase+0x0): first defined here
make: *** [Physalis_GEO_version_3.6.elf] Error 1
PS D:\Users\Arhitect\Documents\C_Programs\Physalis_Banshee\Physalis_GEO_version_3.6>
实际上,错误消息会告诉您所有您需要知道的信息 - 您已经在两个地方定义了这些符号 - main.c 和 setpper_motor.c。
您已在 stepper_motor.c 的第 50 行定义了 stepCounter
,并且如 main.c 中所示。同样适用于 stepPase
和 motor_Phases
.
如果它们是独立的并且不应该在外部可见那么 两者都应声明为
static
,以便它们仅在 他们各自的翻译单位。如果打算让符号引用它们是相同的对象,那么其中一个需要被声明为
extern
向编译器指示它的类型和名称,但它在其他地方已 定义 ..如果它们是独立的但 "need" 是全局的(因为你不能 想想一个更好的解决方案),那么他们就不能有相同的名字。
如果您没有在 main.c 中引用它们,那么无论如何都应该将它们从那里删除。当它们明显与步进电机控制相关并且可能应该封装在 stepper_motor.c 中时,您会在这里定义它们似乎很奇怪。
避免在第一个地方使用全局变量是一个更好的解决方案,请参阅 https://www.embedded.com/a-pox-on-globals/