完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
AVR-BootLoader的源代码是什么?
远程升级DTU是如何连接云平台虚拟串口的? 如何去实现一种基于AVR-BootLoader的远程升级DTU设计? |
|
相关推荐
1个回答
|
|
最近一直利用业余时间写自己的“基于AVR-BootLoader”,启发是由于一次在ourAVR论坛看到了绍子阳的bootloader,联想到公司在用AVR MCU,但每次升级程序都要花费很大的力气车马劳顿的跑到工程现场,而且很多机器还安装在国外,为了升级一次程序发费了很多的人力物力财力,加上公司的机器目前大部分都配有远程监控系统,所以本人决定写一个具有自有产权的“AVR-BootLoader”。
本人已测试过Atmega64A与Atmega128。话不多说了上源代码,网友们和AVR爱好者可以拷贝到CodeWizardAVR V2.03.9编译器下编译。 上位机截图: 远程升级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. http://www.hpinfotech.com 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 =0 b00011111 ; // 看门狗 使能位修改 使能(B4=1) 2.0S(F) WDTCR =0 b00000111 ; // 禁止看门狗 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 《mega32.h》 #endif #ifdef ATMEGA64 #include 《mega64.h》 #endif #ifdef ATMEGA128 #include 《mega128.h》 #endif //---------------------------------------------------// typedef signed char schar ; typedef signed int sin t ; 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 |
|
|
|
只有小组成员才能发言,加入小组>>
2513 浏览 0 评论
1083浏览 2评论
699浏览 1评论
452浏览 0评论
193浏览 0评论
328浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-21 19:28 , Processed in 1.341936 second(s), Total 79, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号