下载模式
ESP8266/ESP32进入下载模式的条件很简单:
EN(也称为RST)上升沿时候GPIO0保持为低电平,如图所示
分析
下载电路如下所示,其结构与RS触发器比较类似,注意EN和IO0信号均连接在三极管集电极,通过控制三极管只能拉低此信号,若三极管截止,则此信号的状态由其他电路决定(一般来说,此类信号会默认接电阻上拉到VCC)
逻辑关系如下
DTR = 0; RTS = 0, 此时Q1截止,Q2截止,EN = 1; IO0 = 1
DTR = 0; RTS = 1,此时Q1截止,Q2导通, EN = 1; IO0 = 0
DTR = 1; RTS = 0, 此时Q1导通,Q2截止, EN = 0; IO0 = 1
DTR = 1; RTS = 1, 此时Q1截止,Q2截止, EN = 1; IO0 = 1
列表如下
DTR | RTS | EN | IO0 |
---|---|---|---|
0 | 0 | 1 | 1 |
0 | 1 | 1 | 0 |
1 | 0 | 0 | 1 |
1 | 1 | 1 | 1 |
简单总结:当DTR和RTS同时为0或者同时为1时,三极管Q1和Q2均为截止状态,此时EN和IO0的状态由其他电路决定(内部/外部上拉电阻)。
当不同时为0或者1时:
EN = RTS
IO0 = DTR
注意这种逻辑下 EN和IO0是不可能同时为0的,然而进入下载模式则需要如下的序列
1. IO = 0; EN = 0
2. IO = 0; EN 0 -> 1
再来继续分析一下esptool.py里下载相关的代码
# 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
1) self._setRTS(True) # EN=LOW, chip in reset
time.sleep(0.1)
2) self._setDTR(True) # IO0=LOW
3) self._setRTS(False) # EN=HIGH, chip out of reset
time.sleep(0.05)
4) self._setDTR(False) # IO0=HIGH, done
注意True
是低电平,False
为高电平,另外代码中的setDTR()
和setRTS()
两条语句之间虽然看上去紧挨着没有延时,然而由于这里是高级语言python
,两条语句之间的延时并不能忽略,因此分析的时候必须依次的进行状态分析,以下分为四个阶段依次分析
-
- 设置DTR = 1; RTS = 0, 此时Q1导通,Q2截止, EN = 0; IO0 = 1
-
- 设置DTR = 0; RTS = 0, 此时Q1截止,Q2截止, EN = 1; IO0 = 1
-
- 设置DTR = 0; RTS = 1, 此时Q1截止,Q2导通, EN = 1; IO0 = 0
-
- 设置DTR = 1; RTS = 1, 此时Q1截止,Q2截止, EN = 1; IO0 = 1