作者:未知 来源:http://blog.ednchina.com/
STC89C52RC单片机可以直接用串口进行ISP编程,对于使用者来说,这就变得很简单了.这里要说的是,对STC89C52RC进行串口ISP编程的两种方法.
第一种 冷启动, 即彻底关断用户目标板的电源,再上电.这一方法为厂家推荐之方法.宏晶公司在STC89C52RC数据手册上给出了下面的编程流程.
具体做法如下:
1.首先确保有STC89C52RC的目标板至少有最小系统.
2.到宏晶公司的网站下载一个软件,下载地址为:
http://www.mcu-memory.com/datasheet/stc/stc-isp-v2.9-setup/stc-isp-v2.9-setup-beta5.exe
先在MCU Type下拉列表中选择正确的单片机型号,这里就选STC89C52RC啦,然后点击“Open File”打开待下载的文件,接着选择正确的COM口以及本机可用的最高波特率,COM口根据你接的串口来确定,最高波特率通常不必改动,接下来就是选择是否启用单片机的倍速特性,根据自己的需要来定,选择芯片内置振荡器的增益大小,可以根据提示,按提示要求去做,可得到较低的EMI特性。
一切选项最好之后,可以开始下载.
关断电源,然后点击“Download/下载”按钮,点完后,再接通电源,这里要注意,关断电源到接通电源时间应稍微长一些,保证板子充分放电.只要注意操作顺序应该没有什么问题,如果点击“Download/下载”未及时插上电源,会出现如下图所示画面,不必担心,直接将电源插上即可。
第二种 不切断电源的方法
与冷启动相比,前面的操作都一样,只是从冷启动需要关断电源的操作步骤开始不一样.当冷启动需要关断电源时,在本方法下,不需要关断电源.此时,请按照下面步骤进行:
需要用到串口,因此要占用单片机串行口和定时器T1或者T2作为波特率发生器,因此,定时器T1或者T2你就不能用了(在调试阶段)。下面,我们要在程序里加上一段串口初始化的程序:
serial_init () {
SCON = 0x50; /* mode 1: 8-bit UART, enable receiver */
C_T2=0; /*Timer2 runing in Timer mode*/
RCLK=1;
TCLK=1;
RCAP2H=0xff;
RCAP2L=0xee;
TR2=1; /*enable Timer2 run */
ES = 1; REN=1; EA=1; SM2=1; /*SM2=1时收到的第9位为1才置位RI标志*/
}
这段程序加在主程序初始化那里,特别要提示的是,在初始化之前要有一段延时,时间约为0.1s即可,也就是主程序应该是这样的:
void main()
{ ….. 变量的定义,其他初始化语句
mDelay(100); //延时100ms
serial_init();
……
其他语句
为什么一定要在初始化串口之前加一段延时呢?这在后面交待。
然后要加一段串口收数的程序,直接复制下面这一段就可以,了解清楚原理后自己写也行:
uchar bitset(uchar num,uchar cbit) /*设置某一位*/
{ uchar bit_value[]={1,2,4,8,16,32,64,128};
return num|bit_value[cbit];
}
////////////////////////////////////////////////////////
void Ser() interrupt 4
{
static uchar Count=0;
GetCharBuf[Count]=SBUF;
if(GetCharBuf[Count]==(Count+0x10))
//要求stc下载软件发送的数是10 11 12 13 14 15 16 17
{ sMark="bitset"(sMark,Count);
//如果收到的数符合要求,则将sMark这个相应位置1
}
Count++;
if(Count>=8)
{ Count="0";
mGet=1; //置位标志
}
RI=0;
}
看懂了没有呢?这里定义了8个字节的命令字,如果从主机传来连续的8个数正好与所定义的8个数相符合,那么就说明主机有要求重新下载的指令了。定义哪8个数,如何判定,这都可以发挥你自己的聪明才智来写,这里就简单地要求主机发送0x10 0x11 0x12 0x13 0x14 0x15 0x16和0x17这8个数,看程序中的这一行:
if(GetCharBuf[Count]==(Count+0x10))
由于每次收到数Count会加1,从开始的0计到7为止,因此,接收到的数如果是Count加上0x10,就认为是相符的。
相符之后就要做个记号,这里用了一个字节sMark,开机时,该字节为0,相符一次,则将相应位置1,如果收到的8个数均相符,那么sMark=0xff,如果收到的数中有一个不符,那么sMark不等于0xff。利用sMark即可判断是否接收到了正确的8个数。
一旦收到8个数之后,即置位标志位mGet,然后在main函数里面做个判断,如果mGet=1且sMark=0xff,说明要求重新下载,下面即延时1s,然后将数0x60写入特殊功能寄存器:ISP_CONTR即可,main函数中的这一部份程序如下:
if(mGet)
{ if(sMark==0xff) //收到数符合要求
{ sMark="0"; //复位
mDelay(2000);
ISP_CONTR=0x60;//复位到isp下载区
}
else
{ sMark="0";
}
}
你可以把这一段放在main函数的for(;;)循环当中。
ISP_CONTR是STC89C52RC的一个特殊功能寄存器,其地址为0xE7,可以在程序的开头用sfr关键字来定义:
sfr ISP_CONTR=0xe7;
接下来看一看PC机程序端应该怎么做。
点击界面右侧的“自定义下载”,先选定特率,按上面的程序,如果选用stc89C52rc的倍速特性的话,波特率就是38400,否则就是19200,其他按图4设置即可。接着到自定义下载文本框中输入自定义下载指令为10 11 12 13 14 15 16 17 输入好了以后,点击发送,即可在不断电的情况下进行程序的下载了。
那么为什么一开始初始化的时候一定要延时呢?这是我们在实际使用中发现,在下载完成后,软件似乎会多发送一些数据,由于我们的程序中没有设置超时等处理,所以就会干扰数据的正确接收,为此采取了一个简的方法就是延时一段时间再开启串口。当然你也可以采用其他的方法来解决这个问题,不过我们认为这种方法简单有效。
为了更有效地进行程序的开发,建议你将“选项”下方的“每次下载前自动刷新已打开在缓冲区的文件,以方便调试”前面打上勾。
参考资料: 平凡单片机工作室 http://www.mcustudio.com/