基於AVR-BootLoader,通過霜蟬遠程串口可實現單片機的遠程升級

最近一直利用業餘時間寫自己的“基於AVR-BootLoader”,啓發是由於一次在ourAVR論壇看到了紹子陽的bootloader,聯想到公司在用AVR MCU,但每次升級程序都要花費很大的力氣車馬勞頓的跑到工程現場,而且很多機器還安裝在國外,爲了升級一次程序發費了很多的人力物力財力,加上公司的機器目前大部分都配有遠程監控系統,所以本人決定寫一個具有自有產權的“AVR-BootLoader”。

      
特別說明:本“AVR-BootLoad”軟件代碼屬上海霜蟬版權所有,在此貢獻發佈,僅限於個人免費使用不得用於商業用途,本人也不保證代碼的嚴謹性,如在升級中出現任何問題與本人無關,本人已測試過Atmega64A與Atmega128。話不多說了上源代碼,網友們和AVR愛好者可以拷貝到CodeWizardAVR V2.03.9編譯器下編譯。
需要討論或有遇到BUG的網友們可以聯繫我:QQ:285247488  mail:[email protected] 

上位機截圖:


遠程升級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
//--------------------------------------------------//
// 
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
//-----------------------------------------------//
//""退Bootloader0x0000
    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退for21S+2S
                    if(Frame_State==0x06)break;
                }
                crc16 = Wait1S_UART();
                crc16=crc16<<8;
                crc16 += Wait1S_UART();                     // 2CRC
                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
}
// 250msTime1
//-----------------------------------------------//
//使11024CTC4
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);
}
//-----------------------------------------------//
//退Bootloader0x0000
void quit_boot(void)
{
     MCUCR = 0x00;                  //IVSEL "0“ Flash 
     #ifdef ATMEGA128
     RAMPZ = 0x00;                  //0: ELPM/SPM $0000 - $7FFF ( 64K )
     #endif
     #asm("jmp 0x0000")             //Flash0x0000
}
//-----------------------------------------------//
// EEPROM
uchar EEPROM_Read(uint Addr)            // EEPROM1   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")                     // EEMPE1,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      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);    // bootLED
//---------------------------------------------------//
//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
// 1V1.00 CodeWizardAVR V2.03.9 Standard;
// 2AVR;
// 3XmodemXmodem_1K;
// 4"00",1;
// 53S退bootboot;
// 61;
// 710;
// 8;
// 9 1 ;
// 10 10 ;
// 116S;
// 12Boot Loader - Size:1024words;
// 1338.400KB/S2.400KB/S;
// 14持上海霜蟬ATMEGA32,64,128
// 15,
//*********************************************************//
//  (char to int;char is unsigned)
// >=256
// 
// 
//#define   ATMEGA32
#define ATMEGA64                // Atmgea64L
//#define   ATMEGA128
// XmodemXmodem_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                // 使bootLED
// 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章