嵌入式设计应用
STC51单片机里面有一段出厂时固化的程序,这段程序的作用是检测串口是否要下载程序,不需要则执行单片机内的用户程序。每次启动时运行这端程序,这就是为什么每次下载时要冷启动。而复位后单片机是从地址0X0000H处开始执行,地址0X0000H又会指向主程序入口,即主函数处,即片内下载的用户程序而不会执行前面已经固化的检测串口那段程序。这就是为什么单片机每次下载要冷启动,而复位不行。注意,程序前面的宏定义什么的东西不占用系统时间,所以主程序即主函数处。
有一个办法可以给那些需要加电立刻启动的用户,STC单片机可以设置为加电时只有P1.0/P1.1为低电平时开始下载程序,否则直接执行用户程序。这种办法快,不用等前面检测串口的那段时间。STC51单片机冷启动是必须的而复位电路不是必须的,不管是冷启动还是手动启动。也就是想下载程序必须冷启动,而有没有复位电路无所谓。但是最小系统板上必须有复位电路,无论是上电复位,还是上电加手动复位,虽然在一些简单的程序中看不出区别,但是因为复位操作会对一些特殊寄存器产生影响,这样没有复位操作的话再次执行函数的时候会出现错误。单片机断电后在通电也会从主函数处继续执行,可能是单片机断电后地址自动回到0X0000H,但是那些特殊寄存器里的值不会改变。
单片机的上电复位和手动复位是比较简单的电路,只要是根据单片机手册要求的复位时间TRESET要小于复位电路中的RC常数。
单片机下载程序一般都是通过串口,即上位机(STC-ISP)与单片机的底层通信都是通过串口协议实现的,两者之间更为高级的通信协议是建立在串口协议上的。
Note2:上位机(STC-ISP)检测单片机时序
波特率即为串口发送每比特所占用的时间,此处为2400,即每比特所占用的时间为1/2400=4.167*E-4 (S);可以点击检测MCU选项,上位机开始与单片机握手。整个握手过程可以从图2.2中获得,图中橙色为上位机发送的询问脉冲,蓝色为单片机的响应脉冲
我买到的型号是 STC90C516RD+,跑程序的流程大概是这样的:
用C语言或者汇编写源代码。
用 Keil 编译成hex或者bin文件。
用USB线连接电脑和开发板,然后用STC或普中科技的烧录软件把文件写入单片机,就可以运行了。
开发板上集成了 CH340T 芯片,将USB转换成串口,连接到单片机,所以电脑和单片机的通信协议是串口。(当然,准确来说,USB和串口都是串行通信)
hex文件其实是一个文本文件,它有固定的格式,是Intel定的。烧录软件其实会把它转换成bin文件再写入,这一过程是透明的。bin文件就是单片机可执行的二进制代码了。
Keil是个IDE,而且是收费的,只支持Windows。Linux下可以使用sdcc编译。当然,8051的指令相对较少,完全可以自己写一个汇编器。
但是,这里最关键的是,文件是怎么被写入单片机的?对于此,STC是不公开的。于是……
下面直接上研究结果。
ISP协议
STC单片机内部ROM有一段固化的程序,称为ISP程序,是用来支持烧录的。早期8051并无集成此功能,要用专门烧录器实现。
单片机断电状态下通电,称为“冷启动”,此时,CPU会先执行该ISP程序。
这估计是借鉴了PC中BIOS的原理。
ISP程序会去检查串口RXD是否高电平,有合法的下载命令流,如果有,就进入ISP模式;如果没有,就直接跳转到地址0000H执行用户程序。
因此,我们电脑(被称为“上位机”)上的烧录软件,就是要让单片机进入ISP模式,然后将数据发送给它。
重头戏来了
首先,在单片机断电情况下,但串口仍与PC连接时,烧录软件即要打开串口,以 1200/2400/4800 其中之一(建议1200)波特率,不断往串口发 0x7F。
重要参数:波特率1200,停止位1,无校验、数据位为8位。
重要提示:如果波特率高于4800,无法进入ISP模式。
此时,打开开发板电源,单片机冷启动。检测到串口有0x7F,进入ISP模式。并发送类似如下的回复:
68 00 3B 00 16 BA 16 B6 16 B6 16 BA 16 BA 16 BA 16 B6 16 B6 43 43 FD F1 30 82 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 39 16
68 00 是回应标识符。
3B 包的长度。
00 表示这是数据包。
16 BA 16 B6 16 B6 16 BA 16 BA 16 BA 16 B6 16 B6 是8次测量脉宽的数据,可以借此计算出单片机的晶振频率、最大支持波特率。
43 43 表示固件版本是 4.3C。
FD 是单片机选项,每一位都表示一个选项信息:
x x x x x x x x
8 7 6 5 4 3 2 1
1=时钟倍速,1=12T,0=6T
3=需要短接P1.0/P1.1 才能下载 1=关闭,0=开启
4=下次下载擦DATAFLASH,0=开,1=关
5=时钟增益,1=高,0=低
6=ALE脚,0=P4.5,1=ALE
7=允许访问内部AUX RAM,1=允许,0=不允许
8=停止看门狗,1=复位关,0=停电关
倒数第二个字节 39 是校验和。
最后一个字节 16 是包尾固定值。
其他字节对烧录而言暂不需要。
包的格式
我们发的第一个数据0x7F和单片机第一次回应(如上),都不是真正的包,在接下来的通信中,则使用固定的包格式。其格式如下:
包头 + 标识符 + 包长 + 命令 + 数据 + 校验和 + 包尾
包头:2字节,固定为 46 B9。
标识符:2字节,上位机发往单片机的为 6A 00,单片机发往上位机的为 68 00。
包长:1字节,除包头外的长度。
命令:1字节,代表包的类型。
数据:不固定长度。可以无。其长度可由包长计算得出。
校验和:1字节,除包头、校验和本身、包尾外的数据的校验和。
包尾:1字节,固定为 16。
校验和的计算方法
校验和计算方法为 标识符、包长、命令、数据 4个部分的数据,各字节相加,取低8位。
命令类型
00: 数据
80: 确认
82: 关闭
84: 擦除ROM
8D: 设置选项
8E: 确认波特率
8F: 校验波特率
10: 未知
50: 未知
数据包格式
上位机发往单片机的数据即二进制代码文件,它被封装在上述的包:数据一节中,但它本身也是有格式的:
占位符 + 地址 + 长度 + 代码数据
占位符:2字节,固定为 00 00。
地址:2字节,表示代码的地址。
长度:2字节,表示代码的长度。
代码数据:其长度由上面字段指出。
烧录过程总结
上面已经将STC的通信协议格式分析完毕了。需要具体分析的只剩下命令的含义、各个数据的含义了。这些都是后话了。至少关于烧录,上面的信息已经够多了。
首先,单片机断电。烧录程序启动,以1200波特率不断往其串口发送0x7F。然后通电。
收到单片机信息的回复,此回复主要包括脉宽、型号、选项等信息。
由收到的脉宽值,计算出重装值,并发送给单片机。等待约200ms。同时由脉宽值计算出单片机最大支持的波特率,然后切换到某波特率(不得超出最大波特率),等待回应。
如果收到正确的回复,则表示波特率可行,则切换到1200波特率,并发送一个波特率确认的包文。发送完,等待约200ms,然后切换回原来的波特率,等待回应。
如果收到单片机的波特率确认包文,表示到目前为止,一切正常。否则,就算失败。
连续发送约5次重新握手的包文并等待回应。如果收到回应,表示一切正常,可以开始发送代码数据了。否则就是失败。
将代码数据分割成一定大小的包发送并等待正确回应。
设置单片机选项。
发送50包文,等待正确回应。然后发送关闭包文。
关闭串口,结束通信。
STC还支持热启动烧录,就是不用先断电再通电,而是在通电状态下可以直接烧录。看来,ISP程序一直在监听串口。普中科技的“自动下载软件”就是用这种方法烧录的。其技术细节,以后再更新。
注意
在通信过程中,单片机内部的ISP每次都会启动一个定时器,目测大概是2s,一旦通信过程中超时,单片机就会马上终止通信并跳转到0000H处执行用户程序。
全部0条评论
快来发表一下你的评论吧 !