原文标题:作者:译者:日期:地址:

Program Arduino with AVR-GCC
Javier Valcarce
gashero
2013-09-16
http://www.javiervalcarce.eu/wiki/Program_Arduino_with_AVR-GCC

本文展示如何在Arduino IDE以外使用AVR-GCC给Arduino写程序,包括烧写引导器和设置熔丝。

译者注:Arduino给新手提供了很大便利,但是稍微深入的应用,如定时器和详细硬件控制就很麻烦了。可同时Arduino的硬件做的是很不错的。所以本文以使用Arduino的硬件,但不使用Arduino的软件为主要目的。

目录

  • 1   闪耀LED例子
  • 2   编译和上传
    • 2.1   通过Bootloader上传
    • 2.2   不通过Bootloader,而是用并口编程器
    • 2.3   不通过Bootloader,而是用AVR ISP MK-II编程器
  • 3   注意
  • 4   使用ICSP烧写Bootloader
    • 4.1   什么是Bootloader
    • 4.2   读取熔丝位
    • 4.3   写入熔丝位
  • 5   译者补充

Arduino是IDE和硬件平台,IDE以Java编写,并使用Processing语言。

这对新手是个好主意,因为简化了开发,但是也比C要弱:

  1. C有准确的执行时间,没有隐藏代码,写什么就执行什么
  2. C更容易访问硬件和中断
  3. 便于在多种MCU之间移植

本文编译和上传一个简单的纯C程序(使用avr-libc),而不用Arduino IDE。只需要终端、文本编辑器、AVR-GCC工具链。

1   闪耀LED例子

从让Arduino引脚13的LED闪耀开始(实际是闪耀PORTB的所有位)。创建个文件夹来存放项目,并创建文件 blink.c

#include <avr/io.h>
#include <util/delay.h>int main(void) {unsigned char counter;DDRB=0xff;      //设置PORTB输出while(1) {PORTB=0xff; //设置PORTB为高counter=0;while(counter!=50) {_delay_loop_2(30000);counter++;}PORTB=0x00;counter=0;while(counter!=50) {_delay_loop_2(30000);counter++;}}return 1;
}

2   编译和上传

将Arduino连接到USB口之后,Linux-2.6会自动载入FTDI驱动 ftdi_sio.ko

$ dmesg
...
usb 3-2: FTDI USB Serial Device converter now attached to ttyUSB0
usbcore: registered new interface driver ftdi_sio
drivers/usb/serial/ftdi_sio.c: v1.4.3:USB FTDI Serial Converters Driver

工具链(编译器/连接器/汇编器、标准C库和编程工具)包含在三个包中:

$ apt-get install gcc-avr avr-libc avrdude

C库的手册在 /usr/share/doc/avr-libc/avr-libc-user-manual/index.html 。

建议仔细看看 file:///usr/share/doc/avr-libc/avr-libc-user-manual/group__demo__project.html 。其末尾有个Makefile,可供定制到自己所需。改变程序名到 blink 并编译:

$ make

这会生成 blink.hex ,也就是要上传的镜像。有两种凡是可供上传到Arduino:

  1. ICSP(In-Circuit Serial Programming)
  2. 使用Bootloader,消耗2KB的程序存储器

第二个选项并不严格要求。实际上,第一个选项也并没有绝对优势。除非你只需要一个USB线,而不是两个。

2.1   通过Bootloader上传

此时AVR程序存储器已经包含了Bootloader,烧写 blink.hex 。确保熔丝的BOOTRST=0,如果不是,Bootloader在复位后不会启动。

$ avrdude -p m168 -P /dev/ttyUSB0 -c stk500v1 -b 19200 -F -u -U flash:w:blink.hex

2.2   不通过Bootloader,而是用并口编程器

如果不用Bootloader,直接烧写blink.hex,通过并口编程器。要确保熔丝的BOOTRST=1,如果不是,程序在复位后不会执行(后面章节会解释如何设置熔丝):

$ avrdude -p m168 -P /dev/parport0 -c dapa -b 115000 -F -u -U flash:w:blink.hex

如果你使用ATmega8则用 -p m8 。

2.3   不通过Bootloader,而是用AVR ISP MK-II编程器

要使用这种方法,你需要一个mkII编程器(约30欧元),并连接到Arduino,通过ICSP连接器。在AVR Studio IDE,通过 [Tool]=>[Program AVR]=>[Connect ...] 来选择AVR ISP mkII编程器,USB连接,并选择Flash镜像,最后点击 [Program] 按钮。

