ESP8266自动下载电路分析

硬件环境如下:
乐鑫官方开发板 ESP8266-DevKitC
ESP8266-DevKitC
板载自动下载电路如下:
自动下载电路
开发板入门指南的描述如下:
拨动开关
显然,选择自动下载功能后,RTS 就是 Auto_RTS
拨码
此处,ESP8266 的自动下载涉及 CP2102 的两个引脚,DTR 和 RTS
pins

  • DTR 引脚是 MODEM 联络输出信号,数据终端就绪,低有效;
  • RTS 引脚也是 MODEM 联络输出信号,请求发送,低有效;

注意,所谓 MODEM 联络信号都是由计算机应用程序控制并定义其用途的

ESP8266工作模式

  • 下载模式:芯⽚启动时,若 IO0 为低电平,芯⽚会进⼊下载模式;
  • 运⾏模式:芯⽚启动时,若 IO0 为⾼电平,芯⽚会进⼊运⾏模式;

逻辑
上图的逻辑关系如下:

  • DTR = 0,RTS = 0,此时Q1截止,Q2截止,EN = 1,IO0 = 1;
  • DTR = 0,RTS = 1,此时Q1截止,Q2导通,EN = 1,IO0 = DTR = 0;
  • DTR = 1,RTS = 0,此时Q1导通,Q2截止,EN = RTS = 0,IO0 = 1;
  • DTR = 1,RTS = 1,此时Q1截止,Q2截止,EN = 1,IO0 = 1;

显然,这种逻辑关系下 EN 和 IO0 不可能同时为 0
然而,ESP8266 进入下载模式却需要如下条件:

  • EN = 0,IO0 = 0,ESP8266 芯片掉电复位;
  • EN = 1,IO0 = 0,保持 IO0 为低电平重新上电

那么,问题来了,单靠以上电路 ESP8266 无法进入下载模式
网上找到了一些解释,然而并不能让我信服……可能大多参考了正点原子的自动下载电路原理,但人家的自动下载功能也需要 mcu-isp 软件配合才能实现啊……等等,吐槽之中获得灵感,ESP8266 不也是有下载软件的嘛,就算在命令行下不也是有下载脚本的嘛
ESP8266下载软件
显然,下载软件是看不出所以然的
那么,找到官方 SDK 中的下载脚本源码
ESP8266_RTOS_SDK/components/esptool_py/esptool/esptool.py

def _connect_attempt(self, mode='default_reset', esp32r0_delay=False):
        """ A single connection attempt, with esp32r0 workaround options """
        # esp32r0_delay is a workaround for bugs with the most common auto reset
        # circuit and Windows, if the EN pin on the dev board does not have
        # enough capacitance.
        #
        # Newer dev boards shouldn't have this problem (higher value capacitor
        # on the EN pin), and ESP32 revision 1 can't use this workaround as it
        # relies on a silicon bug.
        #
        # Details: https://github.com/espressif/esptool/issues/136
        last_error = None

        # If we're doing no_sync, we're likely communicating as a pass through
        # with an intermediate device to the ESP32
        if mode == "no_reset_no_sync":
            return last_error

        # issue reset-to-bootloader:
        # RTS = either CH_PD/EN or nRESET (both active low = chip in reset
        # DTR = GPIO0 (active low = boot to flasher)
        #
        # DTR & RTS are active low signals,
        # ie True = pin @ 0V, False = pin @ VCC.
        if mode != 'no_reset':
            self._setDTR(False)  # IO0=HIGH
            self._setRTS(True)   # EN=LOW, chip in reset
            time.sleep(0.1)
            if esp32r0_delay:
                # Some chips are more likely to trigger the esp32r0
                # watchdog reset silicon bug if they're held with EN=LOW
                # for a longer period
                time.sleep(1.2)
            self._setDTR(True)   # IO0=LOW
            self._setRTS(False)  # EN=HIGH, chip out of reset
            if esp32r0_delay:
                # Sleep longer after reset.
                # This workaround only works on revision 0 ESP32 chips,
                # it exploits a silicon bug spurious watchdog reset.
                time.sleep(0.4)  # allow watchdog reset to occur
            time.sleep(0.05)
            self._setDTR(False)  # IO0=HIGH, done

        for _ in range(5):
            try:
                self.flush_input()
                self._port.flushOutput()
                self.sync()
                return None
            except FatalError as e:
                if esp32r0_delay:
                    print('_', end='')
                else:
                    print('.', end='')
                sys.stdout.flush()
                time.sleep(0.05)
                last_error = e
        return last_error

隐藏的好深,看程序的注释其实就差不多了

  • 利用 RTS 控制 EN 或 nRST,因为它们都是低电平触发芯片复位;
  • 利用 DTR 控制 IO0,低电平启动则进入下载模式;
# ie True = pin @ 0V, False = pin @ VCC.

注意,此处 True 为低电平,False 为高电平
程序解析如下:

self._setDTR(False)  # IO0=HIGH
self._setRTS(True)   # EN=LOW, chip in reset

设置 DTR = 1,RTS = 0,此时 Q1 导通,Q2 截止,EN = RTS = 0,IO0 = 1,芯片掉电复位;

time.sleep(0.1)

延时 100ms,为了确保 EN 为低电平,原因嘛很简单,因为 EN 附近有一个 RC 电路,充放电都是需要时间的
RC电路
例如低电平为 0.25VCC,则由高电平放电至低电平需要的时间可按如下公式计算:
0.25 V c c = V c c ( 1 − e − t / R C ) 0.25Vcc = Vcc(1 - e^{-t/RC}) 0.25Vcc=Vcc(1et/RC)
此处,t ≈ 0.29ms,延时 100ms 绰绰有余

self._setDTR(True)   # IO0=LOW
self._setRTS(False)  # EN=HIGH, chip out of reset

设置 DTR = 0,RTS = 1,此时 Q1 截止,Q2 导通,EN = 1,IO0 = 0,芯片重新上电,由于 IO0 为低电平,芯片进入下载模式;

time.sleep(0.05)

延时 50ms,为了确保 EN 为高电平
同理, 0.75 V c c = V c c ( 1 − e − t / R C ) 0.75Vcc = Vcc(1 - e^{-t/RC}) 0.75Vcc=Vcc(1et/RC)
此处,t ≈ 1.39ms,延时 50ms 绰绰有余

self._setDTR(False)  # IO0=HIGH, done

设置 DTR = 1,RTS = 1,此时 Q1 导通,Q2 导通,EN = 1,IO0 = 1,确保下载完成后再复位芯片正常运行
补充一下,不点击下载按钮的话,实际测试 DTR 和 RTS 均为高电平,也就是说不会影响 ESP8266 芯片的正常运行

参考链接:
乐鑫官方 SDK
乐鑫官方开发板 ESP8266-DevKitC

  • 21
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值