应用笔记 4314

采用MAXQ610评估套件(EV kit)和IAR嵌入式工作台进行设计


摘要 : 应用笔记介绍怎样面向MAXQ610低功耗RISC微控制器开发、构建并调试应用程序。文章使用了IAR™系统提供的IAR Embedded Workbench®工具箱和C编译器。

引言

MAXQ610是Maxim Integrated提供的低功耗微控制器,设计用于电池供电的应用,提供低电流工作模式(1MHz时的典型值为1.4mA,12MHz时为3.5mA),以及低电流停止模式(典型值200nA)。微控制器还具有效率非常高的16位单周期RISC处理器核以及灵活的时钟配置,有助于动态控制性能和功耗。MAXQ610适合于需要大量I/O引脚以及对功耗要求比较高的应用。

MAXQ610具有很多重要的特性,包括:
  • 1.7V至3.6V的宽范围工作电压
  • 64KB应用程序(IAP)闪存
  • 2KB数据SRAM
  • SPI™和两个USART
  • 8kHz低功耗“异或”唤醒定时器
  • IR载频发生器和调制
  • 扰码功能可防止攻击者下载软件,提供IP保护
  • 存储器保护功能隔离了内核库,提供IP保护,防止第三方应用
MAXQ610评估套件(EV)为MAXQ610处理器开发低功耗应用提供成熟可靠的平台。套件包括IR发射器和接收器;两个串口;用于用户输入的8个按键;出于应用目的的4个LED;原型区;以及用于访问MAXQ610所有I/O引脚的插头等。此外,还提供跳线,可以方便地监监MAXQ610处理器在工作时的实际功耗。

设置MAXQ610评估套件

MAXQ610评估套件电路板如图1所示。评估套件含有下面的硬件元件,这些元件用于实现并验证本应用笔记中的演示程序:
  1. MAXQ610评估套件电路板
  2. JTAG电路板
  3. JTAG电缆(连接MAXQ610套件电路板和JTAG电路板)
  4. 9针串行电缆
  5. 稳压电源(5V,±5%,300mA,正极中心)
图1. MAXQ610评估套件
更详细的图
(PDF, 284kB)
图1. MAXQ610评估套件

MAXQ610评估套件电路板和JTAG电路板都有很多跳线需要进行配置。在本应用笔记中,应按照表1表2配置这些跳线。

表1. MAXQ610评估套件的电路板跳线配置
Jumper(s) State Purpose
JH1, JH2 Don't Care Control RS-232 level shifters FORCEON and active-low FORCEOFF inputs
JH3, JH4 Don't Care Configure RS-232 transmitter inputs
JH20, JH21 Don't Care Connect RS-232 receiver outputs to MAXQ610 signals
JH18 Don't Care Connect RS-232 active-low INVALID input to MAXQ610 control pin
JH5 Connect Pins 1 (Square Pad) and 2 Connects regulated voltage to MAXQ610 supply
JH22, JH23, JH24, JH25 Closed Connects MAXQ610 port pins to LEDs
JH15, JH16, JH17 Don't Care Connect IR circuitry to MAXQ610 pins
JH26 Closed Uses power from JTAG connection to power the MAXQ610 board
JH14 Closed Connects board power to MAXQ610

表2. JTAG电路板跳线配置
Jumper(s) State Purpose
JH1, JH2 Don't Care External DTR used to control loading the on-board microcontroller.
JH3 Closed Connects JTAG board's 5.0V supply to JTAG connector pin 8 (feeds target board).

用JTAG电缆连接JTAG电路板和MAXQ610评估套件电路板。电缆上的红条应连接至JTAG电路板上标有引脚9和引脚10的连接器一侧,以及MAXQ610评估套件电路板上标有TDI-GND的连接器一侧。

用9针串行电缆连接PC和JTAG电路板(不要将其连接至MAXQ610评估套件电路板)。最后,将5V电源连接至JTAG电路板的电源连接器。

