1 程序结构
1.1 setup
Arduino 控制器通电或复位后,即会开始执行 setup()
函数中的程序,该部分只会执行一次。通常我们会在 setup()
函数中完成 Arduino 的初始化设置,如配置 I/O
口状态,初始化串口等操作。
void setup()
{
pinMode(led,OUTPUT);
Serial.begin(9600);
}
1.2 loop
在 setup()
函数中的程序执行完后,Arduino 会接着执行 loop()
函数中的程序。而 loop()
函数是一个死循环,其中的程序会不断的重复运行。通常我们会在 loop()
函数中完成程序的主要功能,如驱动各种模块,采集数据等。
void loop()
{
digitalWrite(led, HIGH); // 点亮LED
delay(1000); // 等待一秒钟
digitalWrite(led, LOW); // 通过将引脚电平拉低,关闭LED
delay(1000); // 等待一秒钟
}
1.3 main
注意:在进行 Arduino 开发时,没有像传统 C/C++ 程序使用入口函数 main
。实际上main
函数存在于 Arduino 核心库中,且仍然是程序的入口。
2 数字输入输出
2.1 pinMode
在使用输入或输出功能前,你需要先通过 pinMode()
函数配置引脚的模式为输入模式或输出模式,该函数无返回值,一般放在 setup()
函数体中。
pinMode(pin, mode)
/* 参数 pin 为指定配置的引脚编号参数,不过要注意这里是要接在数字引脚的;mode为指定的配置模式通常可用模式
有三种:INPUT 输入模式;OUTPUT 输出模式;INPUT_PULLUP 输入上拉模式 */
2.2 digitalRead
该函数的作用是获取引脚的电平情况,该函数返回值为int 型———HIGH(高电平)或者LOW(低电平),在使用该函数时需要预先使用pinMode(pin,INTPUT)
配置成输入模式。
digitalRead(pin);
// 参数pin为指定读取状态的引脚编号。返回值为获取到的信号状态,1为高电平,0为低电平。
2.3 digitalWrite
使用 pinMode(pin,OUTPUT)
配置成输出模式后,还需要使用 digitalWrite()
让其输出高电平或者是低电平。无返回值,一般放在 loop()
函数体中。
digitalWrite(pin, value)
// 参数 pin 为指定输出的引脚编号;参数 value 为你要指定输出的电平使用 HIGH 指定输出高电平,或是使用 LOW 指定输出低电平。
3 模拟输入输出
3.1 analogRead
模拟输入引脚是带有 ADC(Analog-to-Digital Converter,模数转换器)功能的引脚。它可以将外部输入的模拟信号转换为芯片运算时可以识别的数字信号,从而实现读入模拟值的功能,读取周期为100微妙,即最大读取速度可达每秒10000次。模拟输入功能需要使用 analogRead()
函数。
analogRead(pin)
// 参数pin是指定要读取模拟值的引脚,被指定的引脚必须是模拟输入引脚。
Arduino Uno 模拟输入功能有10位精度,即可以将0~5V的电压信号转换为0~1023的整数形式表示。
3.2 analogWrite
使用 analogWrite()
函数可以实现 PWM 输出功能,即调用analogWrite函数后,相应的引脚会产生一个指定占空比的稳定方波(频率大约为490Hz),直到下一次调用该函数,可应用在LED亮度调节、电机调速控制等方面。
在 analogWrite()
和 analogRead()
函数内部,已经完成了引脚的初始化,因此不用在 Setup()
函数中进行初始化操作。
analogWrite(pin,value)
// 参数pin是指定要输出 PWM 波的引脚,不过要注意使用可以输出 PWM 的引脚带PWM功能的引脚标有波浪线'~';参数value指定是PWM的脉冲宽度,范围为0~255,对应占空比为 value/255。
4 高级输入输出
4.1 tone
tone()
主要用于Arduino连接蜂鸣器或扬声器发声。可以让指定引脚产生一个占空比为50%的指定频率的方波。
tone(pin, frequency, duration)
/* pin: 需要输出方波的引脚 frequency: 输出的频率,unsigned int型 duration: 方波持续的时间,单位毫秒。
如果没有该参数,Arduino将持续发出设定的音调,直到你改变发声频率或者使用noTone() 函数停止发声。*/
noTone(pin)
// pin:需要停止方波输出的引脚
4.2 pulseln
检测指定引脚上的脉冲信号宽度。例如当要检测高电平脉冲时,pulseIn()
会等待指定引脚输入的电平变高,当变高后开始记时,直到输入电平变低,停止计时。pulseln()
函数会返回这个脉冲信号持续的时间,即这个脉冲的宽度。函数还可以设定超时时间,如果超过设定时间,仍未检测到脉冲,则会退出 pulseIn()
函数并返回0。当没有设定超时时间时,pulseIn()
会默认1秒钟的超时时间。
pulseIn(pin, value, timeout)
// pin:需要读取脉冲的引脚 value:需要读取的脉冲类型,HIGH或LOW timeout:超时时间,单位微秒,数据类型为无符号长整型。
返回脉冲宽度,单位微秒,数据类型为无符号长整型。如果在指定时间内没有检测到脉冲,则返回0。
4.3 外部中断
attachInterrupt(pin, ISR, mode)
// 对中断引脚进行初始化配置,以开启Arduino的外部中断功能
/*
pin:中断引脚,选择具体型号对应型号的中断,对于UNO可选0/1,对应2/3号数字引脚。
ISR:中断函数名,当中断发生时执行该子程序部分,其中参数为函数的指针。
mode:中断模式,有四种类型-LOW(低电平触发)、CHANGE(跳变时触发)、RISING(上升沿触发)、FALLING(下降沿触发)。
*/
如果你不需要使用外部中断了,你可以用中断分离函数 detachInterrupt()
来取消中断功能。
detachInterrupt(pin)
// interrupts()和noInterrupts()分别负责打开与关闭中断,这两个函数均为无返回值的函数,无参数。
5 时间控制
5.1 时间运行函数
millis( )
、 micros( )
获取 Arduino 通电后(或复位后)到现在的时间,单位毫秒(ms)。
5.2 延时函数
Arduino 提供了毫秒级和微秒级两种延时函数。运行延时函数时,会等待指定的时间,再运行此后的程序。
delay(ms)
// 此函数为毫秒级延时。参数为时长,类型unsigned long
delayMicroseconds(us)
// 此函数为微秒级延时。参数为时长,类型unsigned int
6 数学函数
6.1 min(x,y)
返回x,y 两者中较小的,函数原型为:
#define min(a,b) ((a)<(b)?(a):(b))
6.2 max(x,y)
返回x,y 两者中较大的,函数原型为:
#define max(a,b) ((a)>(b)?(a):(b))
6.3 abs(x)
获取x的绝对值,函数原型为:
#define abs(x) ((x)>0?(x):-(x))
6.4 constrain(amt,min,max)
constrain(amt,min,max)
函数的工作过程是,如果值amt小于min,则返回min,如果amt大于max,则返回max,否则,返回amt。该函数一般可以用于将值归一化到某个区间内。函数原型为:
#define constrain(amt,min,max) ((amt)<(min)?(min):((amt)>(max)?(max):(amt)))
6.5 map(x,in_min,in_max,out_min,out_max)
map(x, in_min, in_max, out_min, out_max)
函数的作用是将 [in_min, in_max] 范围内的x等比映射到 [out_min, out_max] 范围内。函数返回值为long型,原型为:
long map(long x,long in_min,long in_max,long out_min,long out_max)
{
return (x-in_min)*(out_max-out_min)/(in_max-in_min)+out_min;
}
6.6 三角函数
三角函数包括 sin(rad)
、cos(rad)
、tan(rad)
,分别得到rad的正弦值、余弦值和正切值。返回值都为double型。
6.7 随机数
(1)randomSeed(seed)
randomSeed()
函数用来设置随机数种子,随机种子的设置对产生的随机序列有影响。函数无返回值.
(2)random(howsmall,howbig)
应用 random 函数可生成一个随机数,两个参数 howsmall 和 howbig 决定了随机数的范围,函数的参数及返回值均为 long 型。
6.8 位操作
位操作用于设置或读取字节中某一位或几位,包括 bitRead()
、bitSet()
、bitClear()
等,具体定义及功能可以参考文件 wiring.h
。
7 串口通信
串口,也称UART (Universal Asynchronous Receiver Transmitter,通用异步(串行)收/发器)接口,是指 Arduino 硬件集成的串口。既可以使用 USB 接口与计算机连接而进行 arduino 与计算机之间的串口通信。还可以使用串口引脚连接其他串口设备进行通信。

