⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main._c

📁 BootLoad_Pei&Ecirc &Ccedil ICC&micro &Auml &Ocirc &acute &acute ú&Acirc &euml &pound &not MegaLoad
💻 _C
字号:
/******************************************************************************
Atmega8、16 BootLoad程序  
日  期:2004年的最后一天
肖  鹏  www.527dz.com  527dz@527dz.com

/*****************************************************************************/

//修改pei2005.6.24
//1.针对W0和W1的硬件进行修改,主要是使用晶振、修改Baud、关无线模块
//2.增加:用户区无程序时不跳出Boot循环
//3.修正Bug:原GetPageNumber()由于移位的原因,PageAddress!=0xffff,即FlashLoad()无法退出
//4.增加:Page地址比较重要,也要效验

#include <macros.h>
#include "assembly.h"

#define W0
//×××××××××××××××××××××××××××××××××××××××××××××××××××××××××
//请根据目标板选择芯片型号
#ifdef W0
 #define  ChipType     Atmega8
#else       
 #define  ChipType     Atmega16
#endif       
//#define  ChipType     Atmega32       
//#define  ChipType     Atmega64       
//#define  ChipType     Atmega128       
//#define  ChipType     Atmega8535       
//*********************************************************
//选择BOOT区大小
//#define  BootSize     'a'    //128   
//#define  BootSize     'b'    //256
#define  BootSize       'c'    //512
//#define  BootSize     'd'    //1024
//#define  BootSize     'e'    //2048(不知道是否有2048字BOOT空间的芯片)
//选择BootLoad版本号
//#define  BootVer        'f'    //1.0版本
#define  BootVer      'g'    //1.1版本 pei
//#define  BootVer      'h'    //1.2版本
//#define  BootVer      'i'    //1.3版本
//#define  BootVer      'j'    //1.4版本
//#define  BootVer      'k'    //1.5版本
//#define  BootVer      'l'    //1.6版本
//#define  BootVer      'm'    //1.7版本
//#define  BootVer      'n'    //1.8版本
//#define  BootVer      'o'    //1.9版本
//#define  BootVer      'p'    //2.0版本(应该是最终版本了)
//**********************************************************
#define  Atmega8        0x30
#define  Atmega16       0x31
#define  Atmega32       0x32
#define  Atmega64       0x33
#define  Atmega128      0x34
#define  Atmega8535     0x35
//*****************************************************************************
//#define  InteClk                 //是否使用内部时钟
#define  OscAddress     0x1fff   //时钟校准值存储地址
//#define  OscAddress     0x3fff   //时钟校准值存储地址
//*****************************************************************************
//8时钟下的波特率设置
//#define  BAU  103    //4800
//#define  BAU  51       //9600
//#define  BAU  34     //14400
//#define  BAU  25     //19200
//*****************************************************************************

//11.0592M pei
#define BAU 35 //pei baud19200
//#define BAU 17 //pei baud38400

#if (ChipType == Atmega8)
  #include  "iom8v.h"
  #define   PageByte 	 	 64 
  #define   AddressShift	 6
#endif

#if (ChipType == Atmega16)
  #include  "iom16v.h"
  #define   PageByte 	 	 128    
  #define   AddressShift 	 7
#endif

void          FlashLoad        (void);
void          GetPageNumber    (void);
void          ExecCode         (void);
char          GetPage          (void);
void          WriteFlash       (void);
char          CheckFlash       (void);
void          SendChar         (unsigned char c);
void          delay            (void);                 //1ms延时函数
unsigned char RecChar          (void);

unsigned char PageBuffer[PageByte];
unsigned int  PageAddress;

/*****************************************************************************/
//Flash编程								                     
/*****************************************************************************/
void FlashLoad(void)
  {unsigned char AddH,AddL;
    SendChar('!');
    while (1)
      {
	//GetPageNumber();//bug!由于移位的原因,PageAddress!=0xffff
	//if (PageAddress == 0xffff) return;//退不出了:) 
        
	if (GetPage())
	  { 
	    if (PageAddress == 0xffff) return;//pei Page地址读取和判断加到GetPage()中了
	  
	    WriteFlash();
	    if (CheckFlash()) SendChar('!');
	    else SendChar('@');
	  }
	else SendChar('@');
      }
  }