采用IAR编译器开始设计:blinker

我们不以“Hello World”开始,而是构建一个简单的应用程序,该应用程序使MAXQ610评估套件电路板上的4个LED闪烁(例如,DS1、DS2、DS3和DS4)。我们要使用的工具包是IAR嵌入式工作台,由IAR系统公司提供。本应用笔记的软件采用IAR系统公司2.12版KickStart试验包来编写并进行了测试。

在开始一个新工程之前,需要将一些MAXQ610特殊文件复制到IAR安装目录(通常是C:\Program Files\IAR Systems\Embedded Workbench 4.0,下面将其称为[IAR])中。网上提供本应用笔记的文件(请参考文档最后的了解详细信息一节),评估套件的CD-ROM也提供这些文件。请复制这里提到的这些文件:
  • iomaxq610.h复制到[IAR]\MAXQ\inc
  • lnkmaxq610.xcl复制到[IAR]\MAXQ\config
  • maxq610.sfr复制到[IAR]\MAXQ\config
  • maxq610.ddf复制到[IAR]\MAXQ\config
  • maxq610.menu复制到[IAR]\MAXQ\config\devices
现在启动IAR嵌入式工作台。选择“Create new project in current workspace” (图2)。选择MAXQ®工具链,确定选择了“Empty project” (图3)。单击OK,打开一个文件对话框。在这个例子中,工程文件名为“blinker” (图4)。

图2. 工作台启动
图2. 工作台启动

图3. 建立一个空的工程
图3. 建立一个空的工程

图4. 如图所示,保存工程“blinker”
图4. 如图所示,保存工程“blinker”

工作空间将显示“blinker”工程。现在,建立一个新文件(File New File),将以下文本复制到该文件中。

#include <iomaxq610.h>
#include <iomaxq.h>

void main()
{
  /*
   * Try to get a 1Hz blink on the LEDs. System clock = 12MHz. 
   * Timer reload = 0x5B8D = 23437. Running at div 256, so we get a timer
   * interrupt once every 23437*256 cycles = 5,999,872, or roughly 500ms.
   * We toggle every 500ms, so we get a 1Hz cycle.
   */
  TB0R = 0x5B8D;       // reload for timer 0
  TB0CN = 0x0416;      // timer set to run, enable interrupt, down count, div 256
  PD3 = 0x0f;          // set port 2 lower nibble to output
  IC_bit.IGE = 1;      // set global interrupt enable
  while (1)
  {

  }
}
在这个简单的应用程序中,采用一个定时器中断来启动使评估套件LED不断接通和关断的代码。要重新装入的值在定时器寄存器中断时自动装入该寄存器,大约每500ms周期性中断一次。设置定时器运行之后,将连接LED的端口引脚配置为输出,然后,全局使能中断。应用程序进入无限while循环。中断服务例程(ISR)代码完成应用程序(请参见下面图5)。

单击save,将文件命名为main.c (确定代码保存目录与您建立新工程的目录相同)。在工作窗口下,右键单击“blinker”,选择Add Add main.c

下一步,将另外两个文件从软件分配源复制到您的工程目录中:isr.cclib.r66。C文件含有中断部分,编译器需要利用它来编译程序。r66文件含有应用程序运行需要的启动代码和标准库代码。每次开始新的MAXQ610工程时,都需要重复这一复制步骤。

再次右键单击工作窗口中的“blinker”行,找到Add Add Files,选择isr.c

现在,需要配置工程选项。选择Project Options,打开选项窗口。请按照以下步骤进行:
  • 在General选项下:Target,选择MAXQ610。
  • 在General选项下:Library Configuration,从下拉菜单中选择Custom CLIB。浏览Library File文本区,选择刚刚复制到工程目录中的clib.r66文件。
  • 在Debugger下:Setup,从driver下拉菜单中选择JTAG。
  • 在JTAG下:输入您将使用的连接JTAG电路板的串口。
