Avr-GCC与Arduino技术的集成

8

如何在Ubuntu上使用C语言编程我的Arduino?我听说过avr-gcc,但所有在线教程都非常繁琐,并没有针对带有Arduino引导程序的AVR芯片的选项。有没有人可以帮助我更简单地安装avr-gcc并开始为Arduino使用C语言进行编程?


5
举个例子,如果有人不喜欢Arduino IDE因为它依赖Java,可能想要将项目集成到另一个构建系统(例如Make)中等等。有很多原因可以想做这件事情。 - The Paramagnetic Croissant
手动编写任何微控制器的代码非常困难,需要对平台有非常低级别的了解。这就是Arduino诞生的原因。那些非常了解这些知识的人编写库,使您能够利用本来需要多页低级别C代码(即使对于专业程序员来说也很痛苦)才能实现的功能,只需几行库调用即可。这就是Arduino的精髓。我认为如果放弃所有这些,只会让自己变得更糟。但如果这是您需要的,祝您好运。 - notadam
@adam10603,感谢您的建议,但是我确实想挑战自己,看看极低级别的开发到底是什么样子。同时也非常感谢您的快速回复。 - Application Developer
@adam10603,Arduino库实际上组织混乱且运行缓慢。如果您想要在MCU上进行任何非平凡的操作,您需要省略它们。大部分内容甚至不需要费力编写。是的,您需要阅读数据表,但无论如何都需要阅读文档。而AVR-GCC“标准库”已经提供了抽象(内置函数、宏、常量),您不必深入研究地址空间和位操作。 - The Paramagnetic Croissant
对于我使用Arduino的东西,Arduino库完全可以胜任。我也想用自己的C代码编程,但是查了一些资料后,我意识到这需要比使用Arduino IDE更多的努力,而且(至少对我来说)好处不大。如果你发现手动编写代码非常有益,那么当然可以尝试一下。但是,如果你想完全放弃Arduino库,我认为你也不需要引导程序。你应该直接通过SPI直接编程芯片。 - notadam
显示剩余5条评论
2个回答

18

我建议使用以下命令行选项进行编译:

avr-gcc -c
        -std=gnu99
        -Os
        -Wall
        -ffunction-sections -fdata-sections
        -mmcu=m328p
        -DF_CPU=16000000

而且用于链接:

avr-gcc -Os
        -mmcu=m328p
        -ffunction-sections -fdata-sections
        -Wl,--gc-sections

如何使用 AVR-GCC 编译代码:

  • -c 表示 "仅编译为目标文件,不链接"
  • -std=gnu99 表示 "我的代码符合 C99 标准并使用 GNU 扩展"
  • -Os 表示 "优化可执行文件大小而非代码速度"
  • -Wall 表示 "打开(几乎)所有警告"
  • -ffunction-sections -fdata-sections 是使用 -Wl,--gc-sections 优化的必要条件
  • -mmcu=m328p 表示 "MCU 的型号是 ATmega328P"
  • -DF_CPU=16000000 表示 "时钟频率为 16 MHz"(请根据实际时钟频率进行调整)
  • -Wl,--gc-sections 表示 "告诉链接器删除未使用的函数和数据部分"(这有助于减小代码大小)。

要实际编译代码,您需要首先使用 "仅编译标志" 发出 avr-gcc 命令,就像这样:

avr-gcc -c -std=gnu99 <etc.> MyProgram.c -o MyProgram.o

然后您需要为所有源文件重复此操作。最后,通过在链接模式下调用AVR-GCC来将生成的目标文件链接在一起:

avr-gcc -Os <etc.> MyProgram.o SomeUtility.o -o TheExecutable.elf

这将生成一个ELF文件,该文件不能直接由您的MCU执行。因此,您需要从中提取有用部分(原始机器代码)以Intel Hex格式:

avr-objcopy -O ihex -R .eeprom TheExecutable.elf TheExecutable.ihex

最后,您需要使用AVRdude将hex文件的内容上传到MCU:

avrdude -C /path/to/avrdude.conf
        -p m328p
        -c PROGRAMMER_NAME
        -b 19600
        -P PORT_NAME
        -U flash:w:TheExecutable.ihex:i

如何使用avrdude烧录单片机:

  • -C /path/to/avrdude.conf:表示“将该文件用作配置文件”
  • -c PROGRAMMER_NAME:表示“我正在使用类型为PROGRAMMER_NAME的编程器”(您需要根据实际情况自行填写)。
  • -b 19600:波特率(您可能需要根据设置的波特率或预先编程到引导加载程序中的波特率进行调整)
  • -P PORT_NAME:表示“编程器连接到PORT_NAME端口”。在Linux上,它通常是类似于/dev/ttyusbN(其中N是某个数字)的东西。
  • -U flash:w:TheExecutable.ihex:i:表示“将TheExecutable.ihex文件(Intel Hex格式)的内容写入Flash存储器”。

非常感谢。但是,我必须问一下在哪里下载和安装一个可用的avr-gcc版本。编译和链接有什么区别?此外,这个设置是否适用于预安装了Arduino引导程序的Atmega芯片? - Application Developer
@ApplicationDeveloper "在哪里下载和安装一个可用的avr-gcc版本" - 只需谷歌一下。"编译和链接有什么区别?" - 这是一个长篇故事,只需谷歌一下。"这个设置能与预装了Arduino引导程序的Atmega芯片一起使用吗?" - 是的。 - The Paramagnetic Croissant
谢谢你的一切。 - Application Developer

6

如果您只想在已安装引导加载程序的Arduino上使用C代码,那么您可以直接在Arduino IDE中以C语言编写代码并像平常一样进行编译。Sketch实际上就是一堆头文件和宏定义。

下面是用C语言编写的闪烁示例:

#include <avr/io.h> //defines pins, ports etc
#include<util/delay.h> //functions for wasting time

int main (void) {
//init
DDRB |= (1<<PB5); //Data Direction Register B:
//writing a 1 to the Pin B5 bit enables output
//Event loop
  while (1) {
    PORTB = 0b00100000; //turn on 5th LED bit/pin in PORT B (Pin13 in Arduino)
    _delay_ms (1000); //wait

    PORTB = 0b00000000; //turn off all bits/pins on PB    
    _delay_ms (1000); //wait
  } //end loop
  return(0); //end program. This never happens.
}

将此代码粘贴到集成开发环境(IDE)中并尝试。

如果你想从Arduino转向编程没有引导程序的AVR芯片,我建议你观看Elliot Williams的一段优秀的网络直播作为入门介绍。- https://www.youtube.com/watch?v=ERY7d7W-6nA

祝你好运并玩得开心 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接