STM32单片机的ISP使用方法
干了七八年51单片机和CPLD,最近几年又干STM32单片机和FPGA,都说30而立40不惑,现在30几还是没立,估计40几还是会惑,经常在网上闲吹久了,还是写点实用的东西,全当自己写的笔记,到40几迷惑时再回来看看。
1.前言
通常使用STM32都是在买个Jlink或DAPLink用JTAG/SWD就开始调试和下载程序,这个确实很方便,还可以调试。但是,当产品不能开盖而要求可以更新程序甚至远程更新程序时就显得不方便了。
一些大牛就自己写BootLoader然后通过产品接口就可以更新程序了,这其实就是IAP应用,但这种方法要求有点高,特别是BootLoader的编写有点麻烦(实际上网上可以找到范例),不过STM32官方使用UART1做了一个BootLoader固化在芯片中,只要满足一定条件就可进行程序更新,这个就是ISP。
所以,ISP的前提是产品使用了全双工的串口,并且连接到STM32的UART1上才行。这种模式相对简单也很实用,因为大多数产品都会留有串口。
2.进ISP模式
STM32代码和数据存储在三个区域: RAM区、用户存储区、系统存储区。
.RAM区,掉电会丢失, Debug调试时会用到此区域。
.用户区存储区,正常启动时进入的区域。
.系统存储区则即官方的Bootloader区,即本次要进入的区域。
STM32启动后默认进入用户存储区,即应用程序区,而如果要进入ISP模式则需要进入系统存储区才行。进入系统存储区有软件和硬件方法有两种方法:
2.1硬件方法:
在STM32复位前将BOOT0置高电平BOOT1置低电平,复位后程序将从系统存储器开始执行,进入Bootloader程序。(下表列出了Boot0/1不同时进入的区域)。
2.2软件方法:
通过程序跳转到系统存储区,也能进入BootLoader,下面是我写的代码:
__asm void __set_MSP(u32 mainStackPointer)
{
msr msp,r0
bx lr
}//此代码按里系统中应该有,但不知道为什么我Keil里没找到,但写了一个,如果有就忽略。
#define SystemRomAddr0x1ffff000//系统存储区的地址,如果芯片不同建议查一下
void EntyIspMode(void)
{
void (*BootLoaderFun)(void);
BootLoaderFun=((void *)(void))(*(u32 *)(SystemRomAddr+4));
RCC_DeInit();
SysTick_CTRL=0;
SysTick_LOAD=0;
SysTick_VAL=0;
__disable_irq();
__set_MSP(SystemRomAddr+4);
BootLoaderFun();
}
使用者在满足合适条件下(比如自定义 一个通讯协议)调用EntyIspMode()则可以进入ISP模式了。
3.写入程序
成功进入ISP模式后,上位机即可通过串口对STM32进行程序更新操作,这个操作可以从网上下载现有程序,直接将Hex灌进去即可,这就比较简单。
常用的软件有:
.STM32官方程序,
.FLYMCU这个是第三方的一个公司开发,比较常用,
.SSCOM5.1以上版本,以前就是一个非常好用的串口调试助手,后面集成了STM32下载器。
其他,这就不一一例举了。
如果是简单应用,就差不多了可以了,当然特殊应用情况可能也需要自己编写上位机程序来实现程序更新,这个就需要了解ISP的通讯协议了,后面节做一个简单介绍,如果更详细的建议还是上官网下载吧。
4.ISP协议简述
上位机首先向STM32发送0x7F,STM32收到后会根据此字节来自动匹配波特率,匹配完成后回传ACK正常或NACK异常(0x79=ACK,0x1F=NACK,下同)。正常后STM32等待上位机发送命令,然后根据命令执行ISP过程,如以下流程所示:
命令有:
详细的协议请到意法半导体官网上搜索 AN3155
《USART protocol used in the STM32 bootloader》里详细描述,这里就不一一举例描述了,只举例描述,如读版本号(GET cmd)
功能:获取stm32里bootloader版本号,以及支持的指令代码。
流程: