📄 c8051f020updata.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 + -