现在,构建应用程序就非常简单了。按下F7或者选择Project Make。您首先会被询问保存工作空间。对此,请输入“gettingstarted”。工程应该被正确构建。

如果您希望在此处运行应用程序(例如,Project Debug,然后单击右箭头按钮),电路板上不会有任何事情发生。这是因为应用程序代码试图使用定时器中断来确定LED什么时候应该改变,而定时器的ISR中没有代码。因此,必须为定时器(ISR)编写代码。

打开文件isr.c,找到函数isr6(void),在它旁边应该有注释//timers。在函数中输入以下代码:
  TB0CN = TB0CN & 0xFF7F;       // clear timer 0 interrupt
  PO3 = PO3 ^ 0x0f;             // toggle lower nibble
这些代码首先清除定时器中断标志(必须由软件清除中断标志,否则,将导致中断矢量不断启动)。第二行触发所有4个LED,这些LED连接到端口引脚P3.0至P3.3。

现在开始构建工程,进行调试(Project Debug把您带到执行C代码的第一行,如图5所示)。代码第一行下面高亮显示,左侧空白区有一个箭头,指示程序在此暂停。现在,单击Run按钮(图6)。该按钮使程序运行至结束(或者到下一个断点)。当程序执行无限循环时,LED块在一直闪烁。

图5. 程序在代码第一行暂停
图5. 程序在代码第一行暂停

图6. 程序Run按钮
图6. 程序Run按钮

使用IAR嵌入式工作台调试应用程序

现在,我们看一下MAXQ610和嵌入式工作台工具的调试功能。MAXQ610处理器有内置JTAG引擎,支持在实际芯片中进行调试。这一特性还避免了使用昂贵的模拟器或者有可能出错的仿真器。

返回到最初的blinker应用程序,开始上面介绍的调试过程。第一行高亮显示后,点击Go按钮,继续执行。您将看到LED接通500ms,然后关断500ms。

单击Break按钮,或者选择Debug Break,暂停执行(图7)。程序应暂停在while(1)声明上,这是因为该声明占用了无限循环的大部分运行时间,而中断矢量只占用了很少的时间(每500ms只有几个周期)。

图7. Break按钮
图7. Break按钮

在检查一些处理器寄存器中的数值时,打开寄存器窗口(View Register)。此处,从下拉菜单中选择Timer 0,您将看到与定时器控制闪烁LED相关的寄存器(图8)。这里显示的Timer 0寄存器包括重装寄存器(TB0R),控制寄存器(TB0CN),计数寄存器(TB0C)和数值寄存器(TB0V)。

图8. Register窗口显示Timer 0寄存器
图8. Register窗口显示Timer 0寄存器

作为演示,我们将执行几行代码,观察这些定时器寄存器会有什么变化。按下Step Over按钮几次(图9),或者选择Debug Step Over。观察TB0V中的数值。Step Over按钮执行一行C代码,但是不会进入任何函数调用。该按钮按下时,您将看到TB0V中的数值变化范围很大,这是因为调试引擎执行时,定时器在不断运行。您还将看到,TB0CN寄存器随着定时器中断出现和结束的变化。

图9. Step Over按钮
图9. Step Over按钮

寄存器窗口不但显示了寄存器内容,而且,在调试进程中,还可以向其写入数值。程序暂停时,双击TB0R寄存器中的数值。将寄存器改为0x2DC6 (这是0x5B8C/2),然后,单击Go按钮。LED现在闪烁应比以前快两倍,这是因为定时器重新装入的计数值减小了,从而减小了定时器中断之间的时间。

在另一个演示中,我们把光闪烁模式由全通/全关(1111 0000 1111)改为交替模式(1010 0101 1010)。而这种改变并不需要重新编译程序。首先,我们必须加入一个断点。程序运行时,打开isr.c文件,找到定时器中断矢量。双击代码第一行左侧的灰色区,将出现一个红色X。这一X表示加入了一个断点。当程序执行到这一行代码时,程序将停止,其屏幕显示如图10所示。绿色箭头和高亮显示的代码表示已经到达断点,程序暂停在这里。

