首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

利用I2C总线实现ATmega88的在应用编程

利用I2C总线实现ATmega88的在应用编程

随着嵌入式系统技术的发展,电可擦除的Flash存储器由于具有容量大、成本低、编程方便等优点,在微控制器领域得到了广泛的应用。Flash微控制器在正常运行前必须将Flash写入用户应用程序,目前对微控制器的Flash程序存储器进行编程的方法主要有出厂固化、编程器编程、在系统编程(In System Programming, ISP)和在应用编程(In Application programming,IAP)4种。 其中,出厂固化和编程器编程方法都要求微控制器在焊接前将程序写入,这显然不满足开发阶段的调试和日后升级的需要。目前比较普及的是在板可编程的ISP和IAP方法。ISP是通过微控制器的串行编程写入应用程序,需要少量的外部电路辅助实现;IAP将Flash映射为用户程序和Bootloader两个存储区,Bootloader可通过系统已有的USB、串口、SPI、I2C总线等各种通信接口,对用户程序进行更新而不需要外部电路辅助,实现更加灵活,可方便地实现程序的在线及远程升级。 在利用ATmega88微控制器开发四旋翼飞行器的无感无刷直流电机驱动器时,由于定时器PWM输出口与SPI接口存在引脚共用问题,用SPI口进行ISP编程时会使MOS管误导通而烧毁。由于驱动器中的4个ATmega88微控制器是通过I2C总线通信的,为了调试和升级方便,提出并实现了通过I2C总线对AVR微控制器进行在应用编程的方法,包括Bootloader程序、I2C总线的PC机串口模拟、上位机程序及相关的通信协议。实践证明,该方法可成功实现I2C总线上多个ATmega88微控制器[1]的在线升级。 1 ATmega88微控制器的Bootloader设计 ATmega88是一款基于AVR增强RISC体系结构的CMOS低功耗8位微处理器,它通过执行强大的单周期指令,达到接近1 MIPS/MHz的运算效率。ATmega88的Flash被分为128个大小为64字节的页面,Flash的编程操作都是以页面为单位进行的。为了用户程序的安全性,以及用户的ISP和IAP编程需要[2],ATmega88的Flash存储空间被分为引导程序区(Bootloader Section)和应用程序区(Application Program Section)两部分。 引导程序区为非同时读写区,应用程序区为同时读写区。在非同时读写区内执行的代码可以对同时读写区内的页面进行编程操作,根据这一机制我们可以编制Bootloader程序并将其存储于引导程序区内,以实现应用程序区代码的在线与远程升级。 由于ATmega88分配给引导程序区的空间大小有限(最大2 KB),Bootloader程序一定要简洁而高效,图1给出了以I2C总线为通信接口的Bootloader程序流程图。

为了能够执行Bootloader程序,ATmega88熔丝位中的BOOTRST应设为零,这样在系统上电或应用程序接收到升级命令利用看门狗复位后,系统就能从引导程序区运行Bootloader程序。Bootloader程序中维持了一个溢出时间为2 s的定时器,该定时器利用TIM1以查询的方式实现。没有程序更新或程序更新完毕,程序在2 s内没有从I2C总线接收到数据帧时则利用(*((void(*)(void))(0x0000)))函数跳转到应用程序区执行应用程序,在2 s内接收到数据帧后,则将定时器重置,以继续接收数据帧更新应用程序。 在Bootloader实现中,ATmega88的I2C总线工作在从模式,上位机的I2C总线工作在主模式。上位机发送的数据帧由2字节的Flash页面地址、64字节的页面数据、1字节的密码和1字节的异或校验和构成。Bootloader接收到数据帧后会用数据长度、密码、异或校验和对数据帧进行校验,校验正确的话则根据数据帧中Flash的页面地址和数据相应的Flash页面进行编程,并将flag置1;校验错误的话,则丢弃数据帧等待重发的数据帧。 上位机在发送数据帧后读取flag,并根据其状态重发数据帧或发送下一页面的数据帧。flag被读取后Bootloader程序将其清零,这样就形成了一个简洁而有效的差错控制机制。Flash中页面的编程由页擦除和页编程两个过程组成,页擦除由AVR库函数中的boot_page_erase(addr)函数实现,addr为相应页面中的字节地址。 ATmega88的Flash是以页为单位进行擦除和写入操作的,因此在进行Flash页面写入前,要多次调用boot_page_fill(addr, data)函数将整页的程序代码写入临时缓冲区,其中addr为指令所要写入的字节地址,data为相应的由2个字节构成的16位程序指令。Flash页面的写入由boot_page_write(addr)函数实现,addr为相应页面中的字节地址。 为了程序安全,Flash执行页擦除和编程操作时要求CPU处于等待状态,因此Flash的页擦除和写入函数执行后都要调用boot_spm_busy_wait()函数等待操作完成。此时,I2C总线也处于挂起状态,等所有操作完成后才能将总线释放。上位机软件在发送完数据帧后就一直监听总线状态,等总线释放后再读取flag状态,并决定是重发还是发送下一帧,这样就实现了有效的通信流量控制。 整个Bootloader程序编译完成后,大小为506字节。因此,熔丝位中的BOOTSZ1和BOOTSZ0应设为1和0,将引导程序区设置为地址0x1E00~0x1FFF、大小为512字节的区域。为了使Bootloader程序能正确写入到该区域,程序编译时要将程序起始地址设定在0x1E00,在WinAVR中可以通过在Makefile中添加“LDFLAGS+= -Wl,--section-start=.text=0x1E00”实现。编译完成的Bootloader可以在ATmega88确定PCB前,通过编程器或ISP写入到Flash中。
返回列表