在不改变硬件状态下通过USB升级系统固件;
1.使用Cubemx配置USB,USB配置为虚拟串口
2.生成的工程中添加USB重启识别
新增函数USB_Status_Init();
void USB_Status_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_12,GPIO_PIN_RESET);
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_12,GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_12,GPIO_PIN_SET);
HAL_Delay (100);
}
系统重启时,软件自动重新上下拉PD+引脚,避免端口占用,无法识别需要重新插拔;
在系统时钟初始化完成后调用该函数
3.USB接收指令进入Bootloader状态
1.通过标志位写入flash中,接收到指令后系统重启,在初始化完成进入while循环之前读取flash位,判定是否进入Bootloader状态,调用JumpToBootloader();函数跳转至Bootloader
void JumpToBootloader(void)
{
uint32_t i=0;
void (*SysMemBootJump)(void); /* 声明一个函数指针 */
__IO uint32_t BootAddr = 0x1FFF0000; /* STM32F4的系统BootLoader地址 */
/* 关闭全局中断 */
__disable_irq();
/* 关闭滴答定时器,复位到默认值 */
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
/* 设置所有时钟到默认状态,使用HSI时钟 */
HAL_RCC_DeInit();
/* 关闭所有中断,清除所有中断挂起标志 */
for (i = 0; i < 8; i++)
{
NVIC->ICER[i]=0xFFFFFFFF;
NVIC->ICPR[i]=0xFFFFFFFF;
}
/* 使能全局中断 */
__enable_irq();
/* 设置重映射到系统Flash */
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
/* 跳转到系统BootLoader,首地址是MSP,地址+4是复位中断服务程序地址 */
SysMemBootJump = (void (*)(void)) (*((uint32_t *) (BootAddr + 4)));
/* 设置主堆栈指针 */
__set_MSP(*(uint32_t *)BootAddr);
/* 在RTOS工程,这条语句很重要,设置为特权级模式,使用MSP指针 */
__set_CONTROL(0);
/* 跳转到系统BootLoader */
SysMemBootJump();
/* 跳转成功的话,不会执行到这里,用户可以在这里添加代码 */
while (1)
{
}
}
2.USB接收指令
3.系统重启,进入Bootloader
4.串口助手发送01 01 a1指令进入Bootloader,此时电脑设备管理器中可以看到STM32 BOOTLOADER设备(已安装驱动)
5.Cubeprogrammer中可以检测到USB
选择“Connect”可读取到芯片信息
打开“Open file"选择.hex或.bin文件,再点击下载即可;
下载完成后断开Cubeprogrammer工具连接,手动复位芯片(USB更新固件需手动复位重启程序),程序更新完成
注:
当显示程序下载成功但是程序并未更新时,可通过左上的下载标图查看是否为如上错误,该错误应Cubeprogrammer版本存在问题,使用其他低版本工具可解决如上问题
亲测有效版本连接如下
链接:https://pan.baidu.com/s/1inx7xH-EMHP7prb8xY6cYw?pwd=mm3r
提取码:mm3r
本文档用于记录STM32单片机运用过程中出现的问题并找到的解决方案