那么进入主题:STC12系列下载的帧格式:
协议帧简介:主要构成如下
Head |
Sign |
Reserved |
Length |
Frame |
Data |
Checksum |
Trail |
各个填充区详细说明:
名称 |
长度 |
功能 |
Head |
2-Byte |
包头 (0×46,0xB9) |
Sign |
1-Byte |
标识 (0x6A或0×68) |
Reserved |
1-Byte |
预留区 (填充0×00) |
Length |
1-Byte |
(Head + Length + Frame+Da |
Frame |
1-Byte |
用以区分不同的帧 |
Da |
0~0x8A Bytes |
数据 |
Checksum |
2 Byte |
校验和 |
Trail |
1 Byte |
包尾 (0×16) |
至于Cmd的协议应答之类的:
命令 说明 MCU回应
7F 引导MCU进入ISP并测量时钟 50 MCU选项信息
50 设置MCU型号等 8F 应答
8F 新波特率测试 8F 测试应答
8E 正式修改波特率 84 修改波特率应答
84 文件容量,擦除芯片 00 应答
00 下载程序 00/30 应答校验和,成功或失败
30 重新下载程序 00/30 应答校验和
69 型号等 8D 应答
8D 设置选项 50 应答选项
82 退出 重启进用户程序
至于交互过程,也算是简单的,就是看你的设备反应速度了。这就是为什么某些PL2303线下载老出错的原因,不过我这里至少用的挺好。
PC ->0x7f ->MCU
MCU ->信息 ->PC
PC -> 核对?MCU型号 -> MCU
MCU ->波特率变更请求 ->PC
PC ->波特率测试 ->MCU[此时,计算重载值切换波特率】
MCU ->成功/无回应 -> PC
PC ->波特率设置 ->MCU [切换到最低波特率上去
MCU ->成功/无回应 ->PC [切换到数据波特率上去
PC -> 擦除芯片 -> MCU
MCU ->成功/无回应 ->PC
PC -> 0x80个字节数据 ->MCU
MCU -> 校验码 ->PC
循环到文件结束
PC ->设置?型号 ->MCU
MCU ->成功/无回应 -> PC
PC ->设置选项 ->MCU
MCU ->成功/无回应 -> PC
PC ->编程结束 ->MCU
校验和算法是将标识到数据区的内容统统加起来,取低十六位,看程序:
01 | PUBLIC FUNCTION CheckSum(buff AS String, start AS Integer, endchr AS Integer) AS String '返回两个字 |
02 | DIM i AS Integer |
03 | DIM chkSum AS Long |
04 | DIM lo AS Byte |
05 | DIM hi AS Byte |
06 | DIM tempStr AS String |
07 | chksum = 0 |
08 | FOR i = start TO endchr |
09 | chksum = chksum + Asc(Mid(buff, i, 1)) |
10 | NEXT |
11 | hi = Shr(chksum AND &HFF00, 8) |
12 | lo = chksum AND &H00FF |
13 | tempStr = Chr(hi) & Chr(lo) |
14 | RETURN tempStr |
15 | END |
关于STC12C5Ax系列的信息帧,这里有一张别人分析的图:
至于固件版本我这里测试的有:
1 | 6.6I : 66 49 |
2 | 6.2I : 62 49 |
关于晶振速度的计算:
如果是标准12M时钟,1200Kps波特率,则计数值为1/1200*7 = 5833uS,数值也为5833。将八次技术求平均(假设为18 94=6292),则此时单片机时钟频率=6292*12M/5833 = 12.994MHz。[page]
以下数据帧省略帧头帧尾帧长度校验码
——————–核对MCU型号帧————————-
发送数据 50 07 00 36 01 MCU型号
接收数据 8F
——————-波特率实验帧—————————–
发送数据 8F xx yy zz aa dd 83
xx=0xC0 (C0=1100 0000,意思就是T1x12,波特率加倍)
yy=定时器重载值,按照加倍/1T计算。
zz=设置校验值,计算方式是 ff=xx
aa=波特率校验值,计算方式是aa=2 * (0×100 -yy)
dd=延时值,延时多少时间片切换
83为ISP定时常数,这个值适用于12M晶振,在STC手册中有不明显的描述:
1 | //#define ENABLE_IAP 0x80//if SYSCLK<30MHz |
2 | //#define ENABLE_IAP 0x81//if SYSCLK<24MHz |
3 | //#define ENABLE_IAP 0x82//if SYSCLK<20MHz |
4 | //#define ENABLE_IAP 0x83//if SYSCLK<12MHz |
5 | //#define ENABLE_IAP 0x84//if SYSCLK<6MHz |
6 | //#define ENABLE_IAP 0x85//if SYSCLK<3MHz |
7 | //#define ENABLE_IAP 0x86//if SYSCLK<2MHz |
8 | //#define ENABLE_IAP 0x87//if SYSCLK<1MHz |
但是实际上测试似乎83这个值在40M都没有问题。
接受数据:
8F xx yy zz aa dd 83
—————————–波特率确认帧
发送数据 8E xx yy zz dd 83
接收数据 同上
——————————擦除帧:
这里我有充分的理由怀疑老妖是有毛病的。都到了下载程序的地步了还搞这么诡异的擦除命令:
1 | 84 FF 00 F0 00 00 F0 00 00 00 00 00 00 00 00 00 00 00 |
2 | 00 80 7F 7E 7D 7C 7B 7A 79 78 77 76 75 74 73 72 71 70 6F 6E 6D 6C 6B |
3 | 6A 69 68 67 66 65 64 63 62 61 60 5F 5E 5D 5C 5B 5A 59 58 57 56 55 54 |
4 | 53 52 51 50 4F 4E 4D 4C |
5 | 4B 4A 49 48 47 46 45 44 43 42 41 40 3F 3E 3D 3C 3B 3A 39 38 37 36 35 |
6 | 34 33 32 31 30 2F 2E 2D 2C 2B 2A 29 28 27 26 25 24 23 22 21 20 1F 1E |
7 | 1D 1C 1B 1A 19 18 17 16 15 14 13 12 11 10 0F 0E |
回应:
00 00
———————数据帧
发送 00 00 00 ADDR 00 LEN EF 0×80 bytes数据
ADDR = 2BYTE 的地址,高位在前低位在后
LEN 似乎是数据长度
数据字段如果不足80 bytes填ff补足
回应 07 ChkSum
ChkSum的算法和前面介绍的一样,只不过只是针对数据部分的校验
——————设置型号帧:
69 07 00 36 01 MCU_MODEL
MCU_MODEL是MCU型号
回应就一个字 8D
——————-设置选项帧
发送:8D FF x1 x2 FF FF FF FF FF x3 FF FF FF FF FF FF 00 A9 0A A6
x1,x2,x3参见前面的选项信息
接受:50 FF x1 x2 FF x3 03 FF 固件版本 FF x1 x2 FF x3 FF 00 A9 00 03 00 9A 04 79 1A 00 AD FF 00 62
——————RESET帧
发送:82 00 00
没有回应。
具体实现可以看kSTC12-ISP的实现方式
上一篇:把EasyPro51编程器的源代码修改在SDCC上,编译运行通过
下一篇:一个简单的测试单片机的整数性能的程序
推荐阅读最新更新时间:2024-03-16 14:25