Arduino学习

A000066_03.front_970c6014-61ab-4226-a20f-14cc6d8d682c_1000x750

[TOC]

Arduino UNO

解析图

image-20211008233333288

  1. 电源
  • 通过USB供电,电压为5V;
  • 通过DC电源输入接口供电,电压要求7~12V;
  • 通过电源接口处5V或者VIN供电,5V端口处供电必须为5V,VIN端口处供电为7~12V;
  1. 指示灯
  • ON,电源指示灯
  • TX,串口发送指示灯
  • RX,串口接受指示灯
  • L,可编程指示灯,通过特殊电路连接到13号引脚,当13号引脚为高电平高阻态时点亮,低电平时不会点亮
  1. 存储空间
  • FLASH 32KB 其中0.5KB作为BOOT区存放引导程序,实现串口下载的功能。另外的31.5KB存放程序
  • SRAM 2KB 内存
  • EEPROM 1KB 电可擦写的可编程只读存储器
  1. 输入/输出端口

Pinout-UNOrev3_latest

  • UART通信,为0(RX)和1(TX)引脚,用于接收和发送串口数据,这两个引脚通过连接到ATmega16U2与计算机通信
  • 外部中断,为2和3引脚,可以输入外部中断信号
  • PWM输出,为3、5、6、9、10和11引脚,可以输出PWM波
  • SPI通信,为10(SS)、11(MOSI),12(MISO)和13(SCK)引脚,可用于SPI通信
  • TWI通信,为A4(SDA),A5(SCL)引脚和TWI接口,可用于TWI通信,兼容IIC通信
  • AREF,模拟输入参考电压的输入端口
  • RESET,复位端口,接低电平会使Arduino复位

Arduino语言及程序结构

程序结构

1
2
3
4
5
6
7
8
void setup()
{
// put your setup code here, to run once:
}
void loop()
{
// put your main code here, to run repeatedly:
}

Arduino控制器通电或复位后,执行setup()函数中的程序代码,只会执行一次。setup()函数中的代码执行完以后,会重复执行loop()函数中的程序。

引脚操作

pinMode(pin,value)

pinMode有三种模式

INPUT(0) 输 入 模 式

OUTPUT(1) 输 出 模 式

INPUT_PULLUP(2) 输入上拉模式

digitalWrite(pin,value)

value的值

HIGH(1):高电平

LOW(0):低电平

digitalRead(pin)

将-0.5~1.5V的输入电压作为低电平

将3~5.5v的输入电压作为高电平

模拟量

analogRead(A0)

Arduino有十位精度,5v电压可分为0~1023

analogWrite(9)

Arduino的模拟量输出不需要再setup()中声明,采用的是PWM方式模拟的电压输出,范围为0~255。

analogWrite和analogRead已经完成了引脚的初始化,不用在setup()函数中初始化了。

串口通信

1
Serial.begin(9600)

规定串口通信波特率,可用300、600、1200、2400、4800、9600、14400、19200、28800、38400、57600、115200,单位是(bit)。

1
2
Serial.print(val);
Serial.println(val);//与print不同的是,println输出完之后输出一组回车换行符
1
Serial.read()

调用该语句,每次返回1字节的数据,在使用Serial时,Arduino会在SRAM开辟一段64B的空间,串口接收到的数据都放在该空间中。当缓存区中没有数据时,会返回int型值-1。

1
millis()

该函数返回Arduino从通电(或复位)到现在的时间,单位为毫秒,类型为unsigned long大概50天会溢出一次。

1
micros()

该函数返回系统运行时间,单位是微秒,约70分钟溢出一次。

1
delay(1000)

此函数为毫秒级延时

1
delayMicroseconds()

此函数为微秒级延时

高级应用

tone(pin,frequency[,duration])

可以指定引脚产生占空比50%的指定频率的方波。

使用tone()函数会影响3号和11号引脚的PWM输出,并且只能作用于一个引脚,对其他引脚使用需使用noTone()函数停止之前使用了tone()函数的引脚。

pulseIn(pin,value[,timeout])

功能:检测指定引脚上的脉冲信号宽度

参数:

pin:读取脉冲的引脚

value:读取的脉冲类型,为HIGH或LOW

timeout:超时时间,单位为微秒,未设置超时时间,默认为1s

返回值:脉冲宽度,单位为微秒,数据类型为无符号长整型,如果未检测到脉冲,则返回0。


超声波模块使用方法:

引脚名称 说明
Vcc 电源5V
Trig 触发引脚
Echo 回馈引脚
GND

给Trig引脚至少10$\mu s$的高电平信号触发测距功能,模块会自动发送8个40kHz的超声波脉冲,并自动检测是否有信号返回,若有信号返回,则Echo引脚会输出高电平,高电平持续时间就是超声波从发射到返回的时间。

设置ADC参考电压

$\mathrm{analogRead}(\mathrm{pin})函数返回值=\frac{被测电压}{参考电压}\times1023$,当没有设置参考电压时,默认使用工作电压(5V)为参考电压。通过$\mathrm{AREF}$引脚输入外部参考电压。使用$\mathrm{analogReference()}$设置参考电压

1
analogReference(type);
type 说明
DEFAULT 工作电压作为参考电压
INTERNAL 使用内部参考电压(UNO为1.1V)
EXTERNAL 使用从AREF引脚输入的外部参考电压

❌ 外部参考电压必须大于0,且小于当前工作电压(5V),否则可能会损坏Arduino

外部中断

中断引脚

ArduinoUNO只支持两个中断引脚,分别为2(int0)、3(int1)。

中断模式

模式名称 说明
LOW 低电平触发
CHANGE 电平变化触发,即高变低或低变高
RISING 上升沿触发
FALLING 下降沿触发

中断函数

中断函数不能带有任何参数,且返回类型为空。

1
2
3
4
void test()
{
Serial.println("Hello!");
}

还应在$\mathrm{setup()}$中使用$\mathrm{attachInterrupt()}$对中断引脚进行初始化。

attachInterrupt(interrupt,function,mode)

1
attachInterrupt(0,test,LOW);

如果不需要中断,可以使用$\mathrm{detachInterrupt()}$来关闭中断。

1
detachInterrupt(interrupt);

串口通信

Arduino硬件集成了串口,IIC,SPI三种常见的通信方式。

串口通信示意图

数据帧格式:

image-20220829115702966

  • 起始位总是低电平
  • 数据位默认使用8位数据位
  • 校验位可以设置奇校验或偶校验或无校验,默认无校验
  • 停止位表示数据帧传输结束,停止位总为高电平,可设置1位或2位,默认为1位

函数

available()

功能:获取串口接受缓存区的字节数,缓存区最多保存64B

begin()

初始化串口,配置各项参数

1
Serial.begin(speed[,config])

speed:波特率

config:数据位、校验位、停止位配置。

end()

结束串口通信,可使该串口所在的数字引脚作为普通数字引脚使用。

find()

从串口缓存区读取数据直到读到指定的字符或字符串。

1
Serial.find(target);

返回true(找到),false(没有找到)。

findUntil()

从串口缓存区读取数据,直到读到指定的字符串或指定的停止符。

1
Serial.findUntil(target,terminal);

target:需要搜索的字符串或字符。

terminal:停止符。

无返回值。

flush()

等待正在发送的数据发送完成。

parseFloat()

从串口缓存区返回第一个有效的float数据。

parseInt()

从串口流中查找第一个有效的整型数据。

peek()

返回1字节的数据,但不会从接收缓存区删除该数据,如无可读数据,返回-1。

print()

将数据输出到串口,以ASCII码形式输出。

1
Serial.print(val,format);

format:

  1. 输出的进制形式
  • BIN(二进制)
  • DEC(十进制)
  • OCT(八进制)
  • HEX(十六进制)
  1. 指定float型数据带小数的位数。

println()

功能与print()相同,只是会加回车换行。

read()

从串口读取1个字节数据,并将其从接受缓存区移除。

readBytes()

从缓存区读取指定长度的字符,并将其存入一个数组中。

1
Serial.readBytes(buffer,length);

buffer:数组

length:读取的字符长度,如果没有找到有效的数据,则返回0;

readBytesUntil()

1
Serial.readBytesUntil(character,buffer,length)

character:停止符。

setTimeout()

设置超时时间,用于设置readBytes()和readBytesUntil()等待串口数据时间。

1
Serial.setTimeout(time)

time单位为毫秒

write()

输出数据到串口

1
2
3
Serial.write(val);
Serial.write(str);
Serial.write(buf,len)

print()和write()的区别:

print是将数据转换为ASCII码再发送出去,如输出整型变量123,会输出123。

write发送的是数值本身,串口监视器接收到数据后,会将数值当作ASCII码形式显示,所以write输出整型变量123,会显示{

串口事件

1
2
3
4
void serialEvent()
{
//Put the code here;
}

当串口接收缓存区中有数据时,会触发该事件。会在两次loop()循环之间检测串口缓冲区是否有数据,如果有就执行serialEvent函数。

串口缓冲区

串口缓冲区默认为64字节,通过宏定义可以增大读写缓冲区的空间。

1
2
#define SERIAL_TX_BUFFER_SIZE 128
#define SERIAL_RX_BUFFER_SIZE 128

软件模拟串口通信——SoftwareSerial

软串口是由程序模拟生成的,使用不如硬串口稳定,使用之前需先声明包含SoftwareSerial.h头文件,其成员函数与硬串口类似,有available()begin()write()print()println()peek()等。

SoftwareSerial()

初始化软串口

1
SoftwareSerial mySerial(rxPin,txPin);

listen()

开启软串口监听状态。Arduino同一时间内只能监听一个软串口

isListening()

检测软串口是否处于监听状态

overflow()

检测缓冲区是否已经溢出,软串口缓冲区最多可保存64B数据

当切换不同的软串口时,需要对要监听的软串口使用port.listen()启动监听。

IIC总线使用

使用IIC协议可以通过两根双向的总线(数据线SDA和时钟线SCL)使Arduino连接最多128个IIC从机。IIC又称TWI(Two-Wire serial Interface)

IIC是一种半双工通信方式。

Arduino使用第三方类库Wire来进行IIC通信

IIC通信函数示意图

begin([address])

未指定address,则以主机模式加入IIC总线,address可设置成0~127中的任意地址。

requestFrom(address,quantity[,stop])

quantity:请求的字节数

stop:当为true时,发送停止信息,释放IIC总线,当为false,继续保持IIC总线有效连接。

beginTransmission(address)

开始向从机发送数据

endTransmission(stop)

当为true时,释放IIC总线,为false继续保持有效连接。

返回值:byte

  • 0,成功
  • 1,数据过长,超过发送缓存区
  • 2,在地址发送时接收到NACK信号
  • 3,在数据发送时接收到NACK信号
  • 4,其他错误

write()

将要发送的数据加入发送队列

available()

返回接收到的字节数

read()

读取1B的字节

onReceive(handler)

当从机接收到主机发送的数据时触发

OnRequest(handler)

当从机接收到主机的数据请求时触发

连线

可以通过SCL、SDA接口或A4、A5接口一一连接来建立IIC连接