最近一直利用业余时间写自己的“基于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、支持开门狗自定义开关,自定义时钟频率
/*****************************************************
This program was produced by the
CodeWizardAVR V2.03.9 Standard
Automatic Program Generator
?Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
Project : AVR_BootLoader
Version : V1.00
Date : 2014-7-19
Author : Sui Hongwei
Company : SCICALA
Comments:
Chip type : ATmega64L
Program type : Boot Loader - Size:1024words
AVR Core Clock frequency: 16.000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 1024
*****************************************************/
#include "AVR_boot.h"//头文件包含
//--------------------------------------------------//
//同步密码长度
#define CONNECTCNT 7
//同步密码
uchar KEY_Data[10] = {"SCICALA"};
// Declare your global variables here
//--------------------------------------------------//
//全局变量定义
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
#ifdef ATMEGA128
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
{
#if WDGEn
Watchdog_Reset();//喂狗
#endif
if(TIFR&0x10)// OCF1A: T/C1输出比较A匹配标志位
{
TIFR|=0x10;//清除Time1定时器比较匹配标志
i++;
if(i>=4)//等待1S 250ms*4=1S
{Frame_State=0x06;break;}//帧数据超时转为应答请求重发数据帧
}
if(UCSRAREG(COMPORTNo)&0x80)
{
UCSRAREG(COMPORTNo)|=0x80;//清除接收完成状态
#if Run_LEDEn
Run_LED;//运行LED闪烁
#endif
i=100;
returnUDRREG(COMPORTNo);//读取UDR0
}
}
while(100!=i);//等待数据||超时退出
}
//***************************************************//
//===================================================//
voidmain(void)
{
ucharpackNO,packNO_old;//包号、包号留存
uintcrc16;//接收CRC缓存
uintli;//帧计数
ucharch,cl;//包号
PORT_Init();//端口初始化
UART_Init();//串口初始化
Time1_Init();//定时器初始化250ms
#if WDGEn
WatchDog_Enable();//打开看门狗(2S)
#else
WatchDog_Disenable(); //禁止看门狗
#endif
#if Wait_BootTime
Time_cnt=EEPROM_Read(EE_TimeAddr);//读取boot运行时间
#endif
#if SafeUpdated_En
UpdatedSta=EEPROM_Read(EE_SafeAddr);//读取升级成功标志
#endif
#asm("cli")//关总中断
#if Delay_En //是否延时
for(li=0;li<5000;li++)
{#asm("nop")}
#endif
//-----------------------------------------------//
//等待"握手",否则退出Bootloader程序,从0x0000处执行应用程序
Time_cnt+=WiteTimeCnt;
cl=0;
while(1)
{
if(TIFR&0x10)// OCF1A: T/C1输出比较A匹配标志位
{
TIFR|=0x10;//清除Time1定时器比较匹配标志
#if Run_LEDEn
Run_LED;//运行LED闪烁
#endif
Time_cnt--;
if(Time_cnt==0)//等待握手超时
{
#if SafeUpdated_En
if(UpdatedSta)//上次升级失败
{while(1);}//复位boot
else
#endif
{quit_boot();}//跳转到用户程序
}
if(UCSRAREG(COMPORTNo)&0x80)
{
ch=Wait_UART();
if(ch==KEY_Data[cl])
{cl++;}
else
{cl=0;}
//WriteCom(ch); //密码回传
}
if(cl==CONNECTCNT)break;
}
#if WDGEn
Watchdog_Reset();//喂狗
#endif
}
//-----------------------------------------------//
//启动Xmodex CRC传数据=字符“C”,等待控制字〈soh〉
Time_cnt=TimeOutCntC;
while(1)
{
if(TIFR&0x10)// OCF1A: T/C1输出比较A匹配标志位
{
TIFR|=0x10;//清除Time1定时器比较匹配标志
#if Run_LEDEn
Run_LED;//运行LED闪烁
#endif
Send_UART(XMODEM_RWC);//发送"C"
Time_cnt--;
if(Time_cnt==0)//等待文件超时
{
#if SafeUpdated_En
if(UpdatedSta)//上次升级失败
{while(1);}//复位boot
else
#endif
{quit_boot();}//跳转到用户程序
}//跳转到用户程序
}
if(UCSRAREG(COMPORTNo)&0x80)//串口有数据
{
#ifdef Xmodem
if(Wait_UART()==XMODEM_SOH)//XMODEM命令开始0x01
#else // Xmodem_1K
if(Wait_UART()==XMODEM_STX)//XMODEM命令开始0x02
#endif
break;
}
#if WDGEn
Watchdog_Reset();//喂狗
#endif
}
//-----------------------------------------------//
//开始接收数据进入Xmodem协议接收文件
//帧的两个时间很重要:连续出错10次*最大帧请求间隔6S
//累计请求间隔10*6S=1min
packNO=1;// Xmodem起始为0x01
packNO_old=0;
buffptr=0;
buffptr_old=0;
Error_cnt=0;
FlashAddr=0;
Frame_State=0x01;//第一帧不判断帧头
while(1)
{
switch(Frame_State)//帧状态
{
case0x00://接受状态帧头与停止信号判断
{
ch=XMODEM_NUL;//清除
if(UCSRAREG(COMPORTNo)&0x80)//串口有数据
{ch=Wait_UART();}//读取帧头或停止信号
if(TIFR&0x10)// OCF1A: T/C1输出比较A匹配标志位
{
TIFR|=0x10;//清除Time1定时器比较匹配标志
SOH_Wait_cnt++;//等待计时250ms
if(SOH_Wait_cnt>=24)//等待帧超时请求数据(6S*10=1min)
{
Frame_State=0x06;//要求重发数据块
SOH_Wait_cnt=0;//帧请求计时
#if Run_LEDEn
Run_LED;//运行LED闪烁
#endif
}
}
//------------------------------
if(ch==XMODEM_EOT)//发送结束
{
for(li=(buffptr_New-128);li
{
if((RX_buff[li++])!=0xff)break;//填充帧判断争强EOT抗干扰能力FF CF
{
if((RX_buff[li++])!=0xcf)break;//填充帧判断争强EOT抗干扰能力FF CF
}
}
if(li==buffptr_New)
{Send_UART(XMODEM_ACK);//最后一帧应答完成
Frame_State=0x0ff;//转为退出boot
}
else
{
Frame_State=0x06;//要求重发数据块
SOH_Wait_cnt=0;//帧请求计时
}
}
#ifdef Xmodem
if(ch==XMODEM_SOH)// Xmodem帧头判断
#else // Xmodem_1K
if(ch==XMODEM_STX)// Xmodem_1K帧头判断
#endif
{
Frame_State=0x01;//转为包号检查
SOH_Wait_cnt=0;//清除帧头等待计时
}
}
break;
case0x01://包序号校验
{
ch=Wait1S_UART();//获取包序号
cl=~Wait1S_UART();
if(ch==cl)//包号对比
{Frame_State=0x02;
packNO=ch;//正确保留包号
}
else
{Frame_State=0x06;}//重发应答ANK
}
break;
case0x02://进入二级CRC校验
{
for(li=0;li
{
RX_buff[buffptr++]=Wait1S_UART();//接收数据
//帧数据接收超时1S退出for询环,再接收2个数据或超时1S+2S转为应答
if(Frame_State==0x06)break;
}
crc16=Wait1S_UART();
crc16=crc16<<8;
crc16+=Wait1S_UART();//接收2个字节的CRC效验字
if(CRC16_Word(&RX_buff[buffptr-BUFFER_SIZE],BUFFER_SIZE)==crc16)// CRC校验验证
{
if(packNO==packNO_old)//接收相同包不写flash
{Frame_State=0x05;//正常应答ACK
buffptr=buffptr_old;
}
else
{Frame_State=0x03;//正确应答
buffptr_New=buffptr;//记录当前数据指针
}
}
else
{Frame_State=0x06;//应答NAK
buffptr=buffptr_old;//去掉错误数据的指针
}
}
break;
case0x03://校验通过,执行写入
{
if(FlashAddr
{
#if BUFFER_SIZE < SPM_PAGESIZE // ---
if(buffptr>=SPM_PAGESIZE)//缓冲区满,写入数据;否则继续接收
{//接收多个帧,写入一页
write_one_page(&RX_buff[0]);//写入缓冲区内容到Flash中
FlashAddr+=SPM_PAGESIZE;//修改Flash页地址
buffptr=0;
}
#else //----------------------
while(buffptr>0)//接收一帧,写入多个页面
{
write_one_page(&RX_buff[BUFSIZE-buffptr]);
FlashAddr+=SPM_PAGESIZE;//修改Flash页地址
buffptr-=SPM_PAGESIZE;
}
#endif//-----------------------
}
else//超过BootStart,忽略写操作
{buffptr=0;}//重置接收指针
Frame_State=0x04;
}
break;
case0x04://读取写入的Flash内容并和下载的缓冲区比较
{
Frame_State=0x05;//转为应答状态
buffptr_old=buffptr;//写入正常才记录数据指针
}
break;
case0x05://正确应答ACK
{
packNO_old=packNO;//接收完整一帧保留本次包号
Send_UART(XMODEM_ACK);//认可应答
//WriteCom(packNO); //测试
//WriteCom(FlashAddr); //测试
//WriteCom(FlashAddr>>8); //测试
Error_cnt=0;//清除连续错误计数
Frame_State=0x00;//转为帧接收(请求)状态
}
break;
case0x06://错误=重发应答ANK
{
Send_UART(XMODEM_NAK);//要求重发数据块
Error_cnt++;//连续错误计数
Frame_State=0x00;//转为接收状态
}
break;
default://升级完成退出处理
{
#if SafeUpdated_En
EEPROM_Write(EE_SafeAddr,0);//写升级成功标志0
#endif
quit_boot();//退出Bootloader
}
break;
}// switch End
if(Error_cnt>10)//连续出错10次退出升级(复位)
{
Send_UART(XMODEM_CAN);//撤销传送(无条件停止)
#if SafeUpdated_En
EEPROM_Write(EE_SafeAddr,1);//写升级失败标志1
#endif
while(1);//没有升级完成重新开始
}
#if WDGEn
Watchdog_Reset();//喂狗
#endif
}// while end
//-------------------------------------------------//
}// main end
//-----------------------------------------------//
#include "AVR_boot.h"//头文件包含
//-----------------------------------------------//
//----------初始化-------------------------------//
//输出端口初始化
voidPORT_Init()
{
//上电默认全为输入口
//输出口设置
#if Run_LEDEn
DDRREG(LEDPORT)|=(1<
#endif
}
//-----------------------------------------------//
//串口初始化
voidUART_Init()
{
#if RS485_En
DDRREG(RS485PORT)|=(1<
RX485DE_RX;//默认为接收
#endif
UCSRAREG(COMPORTNo)=0x00;
UCSRBREG(COMPORTNo)=0x18;// Enable Receiver and Transmitter
UCSRCREG(COMPORTNo)=0x0E;// Set frame. format: 8data, 2stop bit
//通信速率
UBRRHREG(COMPORTNo)=BAUD_H;// 0X00
UBRRLREG(COMPORTNo)=BAUD_L;// Set baud rate 16M 9600 0x0067
}
// 250ms定时器设置Time1
//-----------------------------------------------//
//使用定时器1:1024分频,CTC模式4,产生以毫秒为单位的时间
voidTime1_Init()
{
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 16MHz
TCCR1A=0x00;// CTC4
TCCR1B=0x08;// CTC4
TCCR1B|=0x03;// clkI/O/64 (来自预分频器) 16M=4us
OCR1A=T1_TCNT;// 250MS
}
//-----------------------------------------------//
//看门狗初始化函数2s
voidWatchDog_Enable(void)
{
// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/2048k
MCUCSR=0x00;//控制与状态寄存器
WDTCR=0x1F;//看门狗使能500ms(D)1.0S(E) 2.0S(F)
WDTCR=0x0F;
}
//禁止看门狗
voidWatchDog_Disenable(void)//禁止看门狗
{
MCUCSR=0x00;//控制与状态寄存器
WDTCR=0b00011111;//看门狗使能位修改使能(B4=1) 2.0S(F)
WDTCR=0b00000111;//禁止看门狗2.0S(7)
}
//喂狗
voidWatchdog_Reset(void)
{#asm("wdr")}//喂狗
//-----------------------------------------------//
//-------------子函数----------------------------//
//写入数据到串口
voidSend_UART(unsignedchardat)
{
uchari;
#if RS485_En
RX485DE_TX;//使能RS485发送
#endif
UDRREG(COMPORTNo)=dat;// UDR0
//等待数据发送完成
while(!(UCSRAREG(COMPORTNo)&0x40));//等待数据发送完成Bit 6 – TXC: USART发送结束
UCSRAREG(COMPORTNo)|=0x40;//清除发送完成状态
#if RS485_En
RX485DE_RX;//使能RS485接收
#endif
}
//-----------------------------------------------//
//等待串口数据(注意是”死等“)
unsignedcharWait_UART()
{
while(!(UCSRAREG(COMPORTNo)&0x80));//等等数据到来Bit 7 – RXC: USART接收结束
UCSRAREG(COMPORTNo)|=0x80;//清除接收完成状态
#if Run_LEDEn
Run_LED;//运行LED闪烁
#endif
returnUDRREG(COMPORTNo);
}
//-----------------------------------------------//
//计算CRC
intCRC16_Word(char*ptr,intcount)
{
intcrc=0;
chari;
while(--count>=0)
{
crc=crc^(int)*ptr++<<8;
i=8;
do
{
if(crc&0x8000)
crc=crc<<1^0x1021;
else
crc=crc<<1;
}while(--i);
}
return(crc);
}
//-----------------------------------------------//
//退出Bootloader程序,从0x0000处执行应用程序
voidquit_boot(void)
{
MCUCR=0x00;//当IVSEL为"0“时,中断向量位于Flash存储器的起始地址;
#ifdef ATMEGA128
RAMPZ=0x00;//0: ELPM/SPM可以访问程序存储器地址$0000 - $7FFF (低64K字节)
#endif
#asm("jmp 0x0000")//跳转到Flash的0x0000处,执行用户的应用程序
}
//-----------------------------------------------//
//读EEPROM一个字节
ucharEEPROM_Read(uintAddr)// EEPROM读1个字节操作0
{
while(EECR&0x02);//等待上一次写操作结束
EEAR=Addr;//设置地址寄存器
EECR|=0x01;//设置EERE以启动读操作b0
return(EEDR);//自数据寄存器返回数据
}
//写EEPROM一个字节
voidEEPROM_Write(uintAddr,charData)// EEPROM写1个字节操作
{
EEAR=Addr;//设置地址寄存器
EEDR=Data;//设置数据寄存器
// #asm("cli") // EEMPE置1,EEPE1,这两步操作中间不能超过4个时钟周期
EECR|=0x04;//置位EEMWE b2
EECR|=0x02;//置位EEWE以启动写操作b1
//#asm("sei")
}
//-----------------------------------------------//
//-------------------------------------------------------//
#ifndef _AVR_BOOT_H_
#define _AVR_BOOT_H_ 1
//配置文件包含
#include "Config.h"
//------------------------------------------------------//
#ifdef ATMEGA32
#include
#endif
#ifdef ATMEGA64
#include
#endif
#ifdef ATMEGA128
#include
#endif
//---------------------------------------------------//
typedefsignedcharschar;
typedefsignedintsint;
typedefsignedlongslong;
typedefunsignedcharuchar;
typedefunsignedintuint;
typedefunsignedlongulong;
//--------------------------------------------------//
//函数申明
voidUART_Init();
voidPORT_Init();
voidTime1_Init();
voidSend_UART(unsignedchardat);
unsignedcharWait_UART();
unsignedcharWait1S_UART();
voidWatchDog_Disenable(void);
voidquit_boot(void);
intCRC16_Word(char*ptr,intcount);
voidwrite_one_page(uchardata[]);
voidWatchDog_Enable(void);
voidWatchdog_Reset(void);
ucharEEPROM_Read(uintAddr);
voidEEPROM_Write(uintAddr,charData);
//--------------------------------------------------//
//内部使用的宏定义
#define CONCAT(a, b) a ## b
#define CONCAT3(a, b, c) a ## b ## c
//端口以及位定义
#define PORTREG(No) CONCAT(PORT, No)
#define PINREG(No) CONCAT(PIN, No)
#define DDRREG(No) CONCAT(DDR, No)
#define UDRREG(No) CONCAT(UDR, No)
//串口初始化需要寄存器
#define UCSRAREG(No) CONCAT3(UCSR, No, A)
#define UCSRBREG(No) CONCAT3(UCSR, No, B)
#define UCSRCREG(No) CONCAT3(UCSR, No, C)
#define UBRRHREG(No) CONCAT3(UBRR, No, H)
#define UBRRLREG(No) CONCAT3(UBRR, No, L)
//---------------------------------------------------//
//端口定义
#define RX485DE_RX PORTREG(RS485PORT)&=~(1 << RS485TXEn); // SCI接收使能
#define RX485DE_TX PORTREG(RS485PORT)|=(1 << RS485TXEn); // SCI发送使能
#define Run_LED PORTREG(LEDPORT)^= (1 << LEDPORTNo); // boot运行LED
//---------------------------------------------------//
//定义Xmoden控制字符
#define XMODEM_NUL 0x00 // null
#define XMODEM_SOH 0x01 // Xmodem数据头
#define XMODEM_STX 0x02 // Xmodem_1K数据头
#define XMODEM_EOT 0x04 //发送结束
#define XMODEM_ACK 0x06 //认可响应
#define XMODEM_NAK 0x15 //不认可响应
#define XMODEM_CAN 0x18 //撤销传送
#define XMODEM_EOF 0x1A //填充数据包
#define XMODEM_RWC 'C' // CRC16-128
//-------------------------------------------------------//
#ifdef Xmodem_1K
#define BUFFER_SIZE 1024
#else // Xmodem
#define BUFFER_SIZE 128
#endif
//-----------------------------------------------------//
#ifdef ATMEGA32
#define SPM_PAGESIZE 128 // SPM页大小
#define BootStart 0x3C00*2 //按字节
#define SPM_REG SPMCR // SPM寄存器
#endif
#ifdef ATMEGA64
#define SPM_PAGESIZE 256 // SPM页大小
#define BootStart 0x7C00*2 //按字节
#define SPM_REG SPMCSR // SPM寄存器
#endif
#ifdef ATMEGA128
#define SPM_PAGESIZE 256 // SPM页大小
#define BootStart 0xFC00*2 //按字节
#define SPM_REG SPMCSR // SPM寄存器
#endif
//接收缓冲区大小不能小于SPM_PAGESIZE
#if BUFFER_SIZE < SPM_PAGESIZE
#define BUFSIZE SPM_PAGESIZE // UART数据缓存
#else
#define BUFSIZE BUFFER_SIZE // UART数据缓存
#endif
//计算和定义波特率设置参数
#define BAUD_SETTING (unsigned char)((unsigned long)CRYSTAL/(16*(unsignedlong)BAUDRATE)-1)
#define BAUD_H ((unsigned char)(BAUD_SETTING>>8))
#define BAUD_L (unsigned char)BAUD_SETTING
//计算T1定时器设置参数
#define T1_TCNT (unsigned int)((unsigned long)CRYSTAL*250/(64*1000));
//--------------------------------------------------------//
#endif// _AVR_BOOT_H_
#ifndef _CONFIG_H_
#define _CONFIG_H_ 1
//*********************************************************//
//关于上海霜蝉-AVR_bootV1.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、支持开门狗自定义开关,自定义时钟频率
//*********************************************************//
//注意:修改编译器配置(char to int;char is unsigned)
//注意:填充数据必须大于两包(>=256)
//定义芯片型号
//芯片型号选择
//#define ATMEGA32
#define ATMEGA64 //已测试Atmgea64L
//#define ATMEGA128
//协议类型选择:Xmodem或Xmodem_1K
#define Xmodem // Xmodex 128(CRC16)
//#define Xmodem_1K // Xmodem 1024(CRC16)
//-----------------------------------------------//
//系统时钟MHz
#ifndef CRYSTAL
#define CRYSTAL 16000000 // 16M
#endif
//波特率38400~2400
#define BAUDRATE 9600
//等待密码的超时时间= WiteTimeCnt * 250ms
//超时次数
#define WiteTimeCnt 10 // 10=2.5s
//用户设置boot驻留等待握手时间(1=250ms)+2.5S(WiteTimeCnt)
#define Wait_BootTime 40 // (1=250ms)+2.5S
//等待文件的超时时间= TimeOutCntC * 250ms
//发送'C'的最大次数
#define TimeOutCntC 40 // 40=1min
//串口号(ATMEA32串口号为空)
#define COMPORTNo 0 // UART0
//看门狗使能
#define WDGEn 1 //使用看门狗
//使用485模式
#define RS485_En 1 //使用485使能脚
// 485控制端口和引脚
#define RS485PORT E // PORTE
#define RS485TXEn 2 // PORTE2
//使用LED指示状态
#define Run_LEDEn 1 //使能boot运行LED指示
// LED控制端口和引脚
#define LEDPORT B // PORTB
#define LEDPORTNo 6 // PORTB6
//延时用于解决串口数据出错
#define Delay_En 0
//用户设置boot驻留等待握手时间(1=250ms)+2.5S(WiteTimeCnt)
//使此功能需要设置EEPROM
#define Wait_BootTime 40 // (40*250ms)+2.5S
#define EE_TimeAddr 0 //使用EEPROM占用1个字节
//安全升级(升级不成功不进入用户区)
//使此功能需要设置EEPROM
#define SafeUpdated_En 1
#define EE_SafeAddr 1 //使用EEPROM占用1个字节
//-----------------------------------------------//
#endif// _CONFIG_H_
//End of file: bootcfg.h