两个串口设备间需要发送端(TX)与接收端(RX)交叉相连,并共用电源地(GND)。
7.1 串口配置
Serial.begin(speed, config)
// 参数speed是指串口通信波特率,波特率是指每秒传输的比特数,除以8就可以得到每秒传输的字节数,一般用9600、19200、57600、115200。
// config:数据位、校验位、停止位配置
7.2 串口输出
Serial.print(val) // val是你要输出的数据,各种类型的数据均可
Serial.println(val) // println会在输出完指定数据后,再输出一组回车换行符
7.3 串口输入
Serial.available() // 用于判断串口是否接受到数据,该函数返回值为int型,不带参数。
Serial.read() // 调用该语句,每次都会返回一个字节的数据,这个返回值便是当前串口读取到的数据。
了解更多,请阅读:Arduino串口通信
8 IIC总线的使用——Wire类库
使用 IIC 协议可以通过两根双向的总线(数据线 SDA 和时钟线 SCL )使 Arduino 连接最多128个IIC 从机设备。
与串口的一对一通信方式不同,总线通信通常有主机(Master)和从机(Slave)之分。通信时,主机负责启动和终止数据传送,同时还要输出时钟信号;从机会被主机寻址,并且响应主机的通信请求。
串口通信双方需要事先约定同样的波特率才能正常进行通信。而在 IIC 通信中,通信速率的控制由主机完成,主机会通过 SCL
引脚输出时钟信号供总线上的所有从机使用。同时,IIC是一种半双工通信方式,即总线上的设备通过SDA
引脚传输通信数据,数据的发送和接收由主机控制,切换进行。
// 主机部分
wire.begin( ); //作为主机加入到IIC总线
wire.beginTransmission(4); //向地址为4的从机传送数据
Wire.write(x); // 发送1B的数据
Wire.endTransmission( ); //结束传送
// 从机部分
//作为从机加入IIC总线,从机地址为4
Wire.begin(4); // 注册一个IIC事件
Wire.onReceive(receiveEvent); //初始化串口
Serial. begin(9600);
Wire.read( );
了解更多,请阅读:如何使用Arduino的IIC总线(Wire)
9 SPI总线的使用——SPI类库
SPI(Serial Peripheral Interface,串行外设接口)是 Arduino 自带的一种高速通信接口,通过它可以连接使用具有同样接口的外部设备。SPI 总线是一种同步串行总线,其收/发数据可以同时进行;也是一种总线通信方式,Arduino 可以通过 SPI 接口连接多个从设备,并通过程序来选择对某一设备进行连接使用。
10 多线程技术
针对多任务同时处理的工作场景,解决方法有多种,
1. 使用计时器或外部中断机制,完成多任务处理;
2. 使用Arduino 多线程技术,本质上也是中断机制。
Scoop多线程库的具体使用,请阅读:Arduino如何实现多线程(SCoop)
友情提示:这里只提供了 Arduino 常用的函数,深入学习请认真阅读参考文档,并不断实战,积累经验,这样你必定会在嵌入式之路越来越顺畅!