3   注意

  1. 使用的引脚号与Arduino的定义不同

  2. 要使用AVR-GCC的术语访问端口和其他硬件,参考datasheet的SFR(特殊功能寄存器),一些ATmega8的不同于ATmega168/328p

  3. 如果你使用其他零件(ATmega8、ATmega168、ATmega328等),注意修改Makefile的MCU变量

  4. 最近Arduino转到ATmega328了,兼容ATmega168,但有更多程序空间,而avr-libc@2009-01-01并不支持ATmeag328,编程工具的串口也不工作:

    #define BAUD 19200
    #include <util/setbaud.h>UBRR0H = UBRRH_VALUE;UBRR0L = UBRRL_VALUE;
    #if USE_2XUCSR0A |= (1<<U2X0);
    #elseUCSR0A &= ~(1<<U2X0);
    #endif
    

你应该替换为:

#define BAUD_RATE 19200
UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
UBRR0H = (F_CPU/(BAUD_RATE*16L)-1)>>8;
UCSR0B = (1<<RXEN0) | (1<<TXEN0);
UCSR0C = (1<<UCSZ00) | (1<<UCSZ01);

启用内部上拉电阻,在D0(RX),来降低线路噪声:

DDRD &= ~_BV(PIND0);
PORTD |= _BV(PIND0);

4   使用ICSP烧写Bootloader

本节针对你的设备是空的,没有Bootloader。已经有Arduino Bootloader的可以直接跳过不看。一个简单的检查是否有Bootloader的方法是复位后PIN13的等会闪3次。

4.1   什么是Bootloader

Bootloader是一种在特定存储区域的程序(bootloader区),其基本任务是接收新的固件,并存储到AVR的Flash存储器(程序存储器)。每个Bootloader都是针对特定设备的,使用特殊的协议。所有这些配置参数必须与主机编程器匹配(avrdude)。avrdude可以用多种类型的协议,支持多种连接(串口、并口、USB、...)。

一个例子是ATmega168在16MHz,stk500v1协议,19200-8N1串口的Bootloader:http://www.javiervalcarce.eu/pub/avr/ATmegaBOOT_168_ng.hex 。

按照如下步骤来烧写到AVR设备。更换其他操作系统,如Windows就是将 /dev/parport0 替换为LPT1,并安装giveio.sys即可。

  1. (解释如何编译Bootloader,而不是提供预编译的)

  2. 连接到并口编程器dapa和ICSP,然后供电:

    $ # write the following fuse bits: efuse=0x00, hfuse=0xdd, lfuse=0xff
    $ # write the following fuse bits: lock=0x3f (unlock boot section)
    $ avrdude -c dapa -p m168 -P /dev/parport0 115000 -U flash:w:ATmegaBOOT_168_ng.hex
    $ # write the following fuse bits: lock=0x0f (lock boot section)
    

在烧写镜像之前,先把熔丝设置成:使用外部晶振、禁用时钟分频、最大化Bootloader段等。然后烧写ATmegaBOOT_168_ng.hex到AVR。对于熔丝位,参考手册。

要访问并口,必须在 lp 组,修改 /etc/group 并退出会话来让改变生效。

4.2   读取熔丝位

$ avrdude -c dapa -p m168 -P /dev/parport0 115000 -U efuse:r:-:h #read efuse
$ avrdude -c dapa -p m168 -P /dev/parport0 115000 -U hfuse:r:-:h #read hfuse
$ avrdude -c dapa -p m168 -P /dev/parport0 115000 -U lfuse:r:-:h #read lfuse
$ avrdude -c dapa -p m168 -P /dev/parport0 115000 -U signature:r:-:h #读取设备签名

最后一个命令仅用于确认数据线正确连接。ATmega168的签名是0x1e, 0x94, 0x06。

4.3   写入熔丝位

$ avrdude -c dapa -p m168 -P /dev/parport0 115000 -U efuse:w:0xff:m #写0xff到efuse
$ avrdude -c dapa -p m168 -P /dev/parport0 115000 -U hfuse:w:0xff:m #写0xff到hfuse
$ avrdude -c dapa -p m168 -P /dev/parport0 115000 -U lfuse:w:0xff:m #写0xff到lfuse

5   译者补充

  1. 对于较新的Arduino,常用的芯片ATmega328P对应的器件名字叫"atmega328p"

  2. avrdude烧写时的编程器为"arduino",波特率为57600,即完整命令:

    avrdude -c arduino -p atmega328p -P /dev/tty.SLAB_USBtoUART -b 57600 -F -u -U flash:xxx.he