/****************************************************************************
void GetPageNumber(void)
  {
    unsigned char PageAddressH;
    unsigned char PageAddressL;

    PageAddressH = RecChar();

    PageAddressL = RecChar();
	
	PageAddress=((int)((PageAddressH << 8) + PageAddressL))<<AddressShift;
  }

/*****************************************************************************/
char GetPage(void)
  {
    unsigned char i,AddH,AddL;
    unsigned char LocalCheckSum = 0;
    unsigned char CheckSum = 0;

	AddH=RecChar();AddL=RecChar();
	PageAddress=(AddH<<8)+AddL;
	if (PageAddress==0xffff) return 1;//exit..
	PageAddress=PageAddress<<AddressShift;
	LocalCheckSum=AddH+AddL;//考虑Page的效验
	
    for (i=0;i<PageByte;i++)
	{
	PageBuffer[i]=RecChar();
	LocalCheckSum += PageBuffer[i];
   	}
		   
    CheckSum = RecChar(); 
    if (LocalCheckSum == CheckSum) return 1;
    else return 0;
  }

/*****************************************************************************/
void WriteFlash(void)
  {
    unsigned int i;
    unsigned int TempInt;

    for (i=0;i<PageByte;i+=2)
      {
   	TempInt=PageBuffer[i]+(PageBuffer[i+1]<<8);
   	fill_temp_buffer(TempInt,i);    //call asm routine.
      }
	
    write_page(PageAddress,0x03);       //擦除页
    write_page(PageAddress,0x05);       //写页数据
   
    enableRWW();
  }

/*****************************************************************************/

char CheckFlash(void)
  {
    unsigned char i;							
    unsigned int TempInt;
    unsigned int TempInt2;

    for (i=0;i<PageByte;i+=2)
      {
	TempInt = read_program_memory(PageAddress + i,0x00);
	TempInt2 = PageBuffer[i] +(PageBuffer[i+1]<<8);
	if (TempInt != TempInt2) return 0;
      }
    return 1;
  }

/*****************************************************************************/
/*  		字符输入函数 		 */	
unsigned char RecChar(void)
  {
     while(!(UCSRA & 0x80));
     return UDR;
  }		
/*****************************************************************************/
void SendChar(unsigned char c)
  {	 
    while (!(UCSRA&(1<<UDRE)));
    UDR=c;
  }
void delay(void)  
  {
    unsigned int i;
    for (i=0;i<65530;i++);
  }

/*****************************************************************************/
void ExecCode(void)
  {
    GICR=0X01;           //中断向量表移位允许
    GICR=0X00;           //中断向量指向应用程序区
    asm("jmp 0x0000");              
  }
		
void main(void)
  {
    unsigned char BootFlag;
    unsigned int TempInt;
	char iTry;
	
    #ifdef InteClk                //如果使用内部时钟,读取时钟校准值
       OSCCAL=read_flash(OscAddress);
    #endif

#ifdef W0	
 //pei 拷贝W0的PortInit
 	PORTB = 0x0F;//rfslp,fs123=1
 	DDRB  = 0xFF;//bit1=output
 	PORTC = 0x21;//0x20;//rfrst=1,not reset! 
 	DDRC  = 0x7F;
 	PORTD = 0x0C;
 	DDRD  = 0xF0;
#else
#endif
    
    UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //8位数据+1位停止
    UCSRB = (1<<RXEN)|(1<<TXEN);       //允许串口发送和接收
    UBRR = BAU;

	iTry=20;
STARTBOOT://pei未下载程序时重复等待
#ifdef W0	
    PORTC=PORTC^0x03;
#endif
	
    SendChar('>');              //通知PC机,BOOT下载准备就绪
    delay();                    //延时等待PC机响应
    BootFlag=UDR;
    if (BootFlag == '<') 
      {
	     SendChar(ChipType);
         SendChar(BootSize);
         SendChar(BootVer);
         while (1)
	   {
	     switch (RecChar())
	       {
	         case 'W': FlashLoad();
			 	   break;
	         case 'E': { 
	         	     SendChar('E');  //通知PC机,进入运用程序区
	         	     ExecCode();  
	         	   } break;
	         default : break;
	       }
	   }
      }
    SendChar('E');  //通知PC机,进入运用程序区
	
	TempInt = read_program_memory(0,0);//pei
	if (TempInt==0xFFFF) goto STARTBOOT;
	  else{ iTry--;
	        if (iTry>0) goto STARTBOOT;}
	
    ExecCode();
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -