大家都知道STC的标准下载方法,调入HEX文件——点“下载”——上电。
其实,STC的资料里(在附录)介绍过自定义下载,可我与很多同行交流过发现,除了我没有人去研究尝试过。
STC内部有两个程序空间:ISP空间与AP空间。上电后先运行ISP程序,如果下载软件正在下载,则先下载新程序代码、然后运行新程序;如果串口上没有下载流,则运行原来存在AP空间里的程序。
STC新增了一个特殊功能寄存器ISP_CONTR,它可以软复位、选择是运行ISP程序还是运行AP程序。自定义下载的中心思想就是软复位到ISP程序空间、相当于上电冷启动;这样可以实现“运行中、不停电、自定义下载”。没有做过实际产品的可能没有体会,工业现场不同于实验室与教室,不是那么容易冷启动上电复位的。
使用方法:
“打开程序文件”调入HEX文件
将“每次下载前重新调入已打开在缓冲区的文件,方便调试使用打钩”
打开“自定义下载”,设好波特率
以后编译了新程序代码后,点击“发送”则新代码被下载进单片机、根本不用先断电再上电。
注:如果将“当目标代码发生变化后自动调入文件,并立即发送自定义下载,命令”打钩,则编译了新程序就会下载进单片机,在线调试。
unsigned char code download[]={0x12,0x34,0x56,0x78,0x90,0xAB,0xCD,0xEF,0x12,0x34,0x56,0x78,0x90,0xAB,0xCD,0xEF,'\0'};
unsigned char di=0;
unsigned char dr1,dr2,dr3;
/************************************************************/
/************************************************************/
void Dnload(uchar r_data)
{
if (r_data==download[di])
{
di++;
if (download[di]=='\0')
{
EA=0;
dr1=( ( (float)Fosc*1000000/(12*2) ) +65535) / 65536;
dr2=( ( (unsigned int)( (float)Fosc*1000000/(12*2) ) ) +255) / 256;
dr3=( (unsigned int)( (float)Fosc*1000000/(12*2) ) ) % 256;
/*用汇编实现一秒钟定时*/
#pragma asm
wait_for_1S:
DJNZ dr3,wait_for_1S
DJNZ dr2,wait_for_1S
DJNZ dr1,wait_for_1S
#pragma endasm
ISP_CONTR=0x60; /*定时时间到软复位到ISP程序区*/
}
}
else
di=0;
}
/****************************************************/
void UART_service() interrupt 4 using 2
{
unsigned char rece;
if (RI)
{
RI=0;
rece=SBUF;
Dnload(rece); /*实时监测自定义下载命令*/
/*下面为实际的串口接收中断处理*/
}
else
{
TI=0;
/*下面为实际的串口发送中断处理*/
}
}
/******************************************************************/
/******************************************************************/
void initial()
{
/*初始化包括3个方面*/
/******************************************************************
①:设置特殊功能寄存器(工作方式的设置)
******************************************************************/
SCON=0x50; //SM0,SM1,SM2,REN,RB8,TB8,RI,TI
//(SM0,SM1)=01: 串口工作方式1
//SM2=0: 不必收到有效停止位即RI置位
//REN=1: 允许接收
TMOD=0x21; //T1: 方式二8位自动重载定时器 T0: 方式一16位定时器
//GATE, C/T, M1,M0
PCON=0x80; //SMOD=1 如果串口使用定时器1则波特率加倍,最高波特率=fosc(Hz)/192
//如果串口使用定时器2则最高波特率固定=fosc(Hz)/32
TH1=TL1=(uchar)((float)256-(float)Fosc*1000000/((float)192*BAUD_rate));
TR1=1;
IE=0x90;
}
|