图10. 断点设置和到达断点
图10. 断点设置和到达断点

在寄存器窗口中,从下拉列表中选择Port I/O。注意,代码使用了XOR (^)运算符来触发端口3 (P3)最下面的4个引脚,而这些引脚从未明确设置。为改变这一操作,单击PO3中的数值,输入新值0x05。输入后,您将看到,按照0101的模式,2个LED接通,2个LED关断。现在,单击Run。程序开始运行,直至到达断点而再次停止,LED将转换状态,因此,处理器现在输出1010模式。双击红色X,清除断点,然后,单击Go。程序将以交替LED模式不断运行。

在IAR嵌入式工作台中,您可以按照与寄存器一样的方法来观察并改变变量值。对此进行演示时,单击Stop或者选择Debug Stop Debugging,停止应用程序。现在,修改代码,在主函数中加入变量x,在while循环中嵌入延时循环。如下所示,输入对程序的一些修改。注意,在代码中故意设置了错误,稍后对它进行讨论。
void main()
{
  /*
   * Try to get a 1Hz blink on the LEDs. System clock = 12MHz. 
   * Timer reload = 0x5B8D = 23437. Running at div 256, so we get a timer
   * interrupt once every 23437*256 cycles = 5,999,872, or roughly 500ms.
   * We toggle every 500ms, so we get a 1Hz cycle.
   */
  long int x;
  TB0R = 0x5B8D;          // reload for timer 0
  TB0CN = 0x0416;         // timer set to run, enable interrupt, down count, div 256
  PD3 = 0x0f;             // set port 2 lower nibble to output
  IC_bit.IGE = 1;         // set global interrupt enable
  while (1)
  {
    for (x=0;x<100000;x++)
    {
      if (x==100000)
        PO3 = PO3 ^ 0x01;
    }
  }
}
这些改变用于偶尔触发端口3最下面一个引脚,因此,3个LED同步闪烁,而1个将独立闪烁。延时循环间隔并不重要,但是必须提供足够的延时才能观察到结果。运行该应用程序(开始调试,然后,运行),您将很快看到和最初的应用程序并没有什么不同;所有LED以1秒的间隔同时接通和关断。暂停应用程序,打开本地变量观察窗口(View Locals)。如果程序停在主应用程序的while循环(很有可能)中,窗口中将显示变量x (图11)。

前面曾提到上面的代码中有错误。现在,按下Step Over按钮几次,您将看到执行从循环对比(x<100000)跳到条件测试“if”声明(x ==100000),直到递增(x++),然后是本地窗口中x值的变化。在PO3 = PO3 ^ 0x01一行设置一个断点,单击Go。出于某些原因,执行并没有暂停。很明显,程序没有进入“if”声明。再次按下Break,将变量x值改为99999,单击Step Over几次。您将注意到,由于x=0部分被执行,“for”循环终止,然后再次开始。问题很明显—x值永远不会到达“for”循环中的100000,这是因为进行了“less than”测试。停止程序,将“if”声明中的对比值改为99999。重新编译程序,启动调试器,单击Go。LED开始闪烁,LED DS1自己独立闪烁。

图11. 本地变量窗口
图11. 本地变量窗口

更多信息
评估套件CD-ROM中提供本应用笔记所有文件的源代码。还可以从Maxim网站下载这些源代码。文件还含有工程文件;所有头文件和include文件;以及机器可装入.HEX输出文件,采用Maxim的MTK (微控制器工具套件)等终端模拟器直接可以装入并运行它(例如,不需要使用编译器工具包),可以下载这一模拟器。

Maxim提供软件库、应用笔记和参考设计。如果您需要了解库和工具的最新信息,或者对本应用笔记还有问题,请搜索Maxim网站的微控制器部分,或者联系技术支持