|
第一章 AVR 单片机GCC 程序设计
WINAVR 是一个ATMEL AVR 系列单片机的开发工具集,它包含GNU C 和C++编译器GCC。
1.1 一个简单的例子
为了先有一个感性的认识,我们首先看一下如下一段程序和它的编译、链接过程。
文件demo1.c :
#include
int main( void )
{
unsigned char i, j, k,led=0;
DDRB=0xff;
while (1)
{
if(led)
PORTB|=0X01;
else
PORTB&=0XFE;
led=!led;
//延时
for (i=0; i<255; i++)
for(j=0; j<255;j++)
k++;
}
}
这是一个使接在PB0 口的LED 发光管闪烁的程序。有了源程序文件demo1.c,我们就可以编译它了。通过点击菜单开始->运行 在弹出的对话框中输入 “ command ” ,来打开控制台窗口,并在命令行输入:avr-gcc –mmcu=at90s2313 –c demo1.c
如图1-1 所示。
必需告诉编译器 程序的mcu 类型,这是我们通过命令行选项-mmcu 来指定的,我们指定的器件为at90s2313。-c 选项告诉编译器编译完成后不链接。
图1-1 控制台窗口
编译完成后在工作目录新生成了一个文件:demo1.o ,它是我们的目标文件,我们再使用链接器将它链接成可在器件上执行的二进制代码。
在命令行输入:avr-gcc –mmcu=at90s2313 –O demo1.elf demo1.o
之后我们会在工作目录看见链接器生成的demo1.elf。gcc 的链接后生成的文件为ELF 格式,在命令行我们通常用.elf 指定其扩展名。ELF 格式文件除了包含不同存储器的二进制格式内容外还包含一些调试信息,所以我们还要借助一个有用工具 avr-objcopy 来提取单片机程序存储器内容。命令行输入:avr-objcopy -j .text -j .data -O ihex demo1.elf demo1.hex
gcc 把不同类型的数据分到不同的段落,相关程序存储器的段有 .text 和 .data ,我们用选项 –j 指定了要提取的段。选项 –O 用来指定输出格式,这里我们指定为ihex (intel HEX file)。
到此我们得到了最终可以写入单片机90S2313 FLASH 存储器的demo1.hex 文件。用编程器将demo1.hex 内空写入到单片机,便可看到接在PB0 口的LED 不断的闪烁。以上对一次编译过程的描述只是为了说明gcc 编译一个C 源程序的步骤,在实际的应用中我们很少用这种方式编译每一个源程序和每一个更新后的程序。而是借助一个叫make 的项目管理工具来进行编译操作。Make 由下一节介绍。
1.2 用MAKEFILE 管理项目
在我看来,通常一个编译器(泛指高级语言编译器、汇编器、链接器等等)、项目管理器和文本编辑器构成一个完整的编程环境。
WINAVR 没有像Keil uVision 那样的集成IDE,所以我们需要写一个叫做makefile 的文件来管理程序的编译链接。makefile 是个脚本文件,一个标准的(应该说经典的)可执行文件make.exe 负责解析它并根据脚本内容来调用编译器、链接器或其它的工具。
1.2.1 make 的使用
make 能够自动记忆各源文件间的依赖关系,避免重复编译。
Make 指令用法是:
Make [-f filename] [names]
方括号表示括号里边的内容可以省略。其中filename 代表make 所使用的项目描述文件,如果此项省略,则从当前目录下按下列顺序寻找默认的项目描述文件
GNUmakefile.
makefile
Makefile (当然在WINDOWS 下不份大小写文件名,也就无所谓了)
names 指定目标名或宏名。若不指定目标名,则make 命令总是把在makefile 文件中遇到的第一个目标当作默认目标。
1.2.2 Makefile 项目描述文件
一.目标
make 命令引入了目标(targets)的概念。Makefile 描述文件便是它的第一个目标,make 命令必须处理至少一个目标,否则不会得出任何结果。正如我们在一个没有默认描述文件的当前目录下敲入make 一样,make 会输出以下的结果:
MAKE: ***No targets specified and no makefile found. Stop.
1.在项目描述文件中定义目标
一个目标通常从一行的开头开始,并后跟一个冒号。
最简单的MAKEFILE
#当前目录 D:\AVRGCC\TEST
all:
@echo hello!
#End makefile
all: 便是第一个目标
调用此描述文件结果:
D:\AVRGCC\TEST>make
hello!
2.默认目标(goal)
在上面提到过,如果调用make 时不指定目标名则make 总是假设在描述文件中遇到的第一个目标是默认目标。以下示例可以非常好的说明这一问题。
具有三个目标的makefile
#当前目录 D\AVRGCC\TEST
one:
@echo one.
Two:
@echo two.
Three:
@echo three.
#End makefile
调用1:
D:\AVRGCC\TEST>make
one.
由于在命令行没有指定目标,make 从makefile 中找到第一个目标(one)并执行后既退出。
调用2:
D:\AVRGCC\TEST>make two
two.
由于在命令行明确指定了要执行的目标(two),make 在makefile 中找到指定的目标,并执行后退出。
调用3:
D:\AVRGCC\TEST make three one two
three.
one.
two.
命令行指定了三个目标,make 一一寻找并执行。
在makefile 中非默认的目标称为可替换的目标,只有默认的目标与它们存在直接或间接的依赖关系时它们才有可能被调用。
二.依赖关系
makefile 文件按如下格式指定依赖关系:
目标1[目标2 … ] : [ : ][依赖1][依赖2] …
[命令]
如下例
#当前目录 D:\AVRGCC\TEST
one: Two
@echo one.
Two:
@echo two.
#End makefile
执行结果是:
d:\avrgcc\test>make
two.
one.
Make 首先找到第一个目标one ,之后发现目标one 依赖目标Two 就先执行Two 后才执行one 中的命令。
三.Makefile 内容
makefile 内容可分为如下五种类型
①规则定义
语法:
目标 : 依赖
命令
...
其中目标为一个文件名或以空格分开的多个文件名,可含通配符。
例如:
%.o : %.c
avr-gcc -c $< -o $@
以上规则定义了任意一个以 .o 结尾的文件依赖于相同前缀且以 .c 结尾的文件。并执行下边的命令获得。
规则中目标和依赖分别为 %.o 和%.c,在目标通配符 “%” 代表任意的字符串,而在依赖中代表与目标中代表的对应字符串。
②隐含规则
隐含规则是make 预先定义的规则,用选项 –r 可取消所有的隐含规则。
例如对于C 程序 %.o 可以自动的从 %.c 通过命令
$(CC) -c $(CPPFLAGS) $(CFLAGS)' 生成。
③变量
变量是在makefile 中描述一字符串的的名称。变量可用在目标、依赖、命令和makefile 其它部分中。变量名由除': '、'#'、'='之外的字符组成,对大小写敏感。
变量的定义并赋值格式:
变量名 = 变量代表字符串
变量的引用格式:
$(变量名)
例如:
CC = avr-gcc
%.o : %.c
$(CC) -c $< -o $@
④命令
命令部分是由make 传递到系统的字符格式的命令行的组合,在目标被创建时它们按顺序一行一行传递到系统并执行。
字符 '@'开始的命令 在系统的输出中不显示本次的指令行。
⑤注释
字符 '# ' 开头的行为注释行,如果注释需要换行需在行尾加 ' \ ',除包含其它MAKEFIEL 外在行的任意处可插入注释。
四.自动变量
在makefile 中有一组预定义的变量,当每一规则被执行时根据目标和依赖重新计算其值,叫作自动变量。
下面列出了常用的几个自动变量
$@ : 在规则中代表目标名,如果规则含有多个目标名它将列举所有目标。
$% : 仅在目标是存档文件的成员时起作用,代表目标。
如目标foo.a(bar.o)中$@ 代表foo.a $%代表bar.o
$< : 在规则中代表第一个依赖文件名
$? : 代表在规则中所有以空格隔开的依赖文件名,如果依赖是存档文件的成员则只有成员名被列出。
$^ : 代表在规则中所有以空格隔开的依赖文件名,如果依赖是存档文件的成员则只有成员名被列出。
WINAVR 提供一种简单makefile 生成工具叫mfile,如图1-2
利用它我们可方便的生成合适的makefile。
Main file name…菜单指定主程序文件,它将决定主源程序文件名及输出文件名。
Output format 菜单项用于选择最终生成的可指行代码格式,根据编程器支持格式选择即可。
Optimization leave 指定C 代码的优化级,s 代表按最小代码量编译。
C/C++ source file(s) 和Assembler source files(s) 用于在项目中添加其它C、C++、和汇编程序文件。
图1-2 mfile 生成makefile
通常我们选择了以上几项便可编译了。
AVR 单片机与GCC 编程----之一
http://bbs.huazhoucn.com/Temp/Temp3332_1.html
AVR 单片机与GCC 编程----之二
http://bbs.huazhoucn.com/Temp/Temp3333_1.html
AVR 单片机与GCC 编程----之三
http://bbs.huazhoucn.com/Temp/Temp3334_1.html
AVR 单片机与GCC 编程----之四
http://bbs.huazhoucn.com/Temp/Temp3335_1.html
AVR 单片机与GCC 编程----之五
http://bbs.huazhoucn.com/Temp/Temp3336_1.html
AVR 单片机与GCC 编程----之六
http://bbs.huazhoucn.com/Temp/Temp3337_1.html
AVR 单片机与GCC 编程----之七
http://bbs.huazhoucn.com/Temp/Temp3338_1.html
AVR 单片机与GCC 编程----之八
http://bbs.huazhoucn.com/Temp/Temp3339_1.html
|
|