如何使用 avr-gcc

上传人:ldj****22 文档编号:46677822 上传时间:2018-06-27 格式:PDF 页数:21 大小:128.93KB
返回 下载 相关 举报
如何使用 avr-gcc_第1页
第1页 / 共21页
如何使用 avr-gcc_第2页
第2页 / 共21页
如何使用 avr-gcc_第3页
第3页 / 共21页
如何使用 avr-gcc_第4页
第4页 / 共21页
如何使用 avr-gcc_第5页
第5页 / 共21页
点击查看更多>>
资源描述

《如何使用 avr-gcc》由会员分享,可在线阅读,更多相关《如何使用 avr-gcc(21页珍藏版)》请在金锄头文库上搜索。

1、 如何使用如何使用 AVR-GCC 安装安装 GNU C for AVR 一执行安装程序一执行安装程序 二生成链接用的库文件二生成链接用的库文件 $(AVR)表示安装的根目录。 (在本人系统里为 f:avrgcc) 生成库文件关键是要运行位于$(AVR)下的 RUN.BAT。原程序如下: echo off if NOT %AVR%!=! goto install rem set environment variables set AVR=f:AVRGCC set CC=avr-gcc set PATH=.;f:AVRGCCbin;%path% doskey :install if %1!=!

2、GOTO end rem install libc cd f:AVRGCClibavr-libc-20010701src rem first win32_make_dirs will make some errors(I dont know why?) make -f makefile-win32 win32_make_dirs make -f makefile-win32 make -f makefile-win32 install make -f makefile-win32 clean :end f: cd f:AVRGCC mode con: lines=43 要修改为: echo o

3、ff if NOT %AVR%!=! goto install rem set environment variables set AVR=f:AVRGCC set CC=avr-gcc rem set PATH=.;f:AVRGCCbin;%path% doskey :install rem if %1!=! GOTO end rem install libc cd f:AVRGCClibavr-libc-20010701src rem first win32_make_dirs will make some errors(I dont know why?) f:AVRGCCbinmake

4、-f makefile-win32 win32_make_dirs f:AVRGCCbinmake -f makefile-win32 f:AVRGCCbinmake -f makefile-win32 install f:AVRGCCbinmake -f makefile-win32 clean :end f: cd f:AVRGCC mode con: lines=43 在以后的应用中,运行的是修改之前的 RUN.BAT,但要去掉 rem if %1!=! GOTO end 的“rem” 。去掉“rem”之后,后续的语句将被跳过。因此 MAKE 部分的“f:AVRGCCbin”可加可不加。

5、 编译和链接应用程序编译和链接应用程序 首先在上下载测试程序集 gcctest.zip,然后安装。 1 将 GCCTESTINCLUDE 下的 MAKE1、MAKE2 拷贝到$(AVR) INCLUDE 2 将工作目录的 MAKEFILE (每个工程都要有一个此文件, 且可由自己进行修改以适合自己的应用。如果要利用原有文件,则注意只能有一个 C 文件)中的 MCU、TRG、SRC、ASRC、INC、LIB 等项填入合适的内容 3 在工作目录运行位于$(AVR)BIN 下的 MAKE.EXE(注意:由于系统可能存在其他应用程序的 MAKE,因此可能还需要加路径。也可以将其改名。 ) 4 从 MA

6、KE1、MAKE2 和 MAKEFILE 可以看出,用户可以修改诸如输出文件名等多种选项。 在在 C 代码中嵌入汇编指令代码中嵌入汇编指令 一一GCC 的的 ASM 声明声明 首先看一个从 PORTD 读入数据的例子: asm(“in %0, %1” : “=r”(value) : “I”(PORTD) : ); 由上可以看出嵌入汇编的 4 个部分: 1汇编指令本身,以字符串“in %0, %1”表示; 2由逗号分隔的输出操作数,本例为“=r”(value) 3由逗号分隔的输入操作数,本例为“I”(PORTD) 4Clobber 寄存器 嵌入汇编的通用格式为: asm(code : outpu

7、t operand list : input operand list : clobber list); 例子中%0 表示第一个操作数,%1 表示第二个操作数。即: %0 ? “=r”(value) %1 ? “I”(PORTD) 如果在后续的 C 代码中没有使用到汇编代码中使用的变量,则优化编译时会将这些语句删除。为了防止这种情况的发生,需要加入 volatile 属性: asm volatile (“in %0, %1” : “=r”(value) : “I”(PORTD) : ); 嵌入汇编的的 Clobber 寄存器部分可以忽略, 而其他部分不能忽略, 但可以为空。如下例: asm v

8、olatile(“cli” : :); 二汇编代码二汇编代码 用户可以在 C 代码里嵌入任意的汇编指令,就如同在汇编器里写程序一样。AVR-GCC 提供了一些特殊的寄存器名称: 符号符号 寄存器寄存器 _SREG_ 状态寄存器 SREG(0x3F) _SP_H_ 堆栈指针高字节(0x3E) _SP_L_ 堆栈指针低字节(0x3D) _tmp_reg_ r0 _zero_reg_ r1。对于 C 代码而言其值永远为 0 三输入三输入/输出操作数输出操作数 约束符号约束符号 适用于适用于 范围范围 a r16r23 b 指针 Y,Z d r16r31 e 指针 X,Y,Z G 浮点常数 0.0 I

