一.执行安装程序
二.生成链接用的库文件
$(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:\AVRGCC\bin;%path%
doskey
:install
if %1!==! GOTO end
rem install libc
cd f:\AVRGCC\lib\avr-libc-20010701\SRC
rem first win32_make_dirs will make some errors(I don’t 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 off
if NOT %AVR%!==! goto install
rem set environment variables
set AVR=f:\AVRGCC
set CC=avr-gcc
rem set PATH=.;f:\AVRGCC\bin;%path%
doskey
:install
rem if %1!==! GOTO end
rem install libc
cd f:\AVRGCC\lib\avr-libc-20010701\src
rem first win32_make_dirs will make some errors(I don’t know why?)
f:\AVRGCC\bin\make -f makefile-win32 win32_make_dirs
f:\AVRGCC\bin\make -f makefile-win32
f:\AVRGCC\bin\make -f makefile-win32 install
f:\AVRGCC\bin\make -f makefile-win32 clean
:end
f:
cd f:\AVRGCC
mode con: lines=43
在以后的应用中,运行的是修改之前的RUN.BAT,但要去掉rem if %1!==! GOTO end
的“rem”。去掉“rem”之后,后续的语句将被跳过。因此MAKE部分的“f:\AVRGCC\bin\”可加可不加。
编译和链接应用程序
首先在 www.pICavr.com 上下载测试程序集gcctest.zip,然后安装。
1. 将GCCTEST\INCLUDE下的MAKE1、MAKE2拷贝到$(AVR)\ INCLUDE
2. 将工作目录的MAKEFILE
(每个工程都要有一个此文件,且可由自己进行修改以适合自己的应用。如果要利用原有文件,则注意只能有一个C文件)中的MCU、TRG、SRC、ASRC、INC、LIB等项填入合适的内容
3.
在工作目录运行位于$(AVR)\BIN下的MAKE.EXE(注意:由于系统可能存在其他应用程序的MAKE,因此可能还需要加路径。也可以将其改名。)
4. 从MAKE1、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)
4. Clobber寄存器
嵌入汇编的通用格式为:
asm(code : output 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 volatile(“cli” : ;
二.汇编代码
用户可以在C代码里嵌入任意的汇编指令,就如同在汇编器里写程序一样。AVR-GCC提供了一些特殊的寄存器名称:
符号寄存器
__SREG__状态寄存器SREG(0x3F)
__SP_H__堆栈指针高字节(0x3E)
__SP_L__堆栈指针低字节(0x3D)
__tmp_reg__r0
__zero_reg__r1。对于C代码而言其值永远为0
三.输入/输出操作数
约束符号适用于范围
a r16~r23
b指针Y,Z
d r16~r31
e指针X,Y,Z
G浮点常数0.0
I6比特正常数0~63
J6比特负常数-63~0
l r0~r15
M8比特正常数0~255
N整数常数-1
O整数常数8,16,24
P整数常数1
r r0~r31
t R0
W寄存器对r24,r26,r28,r30
X指针Xr27:r26
Y指针Yr29:r28
Z指针Zr31:r30
要注意的是,在使用这些约束符号时要防止选择错误。例如,用户选择了”r”约束符号,而汇编语句则使用了”ori”。编译器可以在r0~r31之间任意选择寄存器。若选择了r2~r15,则会由于不适用ori而出现编译错误。此时正确的约束符应该是”d”。
约束符号还可以有前置修饰符,如下表所示。
修饰符指定
=只写操作数
+读-写操作数(嵌入汇编不支持)
&寄存器只能用做输出
输出操作数必须为只写操作数,C表达式结果必须为l(r0~r15)。编译器不检查汇编指令中的变量类型是否合适。
输入操作数为只读。如果输入/输出使用同一个寄存器怎么办呢?此时可以在输入操作数的约束字符里使用一个一位数字来达到这个目的。这个数字告诉编译器使用与第n个(从0开始计数)操作数相同的寄存器。例如:
asm volatile(“SWAP %0” : “=r”(value) : “0”(value));
这条语句的目的是交换变量value的高低4位。约束符号“0”告诉编译器使用与第一个操作数相同的寄存器作为输入寄存器。要注意的是,即使用户没有指定,编译器也有可能使用相同的寄存器作为输入/输出。在某些情况下会引发严重的问题。如果用户需要区分输入/输出寄存器,则必须为输出操作数增加修饰符”&”。如下例所示。 |