不知道大家有没有遇到过这样想喊“我C”的问题?
设计打样了一块STC单片机的PCB电路板,焊好单片机想下载程序才发现,没有设计电源开关和复位开关。USB转串口芯片直接设计在同一块板子上,没有办法单独断电。
不知道大家碰到这种情况有没有好的解决方案,反正我都快要放弃这块板子了。
好在STC比较强大(网站和文档也是相当的强大),单片机产品手册上就有成熟的用户自定义下载方案。
STC-ISP程序下载原理
STC单片机的产品手册,有大量ISP/IAP程序下载的相关描述,大致原理如下:
- ISP软件点击下载后,以固定波特率向单片机发送'0x7F';
- 单片机复位后(上电、硬复位或软复位)进入ISP监控程序区;
- 监控程序判断串口数据是否为合法ISP下载命令流;
- 是合法ISP下载命令流,执行ISP下载程序,完成后复位到用户程序区;
- 非合法ISP下载命令流,直接复位到用户程序区;
STC用户自定义下载(不停电下载)功能
通过用户程序进入ISP下载区有两个方法:
- 用户程序直接跳转到ISP监控程序(需要知道函数地址);(实际上跳转到MCU上电运行的地址应该也行,没有试过,感兴趣的朋友可以测试一下)
- 用户程序软复位到ISP监控程序;
实际上第二种方法更简单一点,STC专门设计了一个寄存器IAP_CONTR用于控制软件复位并选择跳转方向(0x20去用户程序,0x60去用户监控程序),官方手册上就有明确的功能描述。
用户程序可以设计当某个按键被按下或者UART接受到下载命令流时,软复位进入ISP监控程序。
如果你像我一样"衰",没有断电开关和硬复位按钮,建议至少设计保留2种进入ISP监控程序的方法,避免程序无法下载。
STC用户自定义下载部分实现代码
软复位进ISP监控程序区代码:
//userisp.h
#define IAP_MODE_RESET 0x20
#define IAP_MODE_ISP 0x60#define UserISP(mode) IAP_CONTR = mode
按钮被按下,调用ISP跳转函数:
//userisp.c
//定时器回调函数,系统1s定时器函数中调用
//判断下载按键是否被按下,按下后复位到ISP监控程序区
void TimerCallBackUserISP(void)
{if(ISPButton)UserISP(IAP_MODE_ISP);
}
程序下载方法:
- ISP软件点击下载;
- 按下下载按键并保持1s以上,确认下载已启动后释放;
彩蛋:第一次程序是怎么下载的?
首次下装还是比较麻烦的,先拆除USB转串口芯片,焊接飞线连接到外围USB转串口模块上进行ISP下载,原来的USB口仅用于供电。
确保程序自定义下载可靠后,再焊回USB转串口芯片。