| 
 
| 大家都知道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;
 
 }
 
 | 
 |