使用AVR-GCC编程Arduino相关推荐

  1. avr-gcc与avr单片机c语言开发 pdf,AVR 单片机与GCC 编程使用方法

    原标题:AVR 单片机与GCC 编程使用方法 WIN 是一个ATMEL AVR 系列 的开发工具集,它包含GNU C 和C++编译器 . 1.1 一个简单的例子 为了先有一个感性的认识,我们首先看一下 ...

  2. 利用PROGISP实现ARDUINO IDE编写的程序的下载以及如何把AVR单片机做成ARDUINO板

    首先讲讲题目的由来吧.我做的东西原本是利用ARDUINO MEGA2560及各种模块搭建起来的,程序自然也是用ARDUINO IDE写的.但这种东拼西凑的产品自然不够好,更主要的是,之前ARDUINO ...

  3. 自制AVR高压编程器,解锁熔丝位错误的avr单片机

    自制AVR高压编程器,解锁熔丝位错误的avr单片机 这段时间在用atmel的系列单片机at90usb128x/64x和atmega32u4设计键盘,有一块at90的单片机由于熔丝位设置错误被锁死,导致 ...

  4. AVR 单片机与GCC 编程之存储器操作

    AVR 系列单片机内部有三种类型的被独立编址的存储器,它们分别为:Flash 程序存储器.内部SRAM 数据存储器和EEPROM 数据存储器. Flash 存储器为1K-128K 字节,支持并行编程和 ...

  5. Ubuntu 16.04使用电路板绘制Fritzing和单片机编程Arduino说明

    Ubuntu下有很多非常赞的开源软件,将在后续持续介绍,这里简单介绍Fritzing和Arduino,都可以在官网免费下载. Fritzing:http://fritzing.org/home/ Ar ...

  6. gcc编程4步编译、调试c程序实操详解(Linux系统编程)

    gcc编译可以执行程序4步骤:预处理.编译.汇编.链接 一.知识储备(想看实战往下翻) 在linux程序种,c程序需要用gcc进行编译,链接用ld程序,ggc编译完成后可自动调用ld程序完成链接. 调 ...

  7. 使用Arduino ISP编程AVR微控制器和Arduino开发板

    所有微控制器都需要某种机制来对它们进行编程,即使它们只编程一次.通常,程序代码写在主机上,然后编译或翻译,并使用电缆(通常是USB或RS232)将对象(机器可读)代码从PC("主机" ...

  8. arduino语言c,Arduino编程基础(二)——C\C++语言基础(上)

    基础篇 本章开始,将由浅入深,详细介绍开发Arduino Uno所需的基础知识与开发方法. Arduino语言 Arduino使用C/C++编写程序,虽然C++兼容C语言,但这是两种语言,C语言是一种 ...

  9. arduino语言是c语言吗,Arduino编程基础(一)——Arduino语言

    Arduino语言 Arduino使用C/C++编写程序,虽然C++兼容C语言,但这是两种语言,C语言是一种面向过程的编程语言,C++是一种面向对象的编程语言.早期的Arduino核心库使用C语言编写 ...

  10. 利用AVR单片机 专用下载 USBtinyISP对Arduino UNO下载程序

    简 介: 测试了利用USBtinyISP对于Arduino UNO,也就是ATmega系列的单片机下载Bootloader的过程.通过测试可以看到,利用USBtinyISP可以更快的下载ATmega系 ...

最新文章

  1. 使用现代C++如何避免bugs(下)
  2. 3.6 BatchNorm 为什么起作用-深度学习第二课《改善深层神经网络》-Stanford吴恩达教授
  3. Scikit-learn数据预处理分类变量编码之标签二值化
  4. asp.net拦截器
  5. Leet Code OJ 2. Add Two Numbers [Difficulty: Medium]
  6. linux之LAMP架构搭建
  7. java clone方法_Java Calendar clone()方法与示例
  8. kotlin将对象转换为map_Kotlin程序将哈希映射(HashMap)转换为列表(List)
  9. C语言缓冲文件系统和非缓冲文件系统
  10. 每一次结束只是一次新的起点,深有体会。
  11. matlab2016限制内存,matlab
  12. 新浪动作挺快,开始再博客投广告了
  13. 论文阅读汇总(4)-【篇数:50】
  14. “函数...已有主体”问题解决
  15. SVN版本控制—branches、trunk、tag篇
  16. spring用到的设计模式
  17. LINUX防御ssh远程暴力破解
  18. 数字信号处理(七)FIR数字滤波器的设计
  19. 电力电子转战数字IC20220727day57——寄存器模型(续)
  20. 2023上海大学计算机考研信息汇总

热门文章

  1. priority_queue的优先级设置
  2. e盾网络验证源码_趣味设计模式系列:代理模式JDK动态代理源码解析,一文便知
  3. 计算机应用水平excel考什么,全国专业技术人员计算机应用能力考试EXCEL2003中文字处理全真模拟试卷(三)...
  4. c++ 文件操作方式
  5. linux下默认分区system的id,Linux学习笔记之系统中的分区和文件系统
  6. java数据集合总结_java集合总结 - 雷开你的门的个人空间 - OSCHINA - 中文开源技术交流社区...
  7. python实现概率论与数理统计_【总目录】——概率论与数理统计及Python实现
  8. C语言-用指针实现内存动态分配
  9. GitHub 实现了子资源完整性(SRI)
  10. struts 2.3.8备忘