- AVR单片机工程师是怎样炼成的
- 老杨 李鹏举编著
- 7628字
- 2020-08-28 09:54:57
第3章 宝刀屠龙:ICC AVR、AVR Studio
行走江湖,有时想拥有的不只一件兵器,有句话叫“倚天剑出,谁与争锋?武林至尊,宝刀屠龙”。我们要在单片机这个行业里发展,当然也不能只会一个工具,所以这里再为大家介绍两个工具:ICC AVR、AVR Studio。这两个工具就是AVR单片机编程中的屠龙宝刀。
3.1 编译工具介绍
有关AVR的C语言开发工具比较多,常用的有CVAVR(CodeVision AVR)、GCC AVR(GNU C for AVR)、IAR(IAR Embedded Workench)、ICC AVR(Imagecraft C Compiler for AVR)等。
CVAVR是HP Info Tech专门为AVR设计的一款C语言编译器,其界面比较友好,容易上手,并且带一个叫Codewizard的代码生成器,可以生成外围器件的相应初始化代码。该软件是收费产品,Demo版有2KB代码限制,可以通过其公司网站http://www.hpinfotech.ro下载。
GCC AVR是一款免费的C语言编译器,而且源代码是公开的。该软件本来是运行于Linux系统下的,后来由于其特别好用的缘故,就有“好事者”将其移植到Windows下,为Windows用户提供了一款免费的AVR单片机C语言编译器。不过其界面还有Linux编译器的风格,使用起来不是太容易上手。可以通过网站http://www.avrfreaks.net下载最新的GCC AVR软件。
IAR是IAR Systems公司开发的一款C语言编译器,该编译器不仅支持AVR单片机,而且支持众多的8位、16位、32位单片机。IAR Systems公司1983年成立,是全球领先的嵌入式系统开发工具提供商。据说在设计AVR单片机时,Atmel公司的设计人员是根据IAR编译器来优化AVR内部结构的,可见其在单片机编译器领域的地位,同时也可以说明其对AVR单片机的紧密结合性。该编译器的特点是编译环境功能比较强大,界面比较友好,代码执行速度快,价格昂贵,未注册软件有30天的试用期(另外一种Demo版有4KB代码限制),可以通过其网站http://www.iar.com下载。
ICC是ImageCraft公司开发的使用标准C语言的AVR单片机编译环境。其界面比较友好,并且带一个Application Wizard的代码生成器,也可以生成外围器件的初始化代码,因而很容易上手。不过该软件也是收费产品,未注册软件有45天(旧版本是30天)的试用期,可以从其网站http://www.imagecraft.com下载。
下面用一个表格的形式比较一下这4种AVR常用的C语言编译器,具体如表3-1所示。
表3-1 4种AVR常用C语言编译器比较
【建议】
● 初学者选择ICC或CVAVR,因为其界面比较友好,而且带有代码生成器,可以帮我们生成外围器件初始化代码。
● 入门后选择GCC,因为它是免费产品,虽然几乎没有技术支持,但因为其是自由软件,因而有大量的用户在使用,在网上可以找到很多的学习资料(Proteus有关AVR的例程就是基于GCC写的)。另外,GCC具有Linux软件风格,可以为我们进一步学习ARM-Linux开发做些准备工作。
● 商业用户,如果有条件可以选择IAR,它与AVR产品的紧密结合度可以保证其代码的优化程度、执行效率。
这里选择ICC作为AVR的C语言编译环境,因为其友好的开发界面和代码生成器,另外ICC国内的代理商是广州双龙公司,该公司也是AVR单片机的代理商,所以国内使用ICC的用户也相对较多,这样我们就可以更容易获取学习资料。
登录ICC的官方网站http://www.imagecraft.com会发现当前最新版是V8.0,不过国内用户使用更多的是V6.3.1版本,我们这里选择的是V7.22版。初学者最好选择相同版本的软件安装,这样可以减少在学习过程中遇到麻烦。
3.1.1 安装ICC AVR
软件的安装过程比较简单,我们抓几个主要界面作为安装提示。安装之前,如果操作系统运行有杀毒软件,最好先暂停其杀毒功能或退出运行。运行安装文件会看到安装程序的首界面,如图3-1所示。
接下来是安装目录的选择,默认是C:\iccv7avr\目录,如图3-2所示。最好按默认目录安装,因为根据网上介绍,ICC AVR对程序运行的路径支持并不是很好,所以最好不要使安装的目录太深,特别是不要包含中文目录。
单击“下一步”按钮,进入安装提示界面。在该界面单击“安装”按钮,直接进入文件安装的过程,安装完成后会给出提示界面,如图3-3所示。
到此就完成了ICC AVR编译环境的安装。下面运行ICC看看如何。
图3-1 ICC AVR安装首界面
图3-2 安装目录选择
图3-3 安装完成
3.1.2 运行ICC AVR
安装完成后桌面上会有“ICCV7 for AVR”的图标,双击该图标或选择菜单“开始”→“所有程序”→“ImageCraft Development Tools”→“ICCV7 for AVR”可以进入ICC AVR,“开始”菜单如图3-4所示。
图3-4 ICC AVR的“开始”菜单
启动ICC AVR的主界面,如图3-5所示。
如果手头有注册码,可以通过菜单“File”→“Register Software”完成软件的注册。如果不注册该软件也不会影响我们的学习使用,因为它有45天的试用期。
图3-5 ICC AVR主界面
完成了ICC AVR的安装过程,下面就可以使用它进行开发了。在学习开发之前我们先通过一个示例程序来简单了解一下ICC AVR的编译环境。
3.1.3 学用ICC AVR
1.打开工程
我们先打开一个实例工程,执行菜单命令“Project”→“Open…”打开选择工程界面,如图3-6所示。
找到ICC AVR的安装目录C:\iccv7avr\进入examples.avr目录,选择LED文件夹,进入该文件夹,有一个led.prj文件,选择该文件,如图3-7所示。
图3-6 选择工程界面
图3-7 选择LED例子工程
单击“打开”按钮,打开该工程,如图3-8所示。
2.打开led.c文件
在工程界面右侧的列表中有一个Project属性页,该属性页中有一个工程LED,下面有个文件夹,包含一个文件led.c,双击该文件,在左侧打开该文件,如图3-9所示。
先看一下代码文件led.c,最上面是引用的两个头文件io8515v.h和macros.h,引用这两个文件是什么用意呢?我们打开该文件看看。
图3-8 打开LED工程
图3-9 打开led.c文件
3.打开头文件io8515v.h
执行菜单命令“File”→“Open…”或单击工具栏上的“Open File…”按钮来打开这两个文件。在弹出的选择文档对话框中找到ICC AVR的安装目录C:\iccv7avr\,进入include目录,如图3-10所示。
图3-10 include目录
在include目录中可以看到很多以.h结尾的头文件,在其中找到io8515v.h,然后单击“打开”按钮打开该文件,如图3-11所示。
图3-11 io8515v.h文件
打开io8515v.h文件后,先看看该文件的目录C:\iccv7avr\include\,仔细观察可以发现led.c中引用的macros.h文件也在该目录。这个目录就是ICC AVR头文件所在的位置,我们写代码时用#include < >语句引用的头文件,系统都会自动到这里查找。
接下来简单分析一下io8515v.h的内容,首先看到的是一个C语言的宏定义语句:
#ifndef __io8515v_h #define __io8515v_h //文件内容 #endif
学习过C语言编程应该知道,这是为了防止该头文件被重复包含和编译。
接下来是一个注释行:
/* AT90s8515/4414 register and bit name ….*/ /* last changed 01-12-02 */
这是对文件的整体说明,告诉我们该文件是AT90s8515/4414寄存器和位定义的头文件,是针对ICC AVR编译环境的;后面一行是文件最后的修改时间信息。同时该注释也告诉我们,如果针对ATmega8/16编写程序,也要引用其对应的头文件。
再往下看就是该头文件的内容了,主要是用#define语句定义了一些宏定义,其实这也是我们在后面写程序中经常要用到的特殊功能寄存器的定义,有些类似学习51单片机时在Keil C51中看到的sfr、sbit的声明。
我们可以回头看看led.c文件(可以通过工具栏下的属性页来切换),找到main函数,该函数的前三行代码是:
int i; DDRB = 0xFF; /* output */ PORTB = 0xFF; /* all off */
注意观察,这里的DDRB、PORTB就是在头文件io8515v.h中定义的。
4.打开头文件macros.h
使用同样的方法可以打开macros.h文件,发现里面只有两行代码:
// Please use <AVRdef.h> in new code #include <AVRdef.h>
也就是说,该文件直接引用了AVRdef.h,这样我们就需要再打开AVRdef.h看看,如图3-12所示。
图3-12 AVRdef.h文件
观察该文件会发现,这里主要是用宏定义声明的一些常用的函数、汇编语句等。例如:
#ifndef BIT #define BIT(x) ( 1<< (x) ) #endif
该语句可以在led.c中找到对其的使用,在led.c的LED_On函数中有这样一句:
PORTB = ~BIT(i); /* low output to turn LED on */
BIT(i)就是对BIT(x)的调用,其中PORTB是在io8515v.h中声明的寄存器。将BIT(i)直接翻译一下,该语句变为:
PORTB = ~( 1 << (i) );
这样就容易理解了。
有关AVRdef.h中的其他内容,如#define WDR() asm("wdr"),我们在以后使用时再做说明。
比较以上两个头文件会发现,io8515v.h是针对AT90s8515/4414的,而macros.h也就是AVRdef.h,是AVR单片机通用的,因此我们后面会更多地接触macros.h文件。
5.分析led.c
看完两个引用的头文件,再回头看看led.c文件,我们对其简单地分析一下(如图3-13所示)。
图3-13 led.c文件
可以看到,该文件一共包含了三个函数:Delay、LED_On、main。我们先从主函数main开始分析,该函数是写嵌入式软件必有的函数,也是单片机程序运行的起始位置,因而在看程序时,通常都会从该函数着手。
首先是变量i的声明int i;然后是端口的初始化DDRB = 0xFF;PORTB = 0xFF;接下来是一个while(1)的循环语句。细心的读者会发现,这里使用的是一个死循环,也就是说程序运行到这里就再也跳不出来了,除非内部有break、goto等跳出语句。这也是嵌入式程序的一个特点,因为嵌入式程序大多是上电后自动运行,而且运行起来后就不再停止了,所以通常在main函数中都会在最后使用一个while(1)的语句。
while语句内部并没有什么内容,主要是对LED_On函数的调用,这样我们就进入LED_On函数内部看看该函数是做什么的。该函数包含了两个语句:
PORTB = ~BIT(i); Delay();
第一个语句在前面已经分析过,将BIT宏定义展开后就是:
PORTB = ~( 1 <<(i) );
也就是1左移i位后,取反。这样整个语句就是将寄存器PORTB的i位设置为0,其他位设置为1。
接下来是对Delay函数的调用,我们不去看该函数,从其名字分析就可以知道,该函数是一个延时函数。就像macros.h头文件内部是宏定义一样,这也告诉我们,以后写程序要有好的书写习惯,定义函数、文件名、变量时,尽可能定义有意义的名字,不要用字母a、b、c,x1、y2、z3等这样的字符简单组合来命名。
进入Delay函数内部看看会发现,其内部的确是由两个for语句组成的空操作,目的就是为了让单片机在这里做空操作,浪费其时间起到延时的作用。回到LED_On函数就容易理解了,也就是将PORTB寄存器的i位置为0后做一段时间的延时,这就是该函数的功能。
再回到主函数main的while语句进行分析,那就是通过不同的for循环方式对LED_On进行调用,也就是通过不同的循环方式对PORTB寄存器的位做置0操作。在最后我们会通过Proteus更直观地来看该函数操作的结果。
6.编译工程
分析完程序代码,下面就用ICC AVR编译该工程。可以通过执行菜单命令“Project”→“Rebuild All”或单击工具栏上的builed Project按钮来编译该工程。Rebuild All菜单如图3-14所示。
图3-14 Rebuild All菜单
编译结果可以在左侧源文件代码显示窗口的下方看到,如图3-15所示。如果看不到该窗口,可以通过菜单命令“View”→“Status Window”来打开该窗口。
图3-15 LED工程的编译结果
该结果中有两个警告信息:以“!W”开头的两个语句。我们可以简单地看看这两个语句,大概意思是Delay、main两个函数是旧的定义方式。另外,也可以双击警告行,上面的显示代码就会自动跳转到出现警告的下一行。
在这里说明一下,该警告是说Delay、main两个函数定义时用了比较旧的定义方式,也就是在定义空函数时没有说明参数是void。以前的函数定义对空函数没有具体的要求,因而大家写程序时比较随意,有时会不写或忘记写void参数,当时的编译器对此也没有要求,所以就会出现现在的问题。
找到了问题,我们修改一下两个函数的定义:
void Delay(void) void main(void)
然后再次编译该工程会发现,这次编译一个警告也没有了(如图3-16所示)。
图3-16 没有警告的编译结果
通过这个简单的修改使我们注意到,写程序要养成良好的编写习惯。否则产品就会像ICC AVR这样的商业软件提供的源代码一样,出现一些小小的警告信息,这些不起眼的警告信息多了,也许不知道什么时间就会影响产品的稳定性。
上面只是通过一个示例程序简单地介绍了一下ICC AVR的一些基本功能,通过后面章节的学习,我们会进一步了解ICC AVR的使用。例如,怎样新建一个工程、怎样编写一个C程序、如何配置工程等。下面为了能够仿真调试,还要讲解另外一个开发工具,那就是AVR Studio。
3.2 开发调试软件AVR Studio
AVR Studio是Atmel公司为AVR单片机开发的集成开发环境(IDE),包括AVR Assembler编译器、AVR Studio调试功能、AVR Prog串行、并行下载功能和JTAG ICE仿真等功能,而且该软件完全免费,非常实用。AVR Studio以前的版本(5.0以前)集成的是汇编编译器,因此大家喜欢安装一款我们前面介绍的C语言编译器来配合使用,不过现在Atmel公司推出了最新的5.0版,据说该版本是基于微软的VisualStudio 2010开发环境开发的,所以界面比较美观,用Atmel公司的话说,该软件直观、易用和高效。也有网友介绍,如果我们的计算机安装了VisualStudio 2010中文版,还能看到中文的界面,不过我本人认为只要安装对应的.net Framework和对应的简体中文语言包就可以了,不需要完全安装几GB大小的VS2010,我没有去验证,只是从技术理论上推断。另外,AVR Studio 5更大的优点是集成了GCC的C语言编译器,这样我们就可以直接在里面编写C语言代码、编译C语言程序了。所以推荐大家对AVR的开发流程熟悉之后使用AVR Studio集成开发环境,只是其缺点是安装文件比较大,现在发布版本的大小是602MB。
我这里选择的是AVR Studio 4.19版,这是Atmel公司发布的4.0版中的最新版,该版本集成了4.18及其补丁SP1、SP2和SP3,而且还集成了USB驱动程序。选择该版本是因为其文件比较小,只有124MB,我们仅仅用它来做调试、仿真,大家可以先熟悉一下4.19版,然后再换到5.0版。可以到Atmel公司的官网http://www.atmel.com下载,我下载到的版本是2011年9月发布的。
3.2.1 下载AVR Studio
Atmel公司曾经有一段时间是提供中文版官方网页的,但后来不知道什么原因老是打不开,现在我们只能使用英文版了。在其主页上就有Atmel AVR Studio 5的介绍,如果下载5.0版,可直接单击“Download Now”或AVR Studio 5的图片进入详细介绍页面。如果想下载AVR Studio 4.19就麻烦点,需要先通过主页菜单行前面的搜索框根据关键字搜索一下。
在Atmel的官网首页选择“Go to Keyword Search”(如图3-17所示),进入产品搜索界面,在关键字Keyword(s)栏中输入“studio”,后面的选项只选择Resources下的Tools项,如图3-18所示。
图3-17 Atmel官网首页
选择完成后,单击“Submit”按钮进入搜索结果显示界面,如图3-19所示。
这里的第3行就是AVR Studio 4,单击“AVR Studio 4”,进入其详细介绍页面,在其中找到AVR Studio 4.19的下载位置,如图3-20所示。
在图3-20所示界面中,单击带“Register”字样的光盘图标,进入一个Atmel公司要求填写一些注册信息的页面,在该页面可以根据自己的情况填写信息,其中最为重要的一项是自己的邮箱。提交填写信息后,系统会根据所提供的邮箱自动发送电子邮件,其中就有AVR Studio 4.19的下载链接。
图3-18 根据关键字搜索studio
图3-19 搜索结果
图3-20 AVR Studio 4.19
3.2.2 安装AVR Studio
下载完成后,双击AVR Studio 4.19的安装包进入安装程序流程,安装首页如图3-21所示。
图3-21 AVR Studio安装首页
在安装首页单击“Next”按钮,进入协议选择界面,安装包默认是“I do not accept the terms of the license agreement”,我们选择“I accept the terms of the license agreement”项,然后单击“Next”按钮进入下一步:安装路径选择界面。
在安装路径选择界面,默认是“C:\Program Files\Atmel\AVR Tools”,我的C盘资源比较紧张,因此修改了安装路径,如图3-22所示。读者可以根据自己的需要修改安装路径。
图3-22 修改安装路径
安装路径修改完成后,单击“Next”按钮,进入安装提示界面,如图3-23所示。
图3-23 安装提示界面
在安装提示界面,单击“Install”按钮,进入开发环境的安装流程,在安装到最后时会提示安装USB-drivers,如图3-24所示。
图3-24 提示安装USB-drivers
这时会弹出安装USB驱动的界面(其实USB驱动我们可以选择不安装,因为在仿真时并不会用到USB驱动),如图3-25所示。
图3-25 安装USB-drivers
安装USB驱动的过程和前面安装Studio的过程基本类似,先选择接受安装协议“I accept the terms of the license agreement”,然后单击“Next”按钮进入下一步。下一步是安装路径选择界面,因为是驱动程序,所以直接按默认路径安装,单击“Next”按钮进入下一步。
下一步是安装提示界面,直接单击“Install”按钮,进入安装USB驱动的过程。在安装的过程中会弹出一个DOS对话框,如图3-26所示。
图3-26 安装USB驱动到Windows目录
安装完成后,该DOS界面会自动消失,接下来USB驱动安装界面会提示USB驱动已经安装完成,如图3-27所示。
图3-27 USB驱动安装完成
在USB驱动安装完成界面单击“Finish”按钮,回到AVR Studio安装界面,稍等片刻,系统提示Studio安装完成,如图3-28所示。
图3-28 AVR Studio 4.19安装完成
3.2.3 使用AVR Studio
完成上面一系列的安装过程,下面就来使用AVR Studio集成开发环境。可以通过菜单“开始”→“所有程序”→“Atmel AVR Tools”→“AVR Studio 4”来运行Studio集成开发环境,如图3-29所示。
图3-29 Studio“开始”菜单
运行AVR Studio时会有一个启动界面,如图3-30所示。
图3-30 运行AVR Studio 4.19启动界面
第一次运行AVR Studio会有一个欢迎界面,这是用来让我们做工程选择的,在该界面可以新建一个工程,也可以打开一个原有的工程。这里将“Show dialog at startup”前面的“√”去掉,如图3-31所示,单击“Cancel”按钮进入主界面,如图3-32所示。
图3-31 AVR Studio 4.19欢迎界面
图3-32 AVR Studio 4.19主界面
第一次运行AVR Studio,界面上的列表都是空的,我们就先打开一个前面编译的文件来看看。执行菜单命令“File”→“Open File”打开选择文件对话框,如图3-33所示。
图3-33 Studio打开文件对话框
找到ICC AVR的安装目录,然后进入该目录,找到examples.avr文件夹,选择进入,再找到上一节用ICC AVR编译的LED工程所在的文件夹,进入后选择“LED.cof”,如图3-34所示。
图3-34 选择“LED.cof”文件
选择“LED.cof”文件,然后单击“打开”按钮打开该文件,AVR Studio会提示保存Studio的工程文件LED_cof.aps,按默认提示,单击“保存”按钮,进入AVR Studio的仿真器选择界面,如图3-35所示。
图3-35 仿真器选择界面
在仿真器选择界面,在“Debug platform”列表中选择“AVR Simulator”,进行软件仿真,在右侧的“Device”列表中选择ICC AVR例程使用的设备AT90S8515。最后单击“Finish”按钮,回到AVR Studio仿真主界面,如图3-36所示。
图3-36 AVR Studio仿真主界面
可以看到,仿真界面的左侧是“Processor”窗口,也就是CPU信息列表;右侧是“I/O View”窗口,也就是I/O端口信息,该窗口分上、下两部分;中间是代码显示窗口,我们看到程序仿真已经开始,目前是暂停状态,停在main函数的DDRB = 0xFF; 一行;下侧显示的是工程信息。
我们的示例程序重点修改的是PORTB的端口信息,因此这里重点要看的是PORTB的端口信息。在右侧的“I/O View”窗口选择“PORTB”,如图3-37所示。
图3-37 选择显示端口
然后在工具栏找到这几个最常用的按钮,单击Step Into(F11)按钮(也可以通过菜单命令“Debug”→“Step Into”完成此操作),进行单步调试。这时重点观察程序行运行了一行,而右侧的PB口信息也有所改变,如图3-38所示。
图3-38 DDRB信息修改
我们看到,PORTB有三个寄存器:DDRB、PINB、PORTB。而DDRB=0xFF语句运行之后,就改变了寄存器DDRB的值,可以在右侧的图表中清晰地看到。
再次单击Step Into按钮,执行下一条语句,可以看到执行过PORTB=0xFF语句之后,PINB、PORTB寄存器的值都被修改了,如图3-39所示。
图3-39 修改PINB、PORTB寄存器的值
接下来用工具栏上的Toggle Breakpoint按钮在第一个“LED_On(i)”行添加一个断点。添加的方法是,先用鼠标将光标转移到该行(在该行行首单击鼠标),然后单击“Toggle Breakpoint”按钮。接着让程序运行到断点处,可以用run(F5)按钮来完成,如图3-40所示。
图3-40 运行程序到断点处
然后再次使用Step Into按钮跟踪调试,看看LED_On函数内部的操作。进入LED_On函数之后,再按一次Step Into按钮,将光标停留在“PORTB=~BIT(i)”一行。这时我们要看看i的值,可以将鼠标停留在i上一会儿,会有一个浮动窗口显示i的值;也可以通过窗口来显示该值,执行菜单命令“View”→“Watch”打开“Watch”窗口,在“Watch”窗口的“name”列表中输入“i”并回车,就可以看到变量i的值了,如图3-41所示。
图3-41 使用“Watch”窗口
接下来看看“PORTB=~BIT(i)”这行语句执行的结果,使用工具栏上的Step Over(F10)按钮来完成该操作。执行完该操作会发现,光标停留在“Delay()”一行,而且PORTB的值发生了变化,如图3-42所示。
图3-42 观察PORTB寄存器的变化
接下来通过工具栏上的Step Out(Shift+F11)按钮跳出LED_On函数,程序会跳转回main函数。我们使用工具栏上的Remove all Program Breakpoints按钮将刚才添加的断点去掉,然后将光标设定在main函数的第二个LED_On语句上(在该行单击鼠标),再使用工具栏上的Run to Cursor按钮将程序直接运行到第二个LED_On语句处,此时变量i的值是8,DDRB、PINB、PORTB的状态如图3-43所示。
最后,可以单击Reset(Shift+F5)按钮让程序重新运行,也可以单击Stop Debugging(Ctrl+Shift+F5)按钮结束程序的仿真。
OK,有关AVR Studio集成开发环境就先了解这么多,其实还有一个功能我们还没有介绍,那就是将AVR Studio和Proteus结合起来做仿真调试。
图3-43 程序运行到第二个LED_On语句处
上面介绍的是在AVR Studio中进行软件仿真,只能通过寄存器的状态来看仿真结果,而通过Proteus可以更加直观地看到程序运行的结果,就像在电路板上做实验一样。由于篇幅的限制,本章有关工具的介绍就先讲到这里,关于AVR Studio和Proteus的结合仿真,我们会在下一章讲解单片机入门时演示。