前段时间买了一个51单片机开发板。买完后发现,这开发板和芯片的厂家都是十分山寨。
芯片产家叫STC,江湖人称“死太惨”,它的中文名字叫“宏晶科技”,官网是:www.stcmcu.com,相信在打开这个网站之后,你就同意我的看法了。如果还不够的话,可以下载它的芯片手册:STC90C516RD+ PDF,或者 烧录软件,体验体验。
开发板的产家叫做普中科技,一个连官方论坛都打不开的神秘企业,谢天谢地,它还是有官网的:www.prechin.com。
虽然山寨味浓厚,但是接地气。唯一令人生厌的是其不公开ISP协议,而且芯片还加密。
51单片机
51单片机是Intel在1981年推出的一种8位单片机(MCU),它不仅包含了一个8位CPU,还内置ROM和RAM,还有P0.0~P3.7共32根IO脚。型号叫8051。后来Intel不再生产单片机了,但其他产商则相继推出各种与8051完全兼容的单片机,而且还不断增强功能。
8位CPU已经完全没有技术门槛了,所以现在国内很多产家也都在生产。其零售价格大概4.4块钱。要知道,一块ARM32的单片机价格,也是10块钱以内的。
有了单片机,总要接上各种外设,于是就有了开发板。开发板上有PCB、LED、键盘、步进电机等元件,所以价格就比单片机贵多了。
以下是 8051 CPU 外部接口电路图:
烧录
我买到的型号是 STC90C516RD+,跑程序的流程大概是这样的:
- 用C语言或者汇编写源代码。
- 用 Keil 编译成hex或者bin文件。
- 用USB线连接电脑和开发板,然后用STC或普中科技的烧录软件把文件写入单片机,就可以运行了。
开发板上集成了 CH340T 芯片,将USB转换成串口,连接到单片机,所以电脑和单片机的通信协议是串口。(当然,准确来说,USB和串口都是串行通信)
CH340T 电路图:
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处执行用户程序。