Makefile 无法将代码烧录到 ATmega328p

问题描述 投票:0回答:1

几个月前,我问,如果我定义了 ISR,为什么我的用 C 语言编写并闪存到 Arduino R3 Uno 上的 ATmega328p 的眨眼程序不断失败。我最终将问题范围缩小到我的 Makefile 的编写方式(我将其与

avr-gcc
avrdude
一起使用),并通过将代码复制粘贴到 Arduino IDE 中并使用内置的上传来解决这个问题。工具。

现在,我想回去准确理解 Makefile 失败的原因。我一直在浏览

avr-gcc
avrdude
的文档,并相信我已将问题范围缩小到我正在写入的内存区域。我正在使用的示例 C 项目如下:

int main(void)
{
    // set the data direction for the pin connected to
    // onboard LED
    DDRB |= _BV(DDB5);
    PORTB |= _BV(PORTB5);

    // no-op loop
    while (1) ;;

    // keep compiler happy
    return 0;
}

程序故意简单;它只是打开板载 LED 并使其保持亮起状态。此时,使用以下 make 文件进行刷新就可以正常工作了:

AVRFLAGS = -F -v -p m328p -c arduino -P /dev/ttyACM0 -U flash:w:blink.hex


default: blink.elf
    avr-objcopy -O ihex blink.elf blink.hex

blink.o:
    avr-gcc -g -Os -DF_CPU=16000000UL -mmcu=atmega328p -c -o blink.o blink.c

blink.elf: blink.o
    avr-gcc -o blink.elf blink.o

flash:
    sudo avrdude ${AVRFLAGS} blink.hex

clean:
    rm -rf *.o *.hex *.elf

但是,当我将 ISR 添加到文件顶部时:

ISR (TIMER1_COMPA_vect)
{
  PORTD ^= _BV(PORTB5);
}

并尝试闪光,一切都崩溃了。我在使用和不使用定时器/计数器 1 设置代码(出于演示目的而在此处进行了编辑)的情况下都尝试过此操作,并且不认为它会影响闪存的成功。我已经在其他程序中使用了这个完全相同的 ISR——以及与定时器/计数器 1 完全相同的设置代码——只要我使用 Arduino IDE 内置工具来刷新它们,就可以正常工作;否则,Arduino Uno 会闪烁表明正在接收数据,然后板载 LED 开始闪烁并持续闪烁。每当任何程序刷新不佳时,就会出现完全相同的闪烁模式。我用 -j .text -j .data

.eeprom
 和其他选项进行编译,但没有效果。

我只是想知道为什么会失败。

c makefile arduino arduino-uno
1个回答
1
投票
您忘记将

-mmcu=atmega328p

 传递到链接阶段。如果没有此选项,则不会添加 CRT 和中断向量表。虽然您只有一个 
main()
 函数,但它从地址 0(重置向量)开始,并且一切似乎都正常。由于您添加了 ISR,现在它的代码位于地址 0。

对于 GNU Make,您可以使用

COMPILE.c

LINK.c
 内置变量来获取正确的编译和链接命令。

© www.soinside.com 2019 - 2024. All rights reserved.