我正在尝试学习AVR C,并且正在修补atmega 328 p微控制器。我正在使用Linux Mint上的avr-gcc工具链来编译并将代码闪存到Arduino板上。
所以我试着用函数调用来 Flink 两个LED灯。我做了两个函数-一个是 Flink LED连接到引脚7,另一个是 Flink 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 Flink ,即使函数blinkPin7()
被首先调用。我注意到函数的执行顺序总是对应于函数在main()外部定义的顺序,而不是从main()内部调用它们的顺序。
为什么会这样呢?
1条答案
按热度按时间rxztt3cl1#
你的代码没有问题。但是你的Makefile不正确。
字符串
它不会在link stage中传递
-mmcu=atmega328p
。如果没有这个选项,你应该会得到这样的ld错误:型
这意味着你没有一个目标微处理器。使用正确的链接器脚本,main()从地址0开始(重置向量),一切都可以正常工作。但是使用错误的链接器脚本,没有添加启动代码和中断向量表,无论什么函数首先出现,现在都将在地址0,并将按照你观察到的开始执行。
添加目标mcu可以解决问题:
型