9、 6 比特正常数 063 J 6 比特负常数 -630 l r0r15 M 8 比特正常数 0255 N 整数常数 -1 O 整数常数 8,16,24 P 整数常数 1 r r0r31 t R0 W 寄存器对 r24,r26,r28,r30 X 指针 X r27:r26 Y 指针 Y r29:r28 Z 指针 Z r31:r30 要注意的是,在使用这些约束符号时要防止选择错误。例如,用户选择了”r”约束符号,而汇编语句则使用了”ori”。编译器可以在 r0r31 之间任意选择寄存器。若选择了 r2r15,则会由于不适用 ori 而出现编译错误。此时正确的约束符应该是”d”。 约束符号还可以有前

10、置修饰符,如下表所示。 修饰符修饰符 指定指定 = 只写操作数 + 读-写操作数(嵌入汇编不支持)这条语句的目的是交换变量 value 的高低 4 位。约束符号“0”告诉编译器使用与第一个操作数相同的寄存器作为输入寄存器。 要注意的是, 即使用户没有指定,编译器也有可能使用相同的寄存器作为输入/输出。在某些情况下会引发严重的问题。 如果用户需要区分输入/输出寄存器, 则必须为输出操作数增加修饰符” 此例的目的是读入端口数据,然后给端口写入另一个数据。若编译器不幸使用了同一个寄存器作为参数 input 和 output 存储位置,则第一条指令执行后 output 的内容就被破坏了。而用了修饰符”

11、 ld r24, %a0; inc r24; st %a0, r24; sei” : :”z”(ptr) :”r24” ) 编译结果为: CLI LD R24, Z INC R24 ST Z, R24 SEI 当然,用户也可以用_tmp_reg_来取代 r24。此时就没有 clobber 寄存器了。 下面为考虑更详细的例子: c_func uint_t s; asm volatile(“in %0, _SREG_; cli; ld, _tmp_reg_, %a1; inc _tmp_reg_; st %a1, _tmp_reg_; out _SREG_, %0” : “=r”(t) :”z”(

12、ptr) ); 现在看起来好象没问题了。其实不尽然。由于优化的原因,编译器不会更新 C代码里其他使用这个数值的寄存器。出于同样的优化原因,上述代码的输入寄存器可能保持的不是当前最新的数值。用户可以加入特殊的”memory” clobber 来强迫编译器及时更新所有的变量。 更好的方法是将一个指针声明为 volatile,如下所示: volatile uint8_t *ptr; 这样,一旦指针指向的变量发生变化,编译器就会重新加载最新的数值。 API 嵌入式编程的代码可以简单地分为两部分,一是与硬件无关的算法部分,对其编程与普通C编程没有区别; 二是与硬件相关的寄存器/端口操作部分。 不同的MC

13、U实现方法各有不同。在 AVR-GCC 里则通过一系列的 API 来解决。当然,用户也可以定义自己的 API。在此简单地介绍目前 AVR-GCC 里定义的 API,以及AVR-GCC 的工作过程。 一应用程序启动过程一应用程序启动过程(Start Up) 标准库文件包含一个启动模块(Start Up Module),用于为真正执行用户程序做环境设置。 启动模块完成的任务如下: 1. 提供缺省向量表 2. 提供缺省中断程序入口 3. 初始化全局变量 4. 初始化看门狗 5. 初始化寄存器 MCUCR 6. 初始化数据段 7. 将数据段.bss 的内容清零 8. 跳转到 main()。 (不用调用

14、方式,因为 main()不用返回) 启动模块包含缺省中断向量表,其内容为预先定义好的函数名称。这些函数名称可以由程序员重载。中断向量表的第一个内容为复位向量,执行结果是将程序跳转到_init_。在启动模块里,_init_表示的地址与_real_init_指向的地址相同。如果要加入客户代码,则需要在程序里定义一个_init_函数。在此函数的末尾跳转到_real_init_。具体实现如下: void _real_init_(void); void _init_(void) _attribute_(naked); void _init_(void) / 用户代码 / 最后的代码必须为: asm (“

15、rjmp _real_init_“); 在_real_init_部分,系统将设置看门狗和 MCUCR 寄存器。启动模块并没有真正取用相应寄存器的设置数值(以符号_init_wdctr_,_init_mcucr_,_init_emcucr_表示) ,而是通过地址来取得其值。因而用户可以通过链接器的-defsym 选项来设置这些符号的地址。如果用户没有定义,则启动模块将使用缺省值。 接下来系统将从程序存储器里把具有初值的全局变量加载到数据存储器 SRAM。然后是将数据段.bbs 清零。此数据段包含所有没有的初值的非 AUTO 变量。 最后,系统跳转到 main()函数,用户代码开始执行。系统对此特

16、殊函数加入一些特殊的处理。进入此函数后,堆栈指向 SRAM 的末尾。 二存储器二存储器 API AVR 具有三种存储器:FLASH,SRAM 和 EEPROM。AVR-GCC 将程序代码放在 FLASH,数据放在 SRAM。 I程序存储器程序存储器 如果要将数据(如常量,字符串,等等)放在 FLASH 里,用户需要指明数据类型_attribute_(progmem)。 为了方便使用, AVR-GCC 定义了一些更直观的符号,如下表所示。 类型类型 定义定义 prog_void void _attribute_(progmem) prog_char char _attribute_(progmem) prog_int int _

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号