www.pudn.com > C8051F020UPDATA.rar > C8051F020UPDATA.c


#include "c8051f020.h"                 // SFR declarations 
//#include                      // printf() and getchar() 
#include  
#include                      // tolower() and toint() 
#include  
#include  
 
#if 0 
	#define HOST_DEVICE 
#else 
	#define SUB_DEVICE 
#endif 
//----------------------------------------------------------------------------- 
// Global CONSTANTS 
//----------------------------------------------------------------------------- 
#define TRUE         1 
#define FALSE        0 
 
#define SYSCLK       22118400          // SYSCLK frequency in Hz 
#define BAUDRATE     9600           // Baud rate of UART in bps 
//----------------------------------------------------------------------------- 
// Function PROTOTYPES 
//----------------------------------------------------------------------------- 
void main (void); 
 
void erase_flash(void); 
void receive_code(void); 
void write_code(void); 
void Write_Code (void); 
unsigned char hex2char(); 
unsigned char  getChar (void); 
void  putChar(unsigned char c); 
void  getStr (void *str,unsigned char startchar,unsigned char endchar); 
void putStr (unsigned char *str,unsigned char len); 
 
// Initialization Subroutines 
void SYSCLK_Init (void); 
void PORT_Init (void); 
#ifdef 	 HOST_DEVICE 
void UART0_Init (void); 
#else 
void UART1_Init (void); 
#endif 
//----------------------------------------------------------------------------- 
// Global VARIABLES 
//----------------------------------------------------------------------------- 
bit code_erased = FALSE;               // flag used to indicate that the FLASH 
                                       // erase operation is complete 
bit f_valid = FALSE;                   // flag to indicate that the FLASH  
                                       // programming operation is complete 
bit code_receive = FALSE ; 
unsigned char boot_buf[23]; 
unsigned char xdata boot_ram[32700]; 
unsigned int  xramrel = 0; 
 
code unsigned char updata00[]="Xready000X"; 
code unsigned char updata01[] ="XstartX"; 
code unsigned char *erro[] = {"Xerr01X","Xerr02X","Xerr03X","Xerr04X"}; 
 
//----------------------------------------------------------------------------- 
// MAIN Routine 
//----------------------------------------------------------------------------- 
 
void main (void)  
{ 
	char input;    
                                            	WDTCN = 0xde;                       // disable watchdog timer 
	WDTCN = 0xad; 
	EA = 0;                             // disable interrupts (this statement 
	SYSCLK_Init ();                     // initialize oscillator 
	PORT_Init ();                       // initialize crossbar and GPIO 
	#ifdef 	 HOST_DEVICE				    // initialize UART0 
		UART0_Init (); 
	#else 
		UART1_Init (); 
	#endif 
 
//	boot_ram[0x1050] =10; 
//	input =  boot_ram[0x1050] ; 
 
	putStr("   ",3);  //解决第一次发送有缺少字符现象 
 
	while (1){ 
		getStr (boot_buf,'X','X'); 
		input = memcmp ( boot_buf,updata00, 6); 
		if(!input) 
		{ 
			putStr("Xready00X",9);   
			getStr (boot_buf,'X','X'); 
		} 
		input = memcmp ( boot_buf,updata01, 7); 
		if(!input)  
		{ 
			receive_code(); 
			if(code_receive) 
				erase_flash(); 
			else 
				RSTSRC = 0x10; 
			if (code_erased) 
				Write_Code (); 
			if (f_valid) 
				RSTSRC = 0x10; 
		}  
	} // end while	  
} // end main 
//----------------------------------------------------------------------------- 
// hex2char 
//----------------------------------------------------------------------------- 
// This routine converts a two byte ascii representation of a char to an 
// 8-bit variable; 
unsigned char hex2char() 
{ 
   unsigned char retval; 
   char byteH, byteL; 
   // get a two-byte ASCII representation of a char from the UART 
   byteH = getChar(); 
   byteL = getChar(); 
   // convert to a single 8 bit result 
   retval = (char) toint(byteH) * 16; 
   retval += (char) toint(byteL); 
   return retval; 
} 
//----------------------------------------------------------------------------- 
// erase_flash 
//----------------------------------------------------------------------------- 
// This routine erases the first 8 pages of FLASH (0x0000 to 0x0FFF). 
void erase_flash(void) 
{ 
   char xdata* data pagePointer = 0;// a pointer to xdata located in data space 
   int i;                           // temporary int 
   FLSCL |= 0x01;                   // enable FLASH write/erase 
   PSCTL  = 0x03;                   // MOVX erases FLASH 
   // Erase the first 8 FLASH pages 
   for (i = 0; i < 64; i++){ 
      *pagePointer = 0;             // initiate the erase 
      pagePointer += 512;           // advance to next FLASH page 
   } 
   pagePointer = 0xefff; 
   *pagePointer = 0; 
   PSCTL = 0x00;                    // MOVX writes target XRAM 
   FLSCL &= ~0x01;                  // disable FLASH write/erase 
   f_valid = FALSE;                 // indicate that code is no longer valid 
   code_erased = TRUE;              // indicate that FLASH has been erased 
} 
//----------------------------------------------------------------------------- 
// receive_code 
//----------------------------------------------------------------------------- 
void receive_code(void) 
{ 
	unsigned char len;                     
	unsigned int offset;                   
	unsigned char flash_checksum;                   
	unsigned char c,i;                                
	unsigned char errosum=0,errno; 
	unsigned int number=0; 
	memset ( boot_ram , 0 , 32700 ); 
	memset ( boot_buf , 0 , 23);	 
	//开始接收数据; 
	putStr("XstartX",7);  
   // wait for the user send HEX file 
	while(1) 
	{ 
		errno = 0; 
		while( (c = getChar()) != ':' );       
		boot_buf[0] = c;   
		len = hex2char(); 
		boot_buf[1] = len; 
	    for( i = 2; i < (4+len+1+1); i++) 
			boot_buf[i] = hex2char();         // write one byte to FLASH 
		flash_checksum = 0; 
		for (i=1;i<(4+len+1+1);i++) 
			flash_checksum += boot_buf[i]; 
      	if(flash_checksum != 0) 
			errno = 3; 
		else{	 
			offset = (boot_buf[2]<<8 )|boot_buf[2]+boot_buf[2]; 
			if((offset+len)>=0x8000) 
				errno = 2 ;  // print error message 
			else{  
				if (boot_buf[4])  //如果数据类型 
				{ 
					if(boot_buf[4] == 1) 
						if((len==0)&&(offset==0)) 
						{ 
							for(i=0;i<(4+len+1+1);i++) 
								boot_ram[number++] = boot_buf[i]; 
							code_receive = TRUE; 
							putStr("XokX",4); 
							return; 
						} 
	         		errno = 1 ;  
		 		} 
			} 
		} 
		//有错误,上传错误,错误大于三次重启 
	  	if(errno) 
		{ 
			errosum++; 
			if(errosum>=3) 
	   			RSTSRC = 0x10;  
			else 
				putStr(erro[errno],7); 
		} 
		else{  
      		for(i=0;i<(4+len+1+1);i++) 
			{ 
				boot_ram[number++] = boot_buf[i]; 
			} 
			putStr("XokX",4); 
			errosum=0; 
		} 
   }  
    
} 
//----------------------------------------------------------------------------- 
//write code 
//----------------------------------------------------------------------------- 
void Write_Code (void) 
{ 
	unsigned char i = 0,k = 0; 
	unsigned int  j,n = 1; //指向第一个“:”后的第一个数据 
	unsigned char xdata *address ; 
	// make sure FLASH has been erased    
	if(!code_erased){ 
		putStr("Xerr01X",7); 
		RSTSRC = 0x10;  
	} 
	k = boot_ram[n]; //读第一行的数据长度 
	while(1) 
	{ 
		//***读外部RAM************** 
		for(i = 0;i < (k+4+1);i++){ 
			boot_buf[i] = boot_ram[n]; 
			n++; 
		} 
		if(!boot_buf[0]){  //写完Flash,发送升级完成信息,软件强制复位 
			if ((boot_buf[1]==0)&&(boot_buf[2]==0)) 
			{ 
				FLSCL = ((FLSCL&0xF0)|0x09); 
				PSCTL = 0x01;              //允许Flash写操作 
				address = 0xefff; 
				*address = 0xa5; 
				PSCTL = 0x00; 
				FLSCL = (FLSCL&0xFE); 
				f_valid = TRUE;           // indicate that download is valid  
				putStr("XsucceedX\n",10); 
			} 
			return; 
		} 
		j = boot_buf[1]; 
		j = j<<8;  
		address = j | boot_buf[2]; //将要下载到Flash的地址 
 
		FLSCL = ((FLSCL&0xF0)|0x09); 
	    PSCTL = 0x01;              //允许Flash写操作 
		for(i = 0; i< boot_buf[0];i++){ 
			*address = boot_buf[i+4]; 
		    address++; 
	    } 
		PSCTL = 0x00; 
		FLSCL = FLSCL&0xFE; 
		i=0; 
		while(boot_ram[n] != ':') 
		{ 
			n++; 
			i++; 
			if(i>10)	 
				RSTSRC = 0x10;	 
		} 
		 
		n++; 
		k = boot_ram[n];  
	}	 
 
}	 
//----------------------------------------------------------------------------- 
// SYSCLK_Init 
//----------------------------------------------------------------------------- 
void SYSCLK_Init (void) 
{ 
   int i;                              // delay counter 
 
   OSCXCN = 0x67;                      // start external oscillator with 
                                       // 22.1184MHz crystal 
 
   for (i=0; i < 256; i++) ;           // wait for osc to start 
 
   while (!(OSCXCN & 0x80)) ;          // Wait for crystal osc. to settle 
 
   OSCICN = 0x88;                      // select external oscillator as SYSCLK 
} 
//----------------------------------------------------------------------------- 
// PORT_Init 
//----------------------------------------------------------------------------- 
// Configure the Crossbar and GPIO ports 
void PORT_Init (void) 
{ 
   XBR0    = 0x07;                     	// Enable UART0,SPI,SMB0 
   XBR1    = 0x00;					   	// 
   XBR2    = 0xC4;                     	// Enable UART1 
   P0MDOUT = 0xFD;                    	//  
   P1MDOUT = 0xB9;                    	//  
   P2MDOUT = 0x02;                    	// 									   	 
   P3MDOUT = 0xff;                    	// 
   P74OUT  = 0x02;						// 
   EMI0CF = 0x24;	//use XRAM and multiplexed address/data mode,External Only,1 SYSCLK cycle 
} 
//----------------------------------------------------------------------------- 
// UART0_Init 
//----------------------------------------------------------------------------- 
// Configure the UART0 using Timer1, for  and 8-N-1. 
#ifdef 	 HOST_DEVICE 
 
