最近一直利用业余时间写自己的“基于AVR-BootLoader”,启发是由于一次在ourAVR论坛看到了绍子阳的bootloader,联想到公司在用AVR MCU,但每次升级程序都要花费很大的力气车马劳顿的跑到工程现场,而且很多机器还安装在国外,为了升级一次程序发费了很多的人力物力财力,加上公司的机器目前大部分都配有远程监控系统,所以本人决定写一个具有自有产权的“AVR-BootLoader”。
特别说明:本“AVR-BootLoad”软件代码属上海霜蝉版权所有,在此贡献发布,仅限于个人免费使用不得用于商业用途,本人也不保证代码的严谨性,如在升级中出现任何问题与本人无关,本人已测试过Atmega64A与Atmega128。话不多说了上源代码,网友们和AVR爱好者可以拷贝到CodeWizardAVR V2.03.9编译器下编译。
需要讨论或有遇到BUG的网友们可以联系我:QQ:285247488 mail:shw@scicala.com
上位机截图:
远程升级DTU:
远程升级连接云平台虚拟串口:
// 关于上海霜蝉-AVR_BootLoade_V1.00
// 1、软件版本V1.00 编译环境CodeWizardAVR V2.03.9 Standard;
// 2、支持本公司常用的三种AVR芯片;
// 3、支持标准Xmodem和扩展Xmodem_1K协议;
// 4、联机握手密码为"00",握手成功手的等待文件超时为1分钟;
// 5、默认复位等待3S退出boot到用户程序或循环运行boot;
// 6、支持1分钟以内的断网续传;
// 7、支持连续10帧以内数据错误的重传;
// 8、支持下载过程中的取消超作;
// 9、支持当收到包时,接收过程中每个字符的超时间隔为 1 秒;
// 10、支持所有的超时及错误事件至少重试 10 次;
// 11、支持数等待超时6S的请求;
// 12、Boot Loader - Size:1024words;
// 13、支持传输速度:38.400KB/S~2.400KB/S;
// 14、支持公司常用最多的三个型号ATMEGA32,64,128。
// 15、支持开门狗自定义开关,自定义时钟频率
/*****************************************************
Thisprogramwasproducedbythe
CodeWizardAVRV2.03.9Standard
AutomaticProgramGenerator
?Copyright1998-2008PavelHaiduc,HPInfoTechs.r.l.
/zixunimg/eeworldimg/www.hpinfotech.com
Project :AVR_BootLoader
Version:V1.00
Date :2014-7-19
Author:SuiHongwei
Company: SCICALA
Comments:
Chiptype :ATmega64L
Programtype :BootLoader-Size:1024words
AVRCoreClockfrequency:16.000000MHz
Memorymodel:Small
ExternalRAMsize:0
DataStacksize :1024
*****************************************************/
#include"AVR_boot.h"//头文件包含
//--------------------------------------------------//
//同步密码长度
#defineCONNECTCNT 7
//同步密码
ucharKEY_Data[10]={"SCICALA"};
//Declareyourglobalvariableshere
//--------------------------------------------------//
//全局变量定义
ucharRX_buff[BUFSIZE]; //数据拉收缓存
ucharFrame_State,SOH_Wait_cnt; //帧状态,帧头等待计数
uintTime_cnt,Error_cnt;//超时计数,连续帧错误计数
uintbuffptr,buffptr_old,buffptr_New;//数据缓存指针必须大于1024
ulongFlashAddr;//Flash地址
ucharUpdatedSta;//升级标志
//-----------------------------------------------//
//擦除(code=0x03)和写入(code=0x05)一个Flash页
voidboot_page_ew(ulongp_address,charcode)
{
#asm
lddr26,y+1;R26LSB
lddr27,y+2;R27MSB
#endasm
SPM_REG=code;//寄存器SPMCSR中为操作码
#asm
movr30,r26
movr31,r27
#endasm
#ifdefATMEGA128
RAMPZ=(p_address>>16);//RAMPZ0=1:ELPM/SPM可以访问程序存储器地址$8000-$FFFF(高64K字节)
#endif
#asm("spm");//对指定Flash页进行擦操作
}
//填充Flash缓冲页中的一个字
voidboot_page_fill(uintA_address,uintdata)
{
#asm
LDDR30,Y+2;R30LSB
LDDR31,Y+3;R31MSB
LDR26,Y
LDDR27,Y+1
MOVR0,R26
MOVR1,R27
MOVR26,R30
MOVR27,R31
#endasm
SPM_REG=0x01;//寄存器SPMCSR中为操作码
#asm
movr30,r26
movr31,r27
#endasm
#asm("spm");//对指定Flash页进行擦操作
}
//等待一个Flash页的写完成
voidwait_page_rw_ok(void)
{
while(SPM_REG&0x40)
{
while(SPM_REG&0x01);
SPM_REG=0x11;
#asm("spm");
while(SPM_REG&0x01);
}
}
//-----------------------------------------------//
//更新一个Flash页的完整处理
voidwrite_one_page(uchardata[])
{
uinti;
boot_page_ew(FlashAddr,0x03);//擦除一个Flash页
wait_page_rw_ok();//等待擦除完成
for(i=0;i { boot_page_fill(i,(uint)data[i]+(data[i+1]<<8)); wait_page_rw_ok(); } boot_page_ew(FlashAddr,0x05);//将缓冲页数据写入一个Flash页 wait_page_rw_ok();//等待写入完成 } //--------------------------------------------------// //等待串口数据1S超时自动转为应答 unsignedcharWait1S_UART() { uchari=0; do { #ifWDGEn Watchdog_Reset();//喂狗 #endif if(TIFR&0x10) // OCF1A: T/C1 输出比较 A 匹配标志位
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』