使用AVR-GCC编程Arduino

发布者:数据探险家最新更新时间:2020-04-25 来源: eefocus关键字:AVR-GCC  编程  Arduino 手机看文章 扫描二维码
随时随地手机看文章

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


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


C有准确的执行时间,没有隐藏代码,写什么就执行什么

C更容易访问硬件和中断

便于在多种MCU之间移植

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


1   闪耀LED例子

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


#include

#include


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:


ICSP(In-Circuit Serial Programming)

使用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   注意

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


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


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


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


#define BAUD 19200

#include

    UBRR0H = UBRRH_VALUE;

    UBRR0L = UBRRL_VALUE;

#if USE_2X

    UCSR0A |= (1<#else

    UCSR0A &= ~(1<#endif

你应该替换为:


#define BAUD_RATE 19200

UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);

UBRR0H = (F_CPU/(BAUD_RATE*16L)-1)>>8;

UCSR0B = (1<UCSR0C = (1<启用内部上拉电阻,在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即可。


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


连接到并口编程器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   译者补充

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


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


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


关键字:AVR-GCC  编程  Arduino 引用地址:使用AVR-GCC编程Arduino

上一篇:Atmel Studio 6.1 delay函数错误的解决方法
下一篇:Atmel Studio 7新建AVR单片机工程

推荐阅读最新更新时间:2024-11-18 13:39

T0和T1可编程选择为定时功能与计数功能,二者有什么不同?
T0或T1用做计数器时,分别对从芯片引脚T0(P3.4)或T1(P3.5)上输入的脉冲进行计数,外部脉冲的下降沿将触发计数,没输入一个脉冲,加法计数器加1。计数器对外部输入信号的占空比没有特别的限制,但必须保证输入的高电平与低电平的持续时间都在一个机器周期以上。 用做定时器时,对内部机器周期脉冲进行计数,由于机器周期是固定值,故计数值确定时,定时时间也随之确定。如果51单片机系统采用12MHz晶振,则计数周期为:T=12x1/(12x10^6)=1us,这是最短的定时周期。适当选择定时器的初值可获取各种定时时间。 参考资料: (1)王静霞等. 单片机应用计数(C语言版)第3版 . 北京,电子工业出版社,2015:161.
[单片机]
用单片机实现SRAM工艺FPGA的加密应用
在现代电子系统设计中,由于可编程逻辑器件的卓越性能、灵活方便的可升级特性,而得到了广泛的应用。由于大规模高密度可编程逻辑器件多采用SRAM工艺,要求每次上电,对FPGA器件进行重配置,这就使得可以通过监视配置的位数据流,进行克隆设计。因此,在关键、核心设备中,必须采用加密技术保护设计者的知识产权。 1 基于SRAM工艺FPGA的保密性问题 通常,采用SRAM工艺的FPGA芯片的的配置方法主要有三种:由计算机通过下载电缆配置、用专用配置芯片(如Altera公司的EPCX系列芯片)配置、采用存储器加微控制器的方法配置。第一种方法适合调试设计时要用,第二种和第三种在实际产品中使用较多。第二种方法的优点在于外围电路非常简单,体积较
[单片机]
1.9.10_ADC和触摸屏_较准与画线编程_P
上一节得到了触摸屏和LCD坐标关于x轴和y轴的转换公式,其中主要是获取两个长度比例Kx和Ky,以及中心点E的坐标,这节编程实现按下触摸屏,在对应的LCD上画点画线的功能。 Kx = (s1 + s2) / (s1’ + s2’) Ky = (d1 + d2) / (d1’ + d2’) 写程序: 在A点显示 + (fb_disp_cross(int x, int y, int color)); 用户点击 + ; 记录触摸屏坐标(ts_read_raw()); 在BCDE上循环1-3步(显示,点击,读取); 根据获得的数据确定公式(ts_calibrate()); 以后得到TS触点时,转换出LCD坐标(ts_read());
[单片机]
1.9.10_ADC和触摸屏_较准与画线<font color='red'>编程</font>_P
51单片机编程:双路计数器详解
利用 51 单片机构成计数器,计数的上限,做的大一些,也不难,几千几万都可以。 下面的电路,小了一点,是个两路两位的计数器。 用来记录乒乓球比赛,还算可以,用于篮球比赛,分数超过 99,这个电路就不够用了。 电路图中,用的是共阳数码管;还设置了六个按键,用途,都已经标出。 用 C 语言编写驱动程序,是比较简单的,全部代码如下: #include《reg51.h》 unsigned char n1, n2; //----------------------------------------------- void delay(unsigned int i) //1ms延时程序 { unsigned char j; whil
[单片机]
51单片机 模块化编程
了解模块化编程 1.首先了解一下传统方式编程和模块化编程 传统方式编程:所有的函数均放在main.c里,若使用的模块比较多,则一个文件内会有很多的代码,不利于代码的组织和管理,而且很影响编程者的思路 模块化编程:把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其它.c文件想使用其中的代码时,只需要#include XXX.h 文件即可。使用模块化编程可极大的提高代码的可阅读性、可维护性、可移植性等 2. 模块化编程注意事项 .c文件:函数、变量的定义 .h文件:可被外部调用的函数、变量的声明 任何自定义的变量、函数在调用前必须有定义或声明(同一个.c) 使用到的自定义函数的.
[单片机]
51单片机 模块化<font color='red'>编程</font>
编程序:比较2个字符串是否相同(初级版)
DATAS SEGMENT source1 db 50 dup(?) ; 存放第一个串 source2 db 50 dup(?) ; 存放第二个串 title1 db 'Please input the first string:',0dh,0ah,'$' title2 db 'Please input the second string:',0dh,0ah,'$' ans db 'match',0dh,0ah,'$' ans1 db 'no match',0dh,0ah,'$'
[单片机]
12864液晶显示源程序汇编程
;12864液晶显示源程序全部程序如下: ;============================ COM EQU 20H LINE EQU 31H DAT EQU 21H COLUMN EQU 30H PAGE0 EQU 31H CODE0 EQU 32H COUNT EQU 33H CSA EQU P3.2 ;15 CSB EQU P3.4 ;16 D_I EQU P3.7 ;4 R_W EQU P3.6 ;5 E EQU P3.5 ;6 ;=======================================
[单片机]
高速数据流盘处理:编程与标定
概览 PXI Express正在改变着工程师们设计系统的方式。本文讨论了支持高速数据流处理的技术、最大化系统流处理性能的应用设计和在数据流导入磁盘与数据流导入存储器应用中可获得的数据速率基准。 引言 流处理是指以足够维持连续采集或信号生成的高速率将数据传输至仪器或从仪器输出。这就意味着任一项流处理应用的性能总是受限于数据的大小和传输速度。许多工程师利用了“流处理”技术,但是在很多应用中,数据无法以足够快的速率被生成或采集。在这些情况下,工程师们必须折衷处理,或者以足够低的采样率对要通过总线传输的数据进行采样,或者以所需的高速率进行采样但所持续时间较短(这个时间受限于仪器的板载存储器)。然而,无论哪一种的牺牲都不是
[嵌入式]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved