我用的 ESP32 DEVKIT V1引脚图
一、GPIO
1、初始化GPIO
pinMode(pin, mode)
作用:设置一个引脚(pin)作为GPIO时的I/O模式。
参数:
pin:引脚编号
mode:GPIO的I/O模式,取值有3种
INPUT :作为数字输入
OUTPUT :作为数字输出
INPUT_PULLUP:作为数字输入,且使能引脚的内部上拉电阻
注意:
a、引脚作为PWM输出时,无需先前使用pinMode配置其模式,因为PWM本身就代表了输出的意思。且官方库源代码中可以发现,它已经帮我们配置为输出了。
b、模拟引脚也可以作为数字引脚使用,完全OK。这在数字引脚不够用的情况下非常有用。
2、GPIO数字输出
digitalWrite(pin,value)
作用:设置一个数字输出引脚的输出电平值,HIGH或者LOW。
参数:
pin:引脚编号。此引脚必须在之前使用pinMode设置为OUTPUT模式。
value:2个值
LOW:输出低电平
HIGH:输出高电平
3、GPIO数字输入
int digitalRead(pin)
作用:读取一个数字输入引脚的电平值。
返回:HIGH(高电平)或者LOW(低电平)。
参数:
pin:引脚编号。
示例 : 按键控制灯亮灭
-
void
setup()
-
{
-
pinMode(
2,OUTPUT);
-
pinMode(
0,INPUT_PULLUP);
-
}
-
-
void
loop()
-
{
-
if(digitalRead(
0))
-
{
-
while(digitalRead(
0));
-
digitalWrite(
2,!digitalRead(
2));
-
}
-
}
4、GPIO模拟输入:analogRead(pin)
注意 : 模拟输入是通过PWM实现的, 所以不需要初始化PIN
analogRead(4)
5. 模拟信号输入分辨率: analogSetWidth(bit);
bit的值 | 范围 |
---|---|
9 | 0~511 |
10 | 0~1023 |
11 | 0~2047 |
12(默认) | 0~4095 |
6. 模拟信号输出 (基于LEDC)
LEDC是基于PWM调制实现模拟输出的.
与arduino uno主板不同, ESP32的PWM模拟是一个个通道 共16个, 通道可以映射到引脚上. 引脚就可以输出PWM信号了.
6.1 设置通道 ledcSetup(channel,freq,bit_num)
参数:
- channel : LEDC的PWM通道参数,可选0~15
- freq : 10Hz到40MHz , 但较高的频率精确度低
- bit_num: 占空比分辨率(可选1~16), 比如bit_num=8 则范围 0~2的8次方 , 也就是0~255
推荐的配置:
频率 | 位深 | 过渡的可用步骤 |
---|---|---|
1220赫兹 | 16 | 65536 |
2441赫兹 | 15 | 32768 |
4882赫兹 | 14 | 16384 |
9765Hz | 13 | 8192 |
19531赫兹 | 12 | 4096 |
ledcSetup(1,1200,16);
6.2 通道与引脚映射 ledcAttachPin(pin,channel)
ledcAttachPin(5,1);
注意: 一个通道可以同时映射多个引脚
6.3 取消引脚的PWM映射 ledcDetachPin(pin)
ledcDetachPin(5);
6.4 向指定通道写入占空比 ledcWrite(channel,duty)
例: 呼吸灯
-
bool add_status =
true;
-
void setup()
-
{
-
pinMode(
2,OUTPUT);
-
ledcSetup(
2,
1200,
8);
-
ledcAttachPin(
2,
2);
-
}
-
-
void loop()
-
{
-
for(
int i =
0 ; i<
256; i++)
-
{
-
if(add_status)
-
{
-
ledcWrite(
2,i);
-
}
-
else
-
{
-
ledcWrite(
2,
256-i);
-
}
-
delay(
5);
-
}
-
add_status = !add_status;
-
}
例子, 全彩呼吸灯
-
#include <Arduino.h>
-
-
#define LED_R 27
-
#define LED_G 33
-
#define LED_B 32
-
-
void
setup()
-
{
-
Serial.begin(115200);
-
ledcSetup(1,
1200,
8
);
-
ledcSetup(2,
1200,
8
);
-
ledcSetup(3,
1200,
8
);
-
-
ledcAttachPin(LED_R,
1
);
-
ledcAttachPin(LED_G,
2
);
-
ledcAttachPin(LED_B,
3
);
-
-
ledcWrite(1,
255
);
-
ledcWrite(2,
255
);
-
ledcWrite(3,
255
);
-
}
-
-
void
loop()
-
{
-
for
(int
i
=
0
;
i
<
510
;
i++)
-
{
-
if
(i
>=
0
&&
i
<
255
)
-
ledcWrite(1,
255
-
i);
-
if
(i
>=
255
&&
i
<
510
)
-
ledcWrite(1,
i
-
255
);
-
-
if
(i
>=
0
&&
i
<
170
)
-
ledcWrite(2,
85
+
i);
-
if
(i
>=
170
&&
i
<
425
)
-
ledcWrite(2,
425
-
i);
-
if
(i
>=
425
&&
i
<
510
)
-
ledcWrite(2,
i
-
425
);
-
-
if
(i
>=
0
&&
i
<
85
)
-
ledcWrite(3,
85
-
i);
-
if
(i
>=
85
&&
i
<
340
)
-
ledcWrite(3,
i
-
85
);
-
if
(i
>=
340
&&
i
<
510
)
-
ledcWrite(3,
595
-
i);
-
delay(10);
-
}
-
}
6.5 向指定通道输出指定频率的音符信号 ledcWriteTone(channel, freq)
6.6 向指定通道输出指定的音符和音阶 ledcWriteNote(channel,note,octava)
参数
- note : 音符 可选(NOTE_C, NOTE_Cs, NOTE_D, NOTE_Eb, NOTE_C......)
- octava : 音阶 , 可选0~7
7. 模拟信号输出函数 (基于DAC)
ESP32提供了两个DAC通道, 对应引脚25 , 26. 精度为8位.
dacWrite(pin,value);
- value取值: 0~255
-
void setup()
-
{
-
-
}
-
-
void loop()
-
{
-
for(
int i =
0 ; i<
256; i++)
-
{
-
dacWrite(
25,i);
-
delay(
10);
-
}
-
}
二、串口打印 UART
ESP32共有3个UART端口, 其中UART1用于Flash读/写.
串口名 | Arduino名 | TX | RX |
---|---|---|---|
UART0 | Serial | pin1 | pin3 |
UART1 | Serial1 | pin10 | pin9 |
UART2 | Serial2 | pin17 | pin16 |
1、串口初始化
Serial.begin(speed, config)
- 参数:
- speed:波特率,一般取值9600,115200等。
- config:设置数据位、校验位和停止位。默认SERIAL_8N1表示8个数据位,无校验位,1个停止位。
- 返回值:无。
2、关闭串口
Serial.end()
- 描述:禁止串口传输。此时串口Rx和Tx可以作为数字IO引脚使用。
- 原型:Serial.end()
- 参数:无。
- 返回值:无。
3、串口打印
Serial.print()
- 描述:串口输出数据,写入字符数据到串口。
- 原型:
- Serial.print(val)
- Serial.print(val, format)
- 参数:
- val:打印的值,任意数据类型。
- config:输出的数据格式。BIN(二进制)、OCT(八进制)、DEC(十进制)、HEX(十六进制)。对于浮点数,此参数指定要使用的小数位数。
4、串口输出数据并换行 println() 和 printf()
Serial.println()
Serial.printf()
- 描述:串口输出数据并换行。
- 原型:
- Serial.println(val)
- Serial.println(val, format)
- 参数:
- val:打印的值,任意数据类型。
- config:输出的数据格式。
- 返回值:返回写入的字节数。
附: 常用格式字符及转义字符
字符 | 说明 |
---|---|
%o | 八进制整数输出 |
%d | 十进制整数输出 |
%x | 十六进制整数输出 |
%f | 浮点输出,默认6位小数 |
%c | 单字符输出 |
%s | 字符串输出 |
\n | 换行 |
\r | 回车 |
\t | Tab制表符 |
5、将二进制数写入串口
Serial.write()
描述
将二进制数据写入串行端口。该数据以字节或一系列字节的形式发送;要发送代表数字数字的字符,请改用print()函数。
句法
*Serial*.write(val)
*Serial*.write(str)
*Serial*.write(buf, len)
参量
*Serial*
:串行端口对象。请参阅“ 串行”主页上每个板的可用串行端口列表。
val
:要作为单个字节发送的值。
str
:作为一系列字节发送的字符串。
buf
:要作为一系列字节发送的数组。
len
:要从数组发送的字节数。
退货
write()
将返回写入的字节数,尽管读取该数字是可选的。资料类型:size_t
。
6、判断串口缓冲区的状态
Serial.available()
- 描述:判断串口缓冲区的状态,返回从串口缓冲区读取的字节数。
- 原型:Serial.available()
- 参数:无。
- 返回值:可读取的字节数。
7、读取串口数据
Serial.read()
描述:读取串口数据,一次读一个字符,读完后删除已读数据。
- 原型:Serial.read()
- 参数:无。
- 返回值:返回串口缓存中第一个可读字节,当没有可读数据时返回-1,整数类型。
-
#include<stdio.h>
-
#include<stdlib.h>
-
char rev;
-
void setup() {
-
Serial.begin(
115200);
-
}
-
-
void loop() {
-
if(Serial.available())
-
{
-
rev=Serial.read();
-
Serial.print(
"rev=");
-
Serial.println(rev);
-
}
-
}
Serial.readBytes()
- 描述:从串口读取指定长度的字符到缓存数组。
- 原型:Serial.readBytes(buffer, length)
- 参数:
- buffer:缓存变量。
- length:设定的读取长度。
返回值:返回存入缓存的字符数。
Serial.readString()
描述
Serial.readString()
从串行缓冲区读取字符到字符串。如果超时,该函数将终止。
Serial.readString()
从Stream实用程序类继承。
句法
*Serial*.readString()
参量
*Serial*
:串行端口对象。请参阅“ 串行”主页上每个板的可用串行端口列表。
返回值
一个String
从串行读缓冲器
Serial.readStringUntil()
描述
readStringUntil()
从串行缓冲区读取字符到字符串。如果超时,该函数将终止(请参见setTimeout())。
Serial.readStringUntil()
从Stream实用程序类继承。
句法
*Serial*.readStringUntil(terminator)
参量
*Serial*
:串行端口对象。请参阅“ 串行”主页上每个板的可用串行端口列表。
terminator
:要搜索的字符。允许的数据类型:char
。
返回值
String
从串行缓冲区的整个读取,直到终止符
注意和警告
终止符将从串行缓冲区中丢弃。
Serial.find()
描述
Serial.find()
从串行缓冲区读取数据,直到找到目标为止。true
如果找到目标,函数将返回false
超时。
Serial.find()
从流实用程序类继承。
句法
*Serial*.find(target)
*Serial*.find(target, length)
参量
*Serial*
:串行端口对象。请参阅“ 串行”主页上每个板的可用串行端口列表。
target
:要搜索的字符串。允许的数据类型:char
。
length
:目标的长度。允许的数据类型:size_t
。
返回值
资料类型:bool
。
Serial.findUntil()
描述
Serial.findUntil()
从串行缓冲区读取数据,直到找到给定长度的目标字符串或终止符字符串。
如果找到目标字符串,则该函数返回true;如果超时,则返回false。
Serial.findUntil()
从Stream实用程序类继承。
句法
*Serial*.findUntil(target, terminal)
参量
*Serial*
:串行端口对象。请参阅“ 串行”主页上每个板的可用串行端口列表。
target
:要搜索的字符串。允许的数据类型:char
。
terminal
:搜索中的终端字符串。允许的数据类型:char
。
返回值
资料类型:bool
。
Serial.parseFloat()
描述
Serial.parseFloat()
从串行缓冲区返回第一个有效的浮点数。parseFloat()
以不是浮点数的第一个字符终止。如果超时,该函数将终止(请参见Serial.setTimeout())。
Serial.parseFloat()
从Stream实用程序类继承。
句法
*Serial*.parseFloat()
*Serial*.parseFloat(lookahead)
*Serial*.parseFloat(lookahead, ignore)
参量
*Serial*
:串行端口对象。请参阅“ 串行”主页上每个板的可用串行端口列表。
lookahead
:用于在流中向前查询浮点数的模式。允许的数据类型:LookaheadMode
。允许lookahead
值:
-
SKIP_ALL
:扫描流中的浮点数时,除负号,小数点或数字以外的所有字符都将被忽略。这是默认模式。 -
SKIP_NONE
:任何内容都不会被跳过,除非第一个等待的字符有效,否则流不会被触摸。 -
SKIP_WHITESPACE
:仅跳过制表符,空格,换行符和回车符。
ignore
:用于跳过搜索中指示的字符。例如,用于跳过数千个分频器。允许的数据类型:char
返回值:
类型:float
。
Serial.parseInt()
描述
在输入的序列中查找下一个有效整数。如果超时,该函数将终止(请参见Serial.setTimeout())。
Serial.parseInt()
从Stream实用程序类继承。
尤其是:
- 如果没有读取到可配置的超时值的字符,或者读取了非数字,则分析停止。
- 如果在发生超时(请参见Serial.setTimeout())时未读取到有效数字,则返回0;否则返回0。
句法
*Serial*.parseInt()
*Serial*.parseInt(lookahead)
*Serial*.parseInt(lookahead, ignore)
参量
*Serial*
:串行端口对象。请参阅“ 串行”主页上每个板的可用串行端口列表。
lookahead
:用于在流中向前搜索整数的模式。允许的数据类型:LookaheadMode
。允许lookahead
值:
-
SKIP_ALL
:扫描流中的整数时,将忽略数字或减号以外的所有字符。这是默认模式。 -
SKIP_NONE
:任何内容都不会被跳过,除非第一个等待的字符有效,否则流不会被触摸。 -
SKIP_WHITESPACE
:仅跳过制表符,空格,换行符和回车符。
ignore
:用于跳过搜索中指示的字符。例如,用于跳过数千个分频器。允许的数据类型:char
返回值
下一个有效整数。资料类型:long
。
8.判断串口是否就绪** Serial
描述
指示指定的串行端口是否已就绪。
在具有本地USB的板上if (Serial)
(或if(SerialUSB)
在Due上)指示USB CDC串行连接是否打开。对于所有其他板卡和非USB CDC端口,这将始终返回true。
这是在Arduino IDE 1.0.1中引入的。
句法
if (Serial)
while (!Serial) 等等
参量
没有
返回值
如果指定的串行端口可用,则返回true。如果在准备就绪之前查询Leonardo的USB CDC串行连接,则仅返回false。类型:bool
。
9、设置串口超时**
Serial.setTimeout()
描述
Serial.setTimeout()
设置等待串行数据的最大毫秒数。默认值为1000毫秒。
Serial.setTimeout()
从Stream实用程序类继承。
句法
*Serial*.setTimeout(time)
参量
*Serial*
:串行端口对象。请参阅“ 串行”主页上每个板的可用串行端口列表。
time
:超时时间(以毫秒为单位)。允许的数据类型:long
。
退货
没有
注意和警告
使用通过*Serial*.setTimeout()
以下方式设置的超时值的串行函数:
*Serial*.find()
*Serial*.findUntil()
*Serial*.parseInt()
*Serial*.parseFloat()
*Serial*.readBytes()
*Serial*.readBytesUntil()
*Serial*.readString()
*Serial*.readStringUntil()
也可以看看
-
void setup() {
-
//Initialize serial and wait for port to open:
-
Serial.begin(
9600);
-
while (!Serial) {
-
;
// wait for serial port to connect. Needed for native USB
-
}
-
}
-
-
void loop() {
-
//proceed normally
-
}
-
/*
-
Serial
-
串口通讯实验
-
*/
-
int incomedate =
0;
-
void setup() {
-
-
Serial.begin(
9600);
//设置串口波特率9600
-
-
Serial.
println(
78, BIN);
// "1001110"
-
Serial.
println(
78, OCT);
// "116"
-
Serial.
println(
78, DEC);
// "78"
-
Serial.
println(
78, HEX);
// "4E"
-
Serial.
println(
1.23456,
0);
// "1"
-
Serial.
println(
1.23456,
2);
// "1.23"
-
Serial.
println(
1.23456,
4);
// "1.2346"
-
Serial.
println(
'N');
// "N"
-
Serial.
println(
"Hello world.");
// "Hello world."
-
}
-
void loop() {
-
-
if (Serial.available() >
0)
//串口接收到数据
-
{
-
incomedate = Serial.read();
//获取串口接收到的数据
-
if (incomedate ==
'H')
-
{
-
Serial.
println(
"Good Job!");
-
}
-
}
-
delay(
1000);
-
}
使用的串口Serial其实是HardwareSerial类的实例化,实例化过程中传入了串口号,实现过程如下: