设计自己的ISP程序
C程序源代码
/*定义为STC单片机(如果是SST单片机则去掉此行)*/
/********************************************************************
IAP.C SST 和STC单片机IAP操作函数
魏东(tonywei@tom.com)
2004.7.23
********************************************************************/
#define STC
/********************************************************************
* SFR Memory Addresses
********************************************************************/
sfr SFCF = 0xB1; /*SuperFlash Configuration*/
sfr SFCM = 0xB2; /*SuperFlash Command*/
sfr SFAL = 0xB3; /*SuperFlash Address Low*/
sfr SFAH = 0xB4; /*SuperFlash Address High*/
sfr SFDT = 0xB5; /*SuperFlash Data*/
sfr SFST = 0xB6; /*SuperFlash Status*/
/********************************************************************
* MCU IAP Commands
********************************************************************/
#define SFCM_BE 0x0D; /*block-Erase IAP cmd*/
#define SFCM_SE 0x0B; /*Sector-Erase IAP cmd*/
#define SFCM_VB 0x0C; /*Byte-Verify IAP cmd*/
#define SFCM_PB 0x0E; /*Byte-Program IAP cmd*/
bit iap_error=0;
void block0_erase(void);
void sector_erase(unsigned int);
void byte_program(unsigned int, unsigned char);
unsigned char byte_verify(unsigned int);
unsigned char ready(void);
/********************************************************************
* Block0-Erase Subroutine
********************************************************************/
void block0_erase(void)
{
SFCF = SFCF | 0x40;
#ifdef STC
SFAH = 0xf0;
#else
SFAH = 0x00;
#endif
SFDT = 0x55;
SFCM = SFCM_BE;
}
/********************************************************************
* Sector-Erase Subroutine
********************************************************************/
void sector_erase(unsigned short int destAddr)
{
SFCF = SFCF | 0x40;
SFAH = destAddr>>8;
SFAL = destAddr;
SFCM = SFCM_SE;
/*enable IAP */
/*load high order address byte*/
/*load low order address byte */
/*issue block erase command */
/*issue sector erase command */
if(!ready()) iap_error=1;
if(!ready()) iap_error=1;
/*enable IAP */
/*STC单片机选择block0*/
/*SST单片机选择block0*/
1
if(!ready()) iap_error=1;
/*turn off IAP*/
return readByte;
/*issue byte program command */
/*load low order address byte */
/*issue byte verify command */
/*enable IAP */
/*load high order address byte*/
/*load low order address byte */
/*load data to be programmed */
/*enable IAP */
/*load high order address byte*/
}
/********************************************************************
* Byte-Program Subroutine
********************************************************************/
void byte_program(unsigned short int destAddr, unsigned char dataByte)
{
SFCF = SFCF | 0x40;
SFAH = destAddr>>8;
SFAL = destAddr;
SFDT = dataByte;
SFCM = SFCM_PB;
}
/********************************************************************
* Byte-Verify Subroutine
********************************************************************/
unsigned char byte_verify(unsigned short int destAddr)
{ unsigned char readByte;
SFCF = SFCF | 0x40;
SFAH = destAddr>>8;
SFAL = destAddr;
SFCM = SFCM_VB;
readByte = SFDT;
SFCF = SFCF & 0xBF;
SFDT = 0;
}
/********************************************************************
* Ready Subroutine
* Purpose: To check if the IAP operation is completed.
* When it is done, turn off IAP configuration.
********************************************************************/
unsigned char ready()
{ unsigned long TimeOut;
{
}
SFCF = SFCF & 0xBF;
SFDT = 0;
}
{
SFCF = SFCF & 0xBF;
SFDT = 0;
}
/* any value other than 0x55 */
/* IAP operation is completed*/
/*any value other than 0x55*/
/*IAP operation is NOT completed before time out*/
if ((SFST&4) == 0)
/* Check if IAP is done */
for(TimeOut=0;TimeOut<100000;TimeOut++)
/* IAP is done */
/* turn off IAP*/
return 1;
return 0;
/*turn off IAP*/
2
/* 延时*/
/* 振荡频率*/
附件二:ISP.C
/********************************************************************
SST或STC单片机ISP程序
魏东(tonywei@tom.com) 2004.7.25
SST89C54 或STC89C516RD,频率:7.372848MHz
********************************************************************/
#include "reg51.h"
/* 对IAP.C调用的定义 */
extern bit iap_error;
extern void block0_erase(void);
extern void sector_erase(unsigned int);
extern void byte_program(unsigned int, unsigned char);
extern unsigned char byte_verify(unsigned int);
extern unsigned char ready(void);
//#define STC /* 定义为STC单片机*/
sfr WDTC = 0xC0;
sfr WDTD = 0x86;
sfr SFCF = 0xB1;
#define CON_OSC 7372848
#define CON_BPS 256 - ( CON_OSC / 12 / 32 / 6400 ) /* 6400BPS时间常数*/
#define CON_MSC CON_OSC/360000
/* 变量定义*/
unsigned char com_buf[58];
unsigned int nAddress = 0; /* 编程器编程地址*/
/* 函数定义*/
unsigned char com_getch(void);
void com_putch(char);
void com_putinfo(void);
void delay_ms(unsigned char);
void delay_s(unsigned char);
void (* pc_0)(void);
void goto_pc0(void);
/*******************************************************************/
/* 串口接收字符*/
unsigned char com_getch(void)
{ unsigned char c;
RI=0;
c=SBUF;
}
/* 串口发送字符*/
void com_putch(char c)
{
TI=0;
SBUF=c;
}
/* 串口发送复位信息*/
void com_putinfo(void)
/* 延时(单位:0.1毫秒) */
/* 延时(单位:0.01秒) */
/* 程序地址*/
/* 跳转到程序地址运行*/
/* 串口发送字符*/
/* 串口发送复位信息*/
/* 串口接收字符*/
while(RI==0);
return c;
while(TI==0);
3
unsigned char cr,ci;
/* 发送效验和*/
for(cj=0;cj
/* 波特率时间常数*/
/* 启动定时器*/
/* 禁止中断*/
/* 关看门狗*/
/* set TI to send first char of UART */
for(ci=0;ci<5;ci++) delay_ms(100); /* 等待mS稳定时间*/
/* 发送复位信息*/
if(RI)
while(1)
com_putinfo();
{ ci=SBUF;
RI=0;
ui=0;
}
ui++;
TH1=CON_BPS;
TL1=CON_BPS;
TR1=1;
EA=0;
TI=1;
WDTD = 0;
WDTC = 0;
SFCF |= 0x80;
com_putinfo();
ui=0;
RI=0;
{ delay_ms(1);
}
while(1)
{ iap_error=0;
if(ci==0x21)
{
}
据,效验和*/
{
#ifdef STC
#else
限制写地址*/
#endif
}
}
{ block0_erase();
nAddress ++;
if((ci==0x21)||(ci==0x07)) break;/* 接收到命令就进入通讯*/
if(ui>=10000) goto_pc0(); /* 等待秒,跳转到用户程序运行*/
for(ci=0;ci<3;ci++) com_buf[ci]=com_getch();
if((com_buf[0]==0x5a)||(com_buf[1]==0)||(com_buf[2]==0xa6))
else com_putch(5);
/* 发送复位信息*/
/* 返回错误标志*/
else if(ci==0x07) /* 数据包:H,0EH,包长度,'W',00H,地址高字节,地址低字节,程序数
for(ci=0;ci<2;ci++) com_buf[ci]=com_getch();
if((com_buf[0]==0x0e)&&com_buf[1])
for(ci=0;ci<=cj;ci++)
{ cj = com_buf[1];
cr = cj;
{ com_buf[ci] = com_getch();
cr += com_buf[ci];
}
{ nAddress = com_buf[2]*256 + com_buf[3];
cj -= 4;
{
for(ci=0;ci4))
/* 返回错误标志*/
byte_program(nAddress,com_buf[4+ci]);
/* 写*/
if(nAddress<0x8000) byte_program(nAddress,com_buf[4+ci]); /* SST
if(iap_error) com_putch(5); /* 返回错误标志*/
else com_putch(6);
/* 返回正确标志*/
else if((com_buf[0]=='A')||(com_buf[0]=='C'))
/* 擦除器件*/
5
else com_putch(5);
/* 返回错误标志*/
/* 返回错误标志*/
else com_putch(5);
/* 返回错误标志*/
else com_putch(5);
else if(com_buf[0]=='U')
if(iap_error) com_putch(5); /* 返回错误标志*/
else com_putch(6);
/* 返回正确标志*/
/* 返回正确标志*/
/* 跳转到用户程序运行*/
}
{ com_putch(6);
goto_pc0();
}
}
}
ci = com_getch();
}
}
附件三:DOWNLOAD.C
/********************************************************************
ISP 下载程序
魏东(tonywei@tom.com) 2004.7.25
Program files must be of INTEL standard HEX format.
This code was compiled using Borland C++ version 5.0 for DOS.
The clock() function is used to determine communication timeouts.
[the tick resolution is assumed to be 1/18th of a second. It may be
different on other compilers or in memory models other than LARGE]
********************************************************************/
#include /*for reading hex file*/
#include /*for copying parameter strings*/
#include /*for exit() function*/
#include /*for clock() and clock_t (timeouts)*/
#include /*for reading/writing the UART hardware ports*/
#include /*for toupper() function*/
/*******************************************************************/
#define DEFAULTTIMEOUT 5 /*about a quarter of a second*/
#define ERASETIMEOUT 80 /*about 4 seconds*/
#define VER " 1.01 "
#define DATE "25 July,2004 "
/*function prototypes*/
int reset(int *major, int *minor);
int download(int rev, char *program);
int run();
void showTitle(void);
void showInstructions(void);
int decodeCommandLine(int argc, char *argv[],
int *comport, double *crystal,
char *filename,
int *dontEraseData,
6
int *autoRun);
int validateParameters(int comport, double *crystal,
char *filename);
int openComms(int comport, long baudrate);
int initcommshardware(int comport, unsigned long int baudrate);
int dataavail(void);
void charin(unsigned char *ch);
int clearxmit(void);
void charout(unsigned char ch);
int readBlockFromFile(FILE *FptrIn, unsigned long *addr,unsigned char *data);
int sendPacket(unsigned char *message, int length);
int sendLoaderPacket(int len, char *data);
int waitForAck(int timeout);
int waitForSignature(char *sig, int *major, int *minor);
int enable(int revision, int dontEraseData);
int downloadU(char *program);
int runU(long address);
/*******************************************************************/
/* BEGINNING OF MAIN PROGRAM */
/*******************************************************************/
void main(int argc, char *argv[])
{
int comport=1; /*comport to connect through*/
long baudrate=9600; /*communications baud rate*/
char filename[256]=""; /*name&location of program to download*/
double crystal=11.059200; /*crystal frequency of the target*/
int rMajor, rMinor; /*rev number of the target firmware*/
int dontEraseData = 0; /*default to erasing all target memory*/
int autoRun=0; /*don't automatically run target prog*/
showTitle();
decodeCommandLine(argc,argv,
&comport,&crystal,
filename,
&dontEraseData,
&autoRun);
if(!validateParameters(comport,&crystal,filename))
exit(1);
/*work out actual baud rate*/
baudrate=crystal/1152.0;
openComms(comport,baudrate);
/*reset the target device*/
if(reset(&rMajor,&rMinor))
{ rMajor=2;
if(enable(rMajor,dontEraseData))
{
if(download(rMajor,filename))
{
7
if(autoRun)
{
run();
}
}
}
}
}
/*******************************************************************/
/* END OF MAIN PROGRAM , BEGINNING OF FUNCTIONS */
/*******************************************************************/
/*extract the filename etc. from the command line parameters*/
int decodeCommandLine(int argc,char *argv[],
int *comport,double *crystal,
char *filename,
int *dontEraseData,
int *autoRun)
{
int i;
char option;
for(i=1;i