preface
社区教程:https://www.arduino.cn/thread-1066-1-1.html
官方文档:https://www.arduino.cc/reference/en/
函数参考:https://wiki.arduino.cn/
Arduino的语言 = C/CPP的封装 + API
一、项目结构
setup()
Arduino控制器通电或复位后,即会开始执行setup() 函数中的程序,该部分只会执行一次。
通常我们会在setup() 函数中完成Arduino的初始化设置,如配置I/O口状态,初始化串口等操作。
// 给13号引脚连接的设备设置一个别名“led”
int led = 13;
// 在板子启动或者复位重启后, setup部分的程序只会运行一次
void setup(){
// 将“led”引脚设置为输出状态
pinMode(led, OUTPUT);
}
// setup部分程序运行完后,loop部分的程序会不断重复运行
void loop()
{
digitalWrite(led, HIGH); // 点亮LED
delay(1000); // 等待一秒钟
digitalWrite(led, LOW); // 通过将引脚电平拉低,关闭LED
delay(1000); // 等待一秒钟
}
loop()
在setup() 函数中的程序执行完后,Arduino会接着执行loop() 函数中的程序。而loop()函数是一个死循环,其中的程序会不断的重复运行。
通常我们会在loop() 函数中完成程序的主要功能,如驱动各种模块,采集数据等。
main()
在进行Arduino开发时,没有像传统C/C++程序使用入口函数main。实际上main函数存在于Arduino核心库中,且仍然是程序的入口。
在Arduino核心库中可见main.cpp文件,其内容如下:
#include <Arduino.h>
// Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (* /*func*/ )()) { return 0; }
// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }
void setupUSB() __attribute__((weak));
void setupUSB() { }
int main(void)
{
init();
initVariant();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
//进行串口事件判断
if (serialEventRun) serialEventRun();
}
return 0;
}
二、数字输入输出
pinMode(pin, mode)
在使用输入或输出功能前,你需要先通过pinMode() 函数配置引脚的模式为输入模式或输出模式。
- 参数
pin
为指定配置的引脚编号 - 参数
mode
为指定的配置模式 - 通常可用模式有三种:
- INPUT 输入模式
- OUTPUT 输出模式
- INPUT_PULLUP 输入上拉模式
digitalWrite(pin, value)
引脚配置成输出模式后,可使用digitalWrite() 让其输出高电平或者是低电平。
Arduino中输出的低电平为0V,输出的高电平为当前Arduino的工作电压。
digitalRead(pin)
返回得到的信号状态。
三、模拟输入输出
analogRead(pin)
模拟输入引脚是带有ADC(Analog-to-Digital Converter,模数转换器)功能的引脚。
它可以将外部输入的模拟信号转换为芯片运算时可以识别的数字信号,从而实现读入模拟值的功能。
Arduino Uno模拟输入功能有10位精度,即可以将0~5V的电压信号转换为0~1023的整数形式表示。
//光敏电阻检测环境光
void setup()
{
// 初始化串口
Serial.begin(9600);
}
void loop()
{
// 读出当前光线强度,并输出到串口显示
int sensorValue = analogRead(A0);
Serial.println(sensorValue);
delay(1000);
}
analogWrite(pin,value)
使用analogWrite() 函数实现PWM(脉冲宽度调制,一种模拟控制的方法)输出功能。
在Arduino Uno中,提供PWM功能的引脚为3、5、6、9、10、11。
在analogWrite() 和analogRead() 函数内部,已经完成了引脚的初始化,因此不用在Setup() 函数中进行初始化操作。
/*
Fading
通过analogWrite() 函数实现呼吸灯效果
*/
int ledPin = 9; // LED连接在9号引脚上
void setup() {
// Setup部分不进行任何处理
}
void loop() {
// 从暗到亮,以每次加5的形式逐渐亮起来
for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
// 输出PWM
analogWrite(ledPin, fadeValue);
// 等待30ms,以便观察到渐变效果
delay(30);
}
// 从亮到暗,以每次减5的形式逐渐暗下来
for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) {
// 输出PWM
analogWrite(ledPin, fadeValue);
// 等待30ms,以便观察到渐变效果
delay(30);
}
}
四、高级输入输出
tone()
tone() 主要用于Arduino连接蜂鸣器或扬声器发声。
noTone(pin)
停止指定引脚上的方波输出。
实例程序:
/*
Melody
Plays a melody
This example code is in the public domain.
http://arduino.cc/en/Tutorial/Tone
*/
#include "pitches.h"
// 记录曲子的音符
int melody[] = {
NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
// 音符持续时间 4为四分音符, 8为八分音符
int noteDurations[] = {
4, 8, 8, 4,4,4,4,4 };
void setup() {
// 遍历整个曲子的音符
for (int thisNote = 0; thisNote < 8; thisNote++) {
// noteDurations[]数组中存储的是音符的类型
// 我们需要将其换算为音符持续时间,方法如下:
// 音符持续时间=1000ms / 音符类型
// 例如,四分音符=1000 / 4,8分音符 = 1000/8
int noteDuration = 1000/noteDurations[thisNote];
tone(8, melody[thisNote],noteDuration);
// 为了能辨别出不同的音调,你需要在两个音调间设置一定的延时
// 增加30%延时时间是比较合适的
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// 停止发声
noTone(8);
}
}
void loop() {
// 程序并不重复,因此这里为空
}
pulseln(pin,value)
检测指定引脚上的脉冲信号宽度。单位微秒
外部中断
attachInterrupt(pin, ISR, mode)
- 对中断引脚进行初始化配置,以开启外部中断功能
- 参数说明:
- pin:中断引脚
- ISR:中断函数名
- mode:中断模式,有
CHANGE
LOW
HIAH
detachInterrupt(pin)
- 关闭中断功能
中断函数(响应中断的处理函数),不能带任何参数,返回类型为空
五、时间控制
函数 | 说明 |
---|---|
millis() |
获取Arduino通电后(或复位后)到现在的时间,单位:ms |
delay() |
参数为时长,类型unsigned long,单位毫秒:ms |
六、串口通信
Serial.begin(speed)
使用串口与计算机通信时,需要先初始化Arduino的串口通信功能。
参数speed指串口通信波特率,常用波特率:300、600、1200、2400、4800、9600、14400、19200、28800、38400、57600、115200
available()
返回串口接收缓冲区中的字节数(可读取的字节数)。接受缓冲区最多可保存64 bytes的数据。
print()
串口初始化完成后,我们便可以使用 Serial.print(val)
或Serial.println(val)
向计算机发送信息了。println(val)
会在输出完指定数据后,再输出一组回车换行符。
其它函数 | 说明 |
---|---|
Serial.find(target) |
返回值布尔型 |
Serial.findUntil(target, terminal) |
从串口缓冲区读取数据,直到读取到指定的字符串或指定的停止符。 |
Serial.flush() |
等待正在发送的数据发送完成 |
Serial.peek() |
返回1字节的数据,但不会从接受缓冲区删除该数据。 |
int counter=0; // 计数器
void setup() {
// 初始化串口
Serial.begin(9600);
}
void loop() {
// 每loop循环一次,计数器变量加1
counter = counter+1;
// 输出变量
Serial.print(counter);
// 输出字符
Serial.print(‘:’);
// 输出字符串;
Serial.println("Hellow World");
delay(1000);
}
read()
调用该语句,每次都会返回一个字节的数据,这个返回值便是当前串口读取到的数据。