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

📄 c8051f020updata.c

📁 C8051F020
💻 C
字号:
#include "c8051f020.h"                 // SFR declarations
//#include <stdio.h>                     // printf() and getchar()
#include <stdlib.h>
#include <ctype.h>                     // tolower() and toint()
#include <string.h>
#include <intrins.h>

#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 <baudrate> 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 <baudrate> 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<len;i++)
	{
		putChar(*str);
		str++;
	}
}

⌨️ 快捷键说明

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