Qt实现控制串口的RTS和DTR功能_通过串口让ESP32重启

本文围绕ESP32自动下载电路展开,研究串口控制ESP32重启。介绍了串口RTS和DTR的含义,探讨QSerialPort中控制它们的接口。还给出两种让ESP32重启的方法,一是软复位,二是通过RTS和DTR控制模块EN脚,同时给出Qt上的操作及延时说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 我的博客:https://blog.csdn.net/qq_37388044
  • 我的知乎:https://www.zhihu.com/people/bbtganmin
  • 联系方式:知乎私信

转载或者引用本文内容请注明来源及原作者!



前言

  最近在研究ESP32的自动下载电路,参照官方的开发板电路图自己画了一块板。因为用不到JTAG功能,所以用 CH340C 代替了官方使用的 FT2232H USB转串口芯片。

  开发ESP32的同学都知道,模块下载固件时,是需要先将GPIO0拉低再重启模块,让模块进入下载模式。这就意味着串口能控制ESP32重启,主要通过串口RTS和DTR控制。

  正好我要写的Qt上位机就需要有一个让设备重启的功能,那么Qt要怎么去控制RTS和DTR这两个信号呢?


一、串口的RTS和DTR是什么?

RS-232C接口定义(DB9)

1 载波检测 DCD(Data Carrier Detect)
2 接收数据 RXD(Received Data)
3 发送数据 TXD(Transmit Data)
4 数据终端准备好 DTR(Data Terminal Ready)
5 信号地 SG(Signal Ground)
6 数据准备好 DSR(Data Set Ready)
7 请求发送 RTS(Request To Send)
8 清除发送 CTS(Clear To Send)
9 振铃提示 RI(Ring Indicator)

当然,在这里它们的定义并不重要。
我们要关注的是 " RTS = Request To Send " 和 " DTR = Data Terminal Ready " 。


二、QSerialPort 中有控制RTS和DTR的接口吗?

我们打开QSerialPort的头文件,搜索RTS,找不到相关函数?

这时我留意到这四个函数:
在这里插入图片描述
于是我简单封装了一下函数:

void bbtSerialPort::setDTR(bool state)
{
    if(serialPort->isOpen())
        serialPort->setDataTerminalReady(state);
}

void bbtSerialPort::setRTS(bool state)
{
    if(serialPort->isOpen())
        serialPort->setRequestToSend(state);
}

再写两个 QCheckBox 控件

QCheckBox *RTSCheckBox = new QCheckBox("RTS");
QCheckBox *DTRCheckBox = new QCheckBox("DTR");

connect(RTSCheckBox, &QCheckBox::stateChanged, [=](int state){
    if(!serialPort->isOpen()) return ;
    if((Qt::CheckState)state == Qt::Checked) setRTS(true);
    else if((Qt::CheckState)state == Qt::Unchecked) setRTS(false);
});
connect(DTRCheckBox, &QCheckBox::stateChanged, [=](int state){
    if(!serialPort->isOpen()) return ;
    if((Qt::CheckState)state == Qt::Checked) setDTR(true);
    else if((Qt::CheckState)state == Qt::Unchecked) setDTR(false);
});

效果图:(串口的其他操作这里就不多讲了)
在这里插入图片描述
经验证,这两个函数就是用来控制RTS和DTR信号的。当 state 为 true 时,引脚为低电平,为 false 时,引脚为高电平。


三、通过串口让ESP32重启

1、方法一:ESP32软复位

在"esp_system.h"中有软复位函数:

/**
  * @brief  Restart PRO and APP CPUs.
  *
  * This function can be called both from PRO and APP CPUs.
  * After successful restart, CPU reset reason will be SW_CPU_RESET.
  * Peripherals (except for WiFi, BT, UART0, SPI1, and legacy timers) are not reset.
  * This function does not return.
  */
void esp_restart(void) __attribute__ ((noreturn));

可以通过串口发送自定义指令让 ESP32 自己重启。

2、方法二:通过RTS和DTR控制模块的EN脚(CHIP_PU脚)

先来看看电路图:
在这里插入图片描述
三极管原理在这就不多说了,要想让模块重启,就需要将EN脚先拉低再拉高。

  • 一开始,DTR和RTS都是1,看电路右边的表:EN 和 IO0 都为1。
  • 保持DTR为高,RTS拉低:此时 EN 拉低,IO0 不变。
  • 保持DTR为高,RTS拉高:此时 EN 拉高,IO0 不变。

那么在Qt上的操作是:(注意: true 为低电平, false 为高电平。

QPushButton *resetButton = new QPushButton("重启设备");
connect(resetButton, &QPushButton::clicked, this, [=]() {
    setDTR(false);
    setRTS(true);
    msleep(50);
    setRTS(false);
});

这里的延时是为了避免EN位低后EN脚上的电容还供电一段时间,可能会导致重启失败。这要看个人情况,我试了一下不加延时也是可以的。

至于延时的函数,网上有很多实现的方法,我这是其中一种:

void bbtSerialPort::msleep(quint32 msec)
{
    QEventLoop loop;//定义一个新的事件循环
    QTimer::singleShot(msec, &loop, SLOT(quit()));//创建单次定时器,槽函数为事件循环的退出函数
    loop.exec();//事件循环开始执行,程序会卡在这里,直到定时时间到,本循环被退出
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值