我正在努力学习AVR C,并在摆弄atmega 328P微控制器.我正在使用Linux Mint上的avr-GCC工具链来编译我的代码并将其刷新到Arduino板上.

因此,我试图使用函数调用来闪烁两个LED灯.我做了两个功能--一个是LED闪烁,连接到我的Arduino板的第7针,另一个是LED闪烁,连接到Arduino板的第13针.

这些函数正在工作,但在我修改代码时,我注意到了一个奇怪的行为.在main()之外,这些函数是按照它们在中定义的顺序调用和执行的;而不是按照它们从int main()内部调用的顺序.

这是我的代码

#include <avr/io.h>
#include <util/delay.h>

void blinkPin13() {
    while(1) {
        DDRB = DDRB | (1 << DDB5);
        PORTB = PORTB | (1 << PORTB5);
        _delay_ms(5000);
        PORTB = PORTB & ~(1 << PORTB5);
        _delay_ms(500);
    }
}

void blinkPin7() {
    while(1) {
        DDRD = DDRD | (1 << DDD7);
        PORTD = PORTD | (1 << PORTD7);
        _delay_ms(1000);
        PORTD = PORTD & ~(1 << PORTD7);
        _delay_ms(500);
    }
}


int main(void) {    
    blinkPin7();
    blinkPin13();
    return 0;
}

这是用于编译和刷新代码的Makefile

default:
    avr-gcc -Os -DF_CPU=16000000UL -mmcu=atmega328p -c -o led.o led.c
    avr-gcc -o led.bin led.o
    avr-objcopy -O ihex -R .eeprom led.bin led.hex
    sudo avrdude -F -V -c arduino -p ATMEGA328P -P /dev/ttyACM0 -b 115200 -U flash:w:led.hex

因此,当我在我的Arduino板上闪烁上述代码时,连接到管脚13的LED闪烁,即使首先调用了函数blinkPin7().我注意到,函数的执行顺序始终对应于在main()外部定义函数的顺序,而不是从main()内部调用函数的顺序.

为甚麽会这样呢?

推荐答案

您的代码没有任何错误.但是你的Makefile不正确.

avr-gcc -o led.bin led.o

它在链接阶段不会超过-mmcu=atmega328p.在没有此选项的情况下,您应该会得到如下的ID错误:

avr:103 architecture of input file `led.o' is incompatible with avr output

这意味着你没有目标MCU.使用正确的链接器脚本,main()从地址0(重置向量)开始,一切都将正常工作.但是使用错误的链接器脚本,现在最先出现的任何函数都将位于地址0,并将按照您所观察到的开始执行.

添加目标mcu可以解决问题:

     avr-gcc -o led.bin led.o -mmcu=atmega328p

C++相关问答推荐

减法运算结果的平方的最快方法?

如何跨平台处理UTF-16字符串?

为什么该函数不将参数值保存到数据 struct 中?

轮询libusb_pollfd struct 列表的正确方式是什么?

如何使用C for Linux和Windows的标准输入与gdb/mi进行通信?

平均程序编译,但结果不好

如何在STM8项目中导入STM8S/A标准外设库(ST VisualDeveloper)?

关于";*(++p)->;t";、&++p->;t";和&q;++*p->;t";的问题

如何在VS 2022中正确安装额外的C头文件

C语言中的数字指针

C语言中浮点数的取整方式浮点数尾数超过23位时如何取整剩余部分

将 struct 数组写入二进制文件时发生Valgrind错误

宏观;S C调深度

浮动目标文件,数据段

为什么argc和argv即使在主函数之外也能工作?

std::malloc/calloc/realloc/free 与纯 C 的 malloc/calloc/realloc/free 有什么不同

使用复合文字数组初始化的指针数组

文件指针引起的C程序分段错误

如何确定 C 程序中的可用堆内存

使用 SDL2 的 C 程序中的内存泄漏