用Qt编写STM32烧录软件(ISP模式)

文章目录

  • 1.背景
  • 2.stm32的自举模式
  • 3.硬件设计
  • 4.软件设计
  • 5.工程代码
  • 6.注意事项

1.背景

还在上学的时候,下载stm32程序还需要用J-Link的,很大一块,而且插座也大。后来用STLink,小了很多。
后来过了好几年都没接触stm32了,突然有个项目要用到。上某宝搜索开发板/核心板,发现很多都是串口下载的了,一根usb线,又可以下载程序,又可以用来printf,方便。
然后就稍微研究了一下它的原理。

2.stm32的自举模式

stm32有个自举模式,可以用来烧录程序。主要用到三个引脚:boot0、boot1、NRST,其作用请看这个资料【boot0、boot1的作用】、【NRST的作用】。

3.硬件设计

我买的板子上有可以串口烧写功能,其中电路原理图如下(注意,这个图是错误的,因为正确的是三极管Q1、Q2分别一个为PNP一个为NPN,正确的图在这里):
用Qt编写STM32烧录软件(ISP模式)_第1张图片或者改成这样看
用Qt编写STM32烧录软件(ISP模式)_第2张图片其中NRST加了上拉电阻,BOOT0、BOOT1加了下拉电阻
用Qt编写STM32烧录软件(ISP模式)_第3张图片

用Qt编写STM32烧录软件(ISP模式)_第4张图片
用Qt编写STM32烧录软件(ISP模式)_第5张图片
由于BOOT1固定设置为0,因此单片机只能选择UserFlashMemory、SystemMemory这两种中的一个启动。
在这里插入图片描述

4.软件设计

上面的电路设计,实现了可以通过操作CH340的RTS、DTR引脚来使stm32进入烧录模式。
而qt可以通过这两个代码来操作这两个引脚参考资料:

bool setDataTerminalReady(bool set)

bool setRequestToSend(bool set)

//进入ISP模式
void MainWindow::enterBootLoader()
{
    //boot0 为1
    //NRST  为0 进入复位
    mPort->setRequestToSend(true);
    mPort->setDataTerminalReady(false);

    QThread::msleep(100);

    //boot0 为1
    //NRST  为1 从复位中恢复,并且进入ISP模式
    mPort->setDataTerminalReady(true);
}

//进入正常模式
void MainWindow::enterFlash()
{
    //boot0 为1 主要目的是电路上的导通
    //NRST  为0 进入复位
    mPort->setRequestToSend(true);
    mPort->setDataTerminalReady(false);

    //boot0 为0; 由于电路上的设计 ,此时实际上除了boot0发生改变之外,NRST也发生了变化
    mPort->setRequestToSend(false);
//    //NRST 为1 取消复位;此时这个可要可不要
//    mPort->setDataTerminalReady(true);
}

用Qt编写STM32烧录软件(ISP模式)_第6张图片因此,只要参考资料就可以实现对编译好的程序进行烧录了。
【自举模式通讯】
【AN3155应用笔记】(感谢评论区的指导,在官网搜索AN3155就有中文版的资料)
用Qt编写STM32烧录软件(ISP模式)_第7张图片

上面的那个资料是中文版的,可惜不能下载, 这里有个英文的
ISP下载软件的下载流程
用Qt编写STM32烧录软件(ISP模式)_第8张图片其中HEX文件的解析:
https://blog.csdn.net/yx_l128125/article/details/13624947

5.工程代码

【工程代码看这里】,实现了hex文件的解析,程序的烧录等。

6.注意事项

—20211208—
今天突然发现个问题:QSerialPort的write函数,其实并不是同步的
也就是说当调用该函数,并取得返回值后,并不是表示数据已经完全发送出去了。假如在调用完这个函数之后,立马析构掉QSerialPort对象,那么对方很可能会什么也收不到。具体看这里

你可能感兴趣的:(嵌入式,Qt相关,linux,qt,开发语言)