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