首页 > 解决方案 > 具有多个定义的嵌入式 C 和 AVR GCC 编译问题

问题描述

似乎我的编译器不愿意在其中构建固件,stepper_motor.c如下所示,它抛出了这个错误,我无法解决。

我创建了一个stepper_motor.c放置所有函数和变量的源,以及一个放置stepper_motor.h所有#defines 和函数原型的标头。在main.c我只包含stepper_motor.h标题并使用功能。正如您从 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 ++;
}

------------------------------ 头文件 ------------------ -----------------------------------------

#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>

标签: cembeddedc-preprocessorinterrupt-handlingavr-gcc

解决方案


真的,错误消息告诉你所有你需要知道的 - 你已经在两个地方定义了这些符号 - main.c 和 setpper_motor.c。

您已stepCounter在 stepper_motor.c 的第 50 行定义,也如 main.c 中所示。同样对于stepPasemotor_Phases

  • 如果它们是独立的并且不应在外部可见,则应声明两者static,以便它们仅在各自的翻译单元中可见。

  • 如果打算符号引用它们是同一个对象,则需要声明其中之一extern以向编译器指示其类型和名称,但它是在别处 定义的。

  • 如果它们是独立的但“需要”是全局的(因为您想不出更好的解决方案),那么它们不能具有相同的名称。

  • 如果您没有在 main.c 中引用它们,那么无论如何都应该从那里删除它们。当它们清楚地与步进电机控制相关并且可能应该封装在 stepper_motor.c 中时,您在这里定义它们似乎很奇怪。

一开始就避免使用全局变量是一个更好的解决方案,请参阅https://www.embedded.com/a-pox-on-globals/


推荐阅读