void UART0_Init (void) 
{ 
   SCON0   = 0x50;                     // SCON0: mode 1, 8-bit UART, enable RX 
   TMOD    = 0x20;                     // TMOD: timer 1, mode 2, 8-bit reload 
   TH1    = -(SYSCLK/BAUDRATE/16);     // set Timer1 reload value for baudrate 
   TR1    = 1;                         // start Timer1 
   CKCON |= 0x10;                      // Timer1 uses SYSCLK as time base 
   PCON  |= 0x80;                      // SMOD00 = 1 
   TI0    = 1;                         // Indicate TX0 ready 
} 
//****************************************************************** 
//串口1接收字符 
//****************************************************************** 
unsigned char  getChar (void) 
{ 
	unsigned char c,time=0; 
	unsigned int delay=0; 
 	while (RI0==0) 
	{ 
		delay++; 
		if(delay>=62250) 
		{	 
			delay = 0; 
			time++; 
			if(time >=180 ) 
				RSTSRC = 0x10; 
		} 
	} 
	RI0=0; 
	c=SBUF0; 
	return c; 
} 
//*************************************************************************** 
//串口1发送字符 
//*************************************************************************** 
void  putChar(unsigned char c) 
{ 
 	SBUF0 = c; 
	while (TI0==0); 
 
	TI0=0; 
} 
#else 
//******************************************************************************* 
//UART1_Init  
//******************************************************************************** 
// Configure the UART1 using Timer4, for  and 8-N-1. 
void UART1_Init (void) 
{ 
   SCON1  = 0x50;                      // SCON1: mode 1, 8-bit UART, enable RX 
   T4CON  = 0x30;                      // Stop Timer; clear int flags; enable 
                                       // UART baudrate mode; enable 16-bit  
                                       // auto-reload timer function; disable 
                                       // external count and capture modes 
   RCAP4  = -(SYSCLK/BAUDRATE/32);     // set Timer reload value for baudrate 
   T4     = RCAP4;                     // initialize Timer value 
   CKCON |= 0x40;                      // Timer4 uses SYSCLK as time base 
 
   T4CON |= 0x04;                      // TR4 = 1; start Timer4 
   PCON  |= 0x10;                      // SMOD1 = 1 
   EIE2  |= 0x40;                      // enable UART1 interrupts 
} 
//****************************************************************** 
//串口2接收字符 
//****************************************************************** 
unsigned char  getChar (void) 
{ 
	unsigned char c,time=0; 
	unsigned int delay=0; 
 	while (RI1_READ==0) 
	{ 
		delay++; 
		if(delay>=62250) 
		{	 
			delay = 0; 
			time++; 
			if(time >=180 ) 
				RSTSRC = 0x10; 
		} 
	} 
	RI1_CLR0; 
	c=SBUF1; 
	return c; 
} 
//*************************************************************************** 
//串口2发送字符 
//*************************************************************************** 
void  putChar(unsigned char c) 
{ 
 	SBUF1 = c; 
	while (TI1_READ==0); 
	TI1_CLR0; 
} 
#endif 
//****************************************************************** 
//串口接收字符串 
//****************************************************************** 
void getStr (void *str,unsigned char startchar,unsigned char endchar) 
{ 
 	unsigned char c; 
	unsigned char *pt; 
	pt=(unsigned char *)str; 
	while ((c=getChar()) != startchar); 
	do{ 
		*pt = c; 
		pt++; 
		c=getChar(); 
	}while(c != endchar ); 
	*pt = c;  
} 
//****************************************************************** 
//串口发送字符串 
//****************************************************************** 
void putStr (unsigned char *str,unsigned char len) 
{ 
 	unsigned char i; 
	for (i=0;i