/*****************************************************
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
//--------------------------------------------------//
// 全局变量定义
uchar RX_buff[BUFSIZE]; // 数据拉收缓存
uchar Frame_State,SOH_Wait_cnt; // 帧状态,帧头等待计数
uint Time_cnt,Error_cnt; // 超时计数,连续帧错误计数
uint buffptr,buffptr_old,buffptr_New; // 数据缓存指针必须大于1024
ulong FlashAddr; // Flash地址
uchar UpdatedSta; // 升级标志
//-----------------------------------------------//
//擦除(code=0x03)和写入(code=0x05)一个Flash页
void boot_page_ew(ulong p_address,char code)
{
#asm
ldd r26,y+1 ; R26 LSB
ldd r27,y+2 ; R27 MSB
#endasm
SPM_REG = code; // 寄存器SPMCSR中为操作码
#asm
mov r30,r26
mov r31,r27
#endasm
#ifdef ATMEGA128
RAMPZ=(p_address>>16); // RAMPZ0 = 1: ELPM/SPM 可以访问程序存储器地址$8000 - $FFFF ( 高64K 字节)
#endif
#asm("spm"); // 对指定Flash页进行擦操作
}
//填充Flash缓冲页中的一个字
void boot_page_fill(uint A_address,uint data)
{
#asm
LDD R30,Y+2 ; R30 LSB
LDD R31,Y+3 ; R31 MSB
LD R26,Y
LDD R27,Y+1
MOV R0,R26
MOV R1,R27
MOV R26,R30
MOV R27,R31
#endasm
SPM_REG =0x01; //寄存器SPMCSR中为操作码
#asm
mov r30,r26
mov r31,r27
#endasm
#asm("spm"); //对指定Flash页进行擦操作
}
//等待一个Flash页的写完成
void wait_page_rw_ok(void)
{
while(SPM_REG & 0x40)
{
while(SPM_REG & 0x01);
SPM_REG = 0x11;
#asm("spm");
while(SPM_REG & 0x01);
}
}
//-----------------------------------------------//
//更新一个Flash页的完整处理
void write_one_page(uchar data[])
{
uint i;
boot_page_ew(FlashAddr,0x03); //擦除一个Flash页
wait_page_rw_ok(); //等待擦除完成
for(i=0;i<SPM_PAGESIZE;i+=2) //将数据填入Flash缓冲页中 按字填充
{
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超时自动转为应答
unsigned char Wait1S_UART()
{
uchar i=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;
return UDRREG(COMPORTNo); // 读取UDR0
}
}
while(100!=i); // 等待数据||超时退出
}
//***************************************************//
//===================================================//
void main(void)
{
uchar packNO,packNO_old; // 包号、包号留存
uint crc16; // 接收CRC缓存
uint li; // 帧计数
uchar ch, 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) // 帧状态
{
case 0x00: // 接受状态 帧头与停止信号判断
{
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<buffptr_New;) // 判断上一帧数据尾16个正确性以决定是否重传
{
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;
case 0x01: //包序号校验
{
ch = Wait1S_UART(); // 获取包序号
cl = ~Wait1S_UART();
if(ch == cl) // 包号对比
{ Frame_State=0x02;
packNO=ch; // 正确保留包号
}
else
{ Frame_State=0x06; } // 重发应答ANK
}
break;
case 0x02: // 进入二级CRC校验
{
for(li = 0; li < BUFFER_SIZE; li++) // 接收完整一帧数据 (128字节)
{
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;
case 0x03: // 校验通过,执行写入
{
if(FlashAddr < BootStart) //避免写入Boot区
{
#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;
case 0x04: //读取写入的Flash内容并和下载的缓冲区比较
{
Frame_State=0x05; // 转为应答状态
buffptr_old=buffptr; // 写入正常才记录数据指针
}
break;
case 0x05: // 正确应答ACK
{
packNO_old=packNO; // 接收完整一帧保留本次包号
Send_UART(XMODEM_ACK); // 认可应答
//WriteCom(packNO); // 测试
//WriteCom(FlashAddr); // 测试
//WriteCom(FlashAddr>>8); // 测试
Error_cnt = 0; // 清除连续错误计数
Frame_State=0x00; // 转为帧接收(请求)状态
}
break;
case 0x06: // 错误=重发应答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" // 头文件包含
//-----------------------------------------------//
//----------初始化-------------------------------//
// 输出端口初始化
void PORT_Init()
{
// 上电默认全为输入口
// 输出口设置
#if Run_LEDEn
DDRREG(LEDPORT)|=(1 << LEDPORTNo); // 指示灯
#endif
}
//-----------------------------------------------//
// 串口初始化
void UART_Init()
{
#if RS485_En
DDRREG(RS485PORT)|=(1 << RS485TXEn); // 设置(PC5)RS485方向控制引脚为输出
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,产生以毫秒为单位的时间
void Time1_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
void WatchDog_Enable(void)
{
// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/2048k
MCUCSR=0x00; // 控制与状态寄存器
WDTCR=0x1F; // 看门狗使能 500ms(D)1.0S(E) 2.0S(F)
WDTCR=0x0F;
}
// 禁止看门狗
void WatchDog_Disenable(void) // 禁止看门狗
{
MCUCSR=0x00; // 控制与状态寄存器
WDTCR=0b00011111; // 看门狗 使能位修改 使能(B4=1) 2.0S(F)
WDTCR=0b00000111; // 禁止看门狗 2.0S(7)
}
// 喂狗
void Watchdog_Reset(void)
{ #asm("wdr") } // 喂狗
//-----------------------------------------------//
//-------------子函数----------------------------//
//写入数据到串口
void Send_UART(unsigned char dat)
{
uchar i;
#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
}
//-----------------------------------------------//
//等待串口数据(注意是”死等“)
unsigned char Wait_UART()
{
while(!(UCSRAREG(COMPORTNo) & 0x80)); // 等等数据到来 Bit 7 – RXC: USART 接收结束
UCSRAREG(COMPORTNo)|=0x80; // 清除接收完成状态
#if Run_LEDEn
Run_LED; // 运行LED闪烁
#endif
return UDRREG(COMPORTNo);
}
//-----------------------------------------------//
//计算CRC
int CRC16_Word(char *ptr, int count)
{
int crc = 0;
char i;
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处执行应用程序
void quit_boot(void)
{
MCUCR = 0x00; //当IVSEL 为"0“ 时,中断向量位于Flash 存储器的起始地址;
#ifdef ATMEGA128
RAMPZ = 0x00; //0: ELPM/SPM 可以访问程序存储器地址$0000 - $7FFF ( 低64K 字节)
#endif
#asm("jmp 0x0000") //跳转到Flash的0x0000处,执行用户的应用程序
}
//-----------------------------------------------//
// 读EEPROM一个字节
uchar EEPROM_Read(uint Addr) // EEPROM读1个字节操作 0
{
while(EECR & 0x02); // 等待上一次写操作结束
EEAR = Addr; // 设置地址寄存器
EECR |= 0x01; // 设置EERE 以启动读操作 b0
return(EEDR); // 自数据寄存器返回数据
}
// 写EEPROM一个字节
void EEPROM_Write(uint Addr,char Data) // 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
//---------------------------------------------------//
typedef signed char schar;
typedef signed int sint;
typedef signed long slong;
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
//--------------------------------------------------//
// 函数申明
void UART_Init();
void PORT_Init();
void Time1_Init();
void Send_UART(unsigned char dat);
unsigned char Wait_UART();
unsigned char Wait1S_UART();
void WatchDog_Disenable(void);
void quit_boot(void);
int CRC16_Word(char *ptr, int count);
void write_one_page(uchar data[]);
void WatchDog_Enable(void);
void Watchdog_Reset(void);
uchar EEPROM_Read(uint Addr);
void EEPROM_Write(uint Addr,char Data);
//--------------------------------------------------//
//内部使用的宏定义
#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*(unsigned long)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
文章评论(0条评论)
登录后参与讨论