从零开始的ESP8266探索(12)-IO口及系统时间说明与记录
目的
对于IO口的的运用才是单片机最基本的功能,这里就对Arduino for esp8266中IO口基本使用做个说明记录
IO口基本功能说明
Digital IO
Arduino for esp8266可以使用一般Arduino操作IO口的方式去操作,具体说明如下:
- 使用
pinMode(pin, mode)
来设置GPIO口工作模式,pin
取值范围0 ~ 16,mode
可选值见下文; - 使用
digitalWrite(pin, value)
来设置输出状态,value
可选值为HIGH或LOW,即1和0; - 使用
digitalRead(pin)
来读取GPIO口电平,返回值为HIGH或LOW,即1和0; - GPIO0 ~ 15可以设置为
INPUT
、OUTPUT
、INPUT_PULLUP
模式(输入、输出、上拉输入),GPIO16可以设置为INPUT
、OUTPUT
、INPUT_PULLDOWN_16
模式(输入、输出、下拉输入); - 在系统上电启动的时候这些管脚默认设置为
INPUT
模式; - GPIO6 ~ 11在大多数模块中用来连接外部flash芯片,所以对这些管脚进行 操作可能会引起程序崩溃;
另外GPIO0 ~ 15支持外部中断,使用方法及示例如下:
- 使用
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode)
来设置中断,mode
可选值CHANGE
、RISING
、FALLING
(电平改变时、上升沿、下降沿); - 使用
detachInterrupt(digitalPinToInterrupt(pin))
来关闭中断;
按下图连接电路,然后上传下面代码到模块中:
int count = 0;
void callback()
{
Serial.println("按键被按下了!");
count++;
if(count==10) //触发10次中断后关闭中断
{
detachInterrupt(digitalPinToInterrupt(5));
Serial.println("关闭中断!");
}
}
void setup()
{
Serial.begin(115200);
Serial.println();
pinMode(5, INPUT);
Serial.println("开启中断!");
attachInterrupt(digitalPinToInterrupt(5), callback, FALLING);
}
void loop()
{
}
可以看到运行状况如下,按钮被按下时触发中断(图中按键代码并未加入消抖,可以看到有时按下按键会触发多次),触发十次后中断被关闭。
Analog input
ADC针脚可以用于采集模拟信号电压,说明如下:
- 使用
analogRead(A0)
来读取模拟电压; - 电压量程为0 ~ 1.0V,电压值范围为0 ~ 1023;
Analog output(PWM)
GPIO0 ~ 16支持PWM输出,具体说明如下:
- 使用
analogWrite(pin, value)
在对于pin上输出PWM信号,value
表示高电平保持时间,默认下value取值为0 ~ 1023,当value为0时即停止PWM输出; - 使用
analogWriteRange(new_range)
修改PWM value可写范围,默认range为1023; - 使用
analogWriteFreq(new_frequency)
修改PWM频率,new_frequency
取值范围100 ~ 40000,默认为1000; -
range
*frequency
不应大于1000000;
按下图连接电路,然后上传下面代码到模块中:
void setup()
{
Serial.begin(115200);
Serial.println();
analogWriteFreq(100); //设置PWM频率为100Hz
}
void loop()
{
for (int j = 3; j < 9; j++)
{
analogWrite(5, j * 100); //设置PWM占空比
for (int i = 0; i < 1000; i++)
{
delay(1);
Serial.println(analogRead(A0)); //打印输出ADC引脚上电压
}
}
}
可以看到PWM波占空比如代码描述的周期性变化。
Serial
串口相关的内容非常多,这里只简单说明下,具体使用可以参考下文连接:
- Arduino for esp8266可以使用
Serial
和Serial1
两个串口,Serial
可以将针脚映射到某些其他的GPIO口上; -
Serial1
只能用于发送数据; - 串口具有硬件FIFO,收发各128字节,另外收发还各自有256字节缓存;
- 串口收发均有硬件及中断完成,但是当缓存不够用时将会阻塞程序;
- 接收缓存可以通过
Serial.setRxBufferSize(size_t size)
更改接收缓存大小(默认256字节); - 可以使用
Serial.detectBaudrate(time_t timeoutMillis)
来检测外部输入串口的波特率; - 串口发送可用
print()
、println()
、write()
等方法; - 串口接收可用
read()
、readBytes()
等方法; - ……太多了,先放出资料链接,更多使用例程以后再添加;
串口更多内容可参考:
https://arduino-esp8266.readthedocs.io/en/latest/reference.html#serial(Arduino for esp8266文档对串口的描述)
https://github.com/esp8266/Arduino/blob/master/cores/esp8266/HardwareSerial.h
https://github.com/esp8266/Arduino/blob/master/cores/esp8266/HardwareSerial.cpp
https://github.com/esp8266/Arduino/blob/master/cores/esp8266/uart.h
https://github.com/esp8266/Arduino/blob/master/cores/esp8266/uart.c
https://github.com/esp8266/Arduino/blob/master/libraries/esp8266/examples/SerialDetectBaudrate/SerialDetectBaudrate.ino(自动检测波特率示例)
https://www.arduino.cc/reference/en/language/functions/communication/serial/(Arduino串口介绍及方法说明)
I2C
I2C手头没有可以测试的东西,先做下记录:
https://arduino-esp8266.readthedocs.io/en/latest/libraries.html#i2c-wire-library(Arduino for esp8266文档对I2C的描述)
https://github.com/esp8266/Arduino/tree/master/libraries/Wire(Arduino for esp8266 I2C库)
SPI
SPI手头没有可以测试的东西,先做下记录:
https://arduino-esp8266.readthedocs.io/en/latest/libraries.html#spi(Arduino for esp8266文档对SP1的描述)
https://github.com/esp8266/Arduino/tree/master/libraries/SPI(Arduino for esp8266 SPI库)
https://github.com/esp8266/Arduino/tree/master/libraries/SPISlave(Arduino for esp8266 SPISlave库及例程)
系统时间及延时方法
- 使用
millis()
和micros()
可分别获取以毫秒及微秒为单位的系统时间; - 使用
delay(ms)
可进行毫秒级延时; - 使用
delayMicroseconds(us)
可进行微秒级延时,该操作会阻塞系统运行,不建议用该方法完成20毫秒以上延时; - 当进行耗时操作时(>50ms)会影响系统网络功能,需要调用
delay(0)
或yield()
来维持网络功能;
上图中微秒时间差稍大于1000us,因为读取时间及串口打印操作本身有一定耗时;
参考资料
https://arduino-esp8266.readthedocs.io/en/latest/reference.html#
https://www.arduino.cc/reference/en/#functions
总结
IO口及系统时间相关内容和传统的Arduino中功能及使用方法相似,可能稍稍有些出入,有哪些方法可用、取值范围是多少等可以参考源码,具体的使用方法可以参考例程或是传统的Arduino相关教程。