Arduino

来源: Arduino程序设计基础 (第2版)

1. 初识Arduino

1.1 什么是Arduino

Arduino既是一块小小的电路板,还是一个开放的电子开发平台
Arduino既包含了硬件——电路板,也包含了软件——开发环境和分享的代码、程序

1.2 Arduino的由来

开源项目 对Arduino贡献
GCC/G++ Arduino编译器
AVR-Libc Arduino语言
Wiring Arduino语言
JAVA Processing开发环境
Processing Arduino集成开发环境
AVR-DUDE 程序下载到控制器

1.4 Arduino控制器

  • Arduino 101 / Genuino 101
  • Arduino UNO
  • Arduino MEGA
  • Arduino Leonardo
  • Arduino Due
  • Arduino Zero
  • 小型化Arduino
    • Arduino Nano
    • Arduino Mini
    • Arduino Micro
    • Arduino Lilypad
  • Arduino兼容控制器
    • Zduino UNO
    • Zduino Leonardo
    • Zduino MEGA
  • 衍生控制器
  • Intel Galileo
  • Maple
  • ChipKit
  • Google ADK 2012

1.4.3 Arduino UNO R3

电源 Power
USB接口 5V
DC电源输入接口 7~12V
电源接口处5V端口 5V
电源接口处VIN端口 7~12V
指示灯 LED 点亮
ON 电源指示灯 Arduino通电时
TX 串口发送指示灯 USB连接计算机且Arduino向计算机传输数据时
RX 串口接收指示灯 USB连接计算机且Arduino接收计算机的数据时
L 可编程控制指示灯 13号引脚为高电平或高阻态时
复位按键 Reset Button
存储空间 Memory 详情
Flash 32KB 0.5KB = BOOT区,用于储存引导程序;31.5KB = 用户储存程序的空间
SRAM 2KB CPU运算时在其中开辟一定储存空间,Arduino断电或复位后其中数据丢失
EEPROM 1KB (电可擦写的可编程只读存储器) Arduino断电或复位后其中数据不会丢失
输入/输出端口 Input/Output Port 作用
UART通信 0(RX),1(TX) 接收和发送串口数据
外部中断 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 AREF接口 模拟输入参考电压的输入端口
Reset 复位端口 按下复位键,端口接低电平,使Arduino复位

1.5 Arduino软件 (Arduino IDE 下载)

2. 基础篇

2.1 Arduino语言及程序设计结构

2.1.1 Arduino语言

Arduino使用C/C++语言编写程序 (早期Arduino核心库使用C语言编写,最新核心库采用C与C++混合编程)
Arduino语言: 通常指Arduino核心库文件提供的各种应用程序编程接口(Application Programming Interface)集合

2.1.2 Arduino程序结构

Arduino程序表面上看没有main()函数,实际其定义隐藏在Arduino的核心库文件中
Arduino开发时一般不直接操作main()函数,而是使用setup()和loop()这两个函数

1
2
3
4
5
6
7
8
9
10
11
12
void setup()
{
// 在这里填写setup()函数代码,此程序只会运行一次
// Arduino控制器通电或复位后,即会开始执行setup()函数中程序
}

void loop()
{
// 在这里填写loop()函数代码,此程序会不断重复运行
// setup()函数中程序执行完毕后Arduino会接着执行loop()函数中程序,进入程序死循环
}

2.2 C/C++语言基础

2.2.1 数据类型

【常量】

  • 含义: 程序运行过程中,其值不能改变的量
  • 命名: 可以是字符,也可以是数字
  • 定义: #define 常量名 常量值; e.g., #define PI 3.1415926535897932384626433832795;

【变量】

  • 含义: 程序中可变的值
  • 定义: 类型 变量名; e.g., int i;int i=95;
整数类型 取值范围 说明
int -32768 ~ 32767 整型
unsigned int 0 ~ 65535 无符号整型
long -2147483648 ~ 2147483647 长整型
unsigned long 0 ~ 4294967295 无符号长整型
short -32768 ~ 32767 短整型
  • Arduino Due 中,int 型及 unsigned int 型占用4字节(32位)
浮点类型 精度
float 4字节(32位)
double 4字节(32位)
  • Arduino Due 中,double 类型占用8字节(64位)
字符类型 精度 说明
char 1字节(8位) 存储字符变量
  • char col = 'C'; 字符以数字形式存储在 char 类型变量中,数字与字符对应关系参照ASCII码
布尔类型 精度 说明
boolean 1字节(8位) false(假) or true(真)

2.2.2 运算符

运算符类型 运算符 说明
算术运算符 = 赋值
算术运算符 +
算术运算符 -
算术运算符 *
算术运算符 /
算术运算符 % 取模
比较运算符 == 等于
比较运算符 != 不等于
比较运算符 < 小于
比较运算符 > 大于
比较运算符 <= 小于或等于
比较运算符 >= 大于或等于
逻辑运算符 && “与”
逻辑运算符 “或”
逻辑运算符 ! “非”
复合运算符 ++ 自加
复合运算符 自减
复合运算符 += 复合加
复合运算符 -= 复合减

2.2.3 表达式

含义: 通过运算符将运算对象连接起来的式子 e.g., 5+3 a-b 1<9

2.2.4 数组

含义: 由一组具有相同数据类型的数据构成的集合
定义: 数据类型 数据名称[数据元素个数]; e.g., int a[5];
使用: 数组名称[下标] 访问数组中的元素

  • 令数组中某一元素赋值: int a[5]; a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4; a[4] = 5;
  • 令数组中在定义时赋值: int a[5] = {1,2,3,4,5};

2.2.5 字符串

定义:

  • 以字符型数组方式定义: char 字符串名称[字符个数];
  • 使用String类型定义: String 字符串名称;
    • 单独给赋值: String abc; abc = 'Arduino;’
    • 定义时赋值: String abc = 'Arduino';

2.2.6 注释

1
2
3
4
5
6
7
// 单行注释内容

/*
多行注释内容1
多行注释内容2
……
*/

2.2.8 顺序结构

三种基本结构之一,也是最基本、最简单的程序组织结构,顺序结构中程序按语句的先后顺序依次执行
一个程序或函数,在整体上是一个顺序结构,由一些列语句或控制结构组成,且都按先后顺序运行

2.2.9 选择结构/选取结构/分支结构

if…else 语句

  • 简单分支结构
1
2
3
4
if (表达式)
{
语句
}
  • 双分支结构
1
2
3
4
5
6
7
8
if (表达式)
{
语句 1
}
else
{
语句 2
}
  • 多分支结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if (表达式 1)
{
语句 1
}
else if (表达式 2)
{
语句 2
}
else if (表达式 3)
{
语句 3
}
……
else
{
语句 n
}

switch…case 语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
switch (表达式)  //switch后的表达式的结果只能是整形或字符型
{
case 常量表达式 1:
语句 1
break;
case 常量表达式 2:
语句 2
break;
case 常量表达式 3:
语句 3
break;
……
default :
语句 n
break;
}

2.2.10 循环结构/重复结构

循环语句

  • while 循环: 一种“当”循环,即满足条件才会执行循环体内的语句
1
2
3
4
while (表达式)  //表达式永远为真或1时,成为死循环
{
语句
}
  • do…while 循环: 一种“直到”循环,即一直执行循环体的语句直到条件不成立为止
1
2
3
4
5
do
{
语句
}
while (表达式);
  • for 循环: 一般,表达式1为循环初始化语句,表达式2为判断语句,表达式3为增量语句
    1
    2
    3
    4
    for (表达式1; 表达式2; 表达式3)  //如: for(i=0; i<5; i++)
    {
    语句
    }

循环控制语句

  • break: 只能用于switch多分支选择结构和循环结构中,中止当前的选择结构或循环结构,转到后续语句运行
1
2
3
4
if (表达式)
{
break;
}
  • continue: 跳过本次循环中的剩余语句,进入判断下一轮循环是否执行
1
2
3
4
if (表达式)
{
continue;
}

2.5 Arduino I/O 口的简单控制

2.5.1 数字 I/O 口的使用

数字信号: 以0、1二进制形式表示的不连续信号
数字信号表示: Arduino中的数字信号,高电平为HIGH1,地电平为LOW0
数字信号引脚: Arduino控制器上,每一个带数字编号的引脚都是数字引脚,包括写有’A’编号的模拟输入引脚
数字信号引脚配置: pinMode(pin, mode); (pin: 引脚编号;mode: 配置模式)

模式名称 模式说明 说明/补充
INPUT 输入模式 可读取引脚数字信号: digitalRead(pin, value)
OUTPUT 输出模式 可写入引脚数字信号:digitalWrite(pin, value)
INPUT_PULLUP 输入上拉模式 空悬时默认电平为HIGH1,联通后再重新判断

下拉/上拉: 将某节点通过电阻接GND/VCC的做法叫做下拉/上拉,这个电阻叫做下拉电阻/上拉电阻
数字引脚别名配置: #define 引脚别名 引脚编号(const) int led = 13; (led: 引脚别名;13: 引脚编号)

2.5.3 模拟 I/O 口的使用

模拟信号: 用连续变化的物理量表示信息,信号随时间作连续变化的信号
模拟信号表示: Arduino中的模拟信号,常用0-5V的电压来表示

模拟信号输入:

  • 模拟输入引脚: Arduino控制器上,编号前带有’A’的引脚都是模拟输入引脚
  • 模拟输入函数: analogRead(pin) e.g., analogRead(A0)(pin: 要读取模拟值的模拟输入引脚)
  • 模拟输入精度: 使用AVR芯片作主控的Arduino的模拟输入功能有10位精度 (将0-5V电压转换成0-1023的整数形式)
  • 模拟输入原理: ADC(Analog-to-Digital Converter)功能,将外部输入的模拟信号转换为数字信号,以读入模拟值

模拟信号输出:

  • 模拟输出引脚: Arduino控制器上,带’~’的PWM引脚
  • 模拟输出函数: anaogWrite(pin, value) (pin: PWM引脚;value: PWM脉冲宽度,0-255)
  • 模拟输出精度: 可输出的PWM脉冲宽度为0-255
  • 模拟输出原理: PWM(Pulse Width Modulation)方式,通过高/低电平的不断转换来输出周期固定(约490Hz)的方波,通过改变高地电平在每个周期中所占的比例(占空比),而得到近似输出不同电压的效果
    (此方法仅能得到近似模拟值输出效果,另外可加外围滤波器以输出真正的模拟值)

2.6 与计算机交流——串口的使用

Arduino与计算机通信最常用的方式是串口通信,Arduino控制器的串口都位于0(RX)和1(TX)两个引脚上
Arduino的USB口都是通过转换芯片(通常是ATmega16u2)与Arduino的两个串口引脚连接
Arduino控制器的这个转换芯片通过USB接口在计算机上虚拟一个用于与Arduino通信的串口
Arduino与计算机建立串口连接后,要使串口与计算机通信,须先初始化Arduino的串口通信功能
Arduino串口通信初始化: Serial.begin(speed) (speed: 串口通信波特率,即设定串口通信速率)
波特率: 衡量通信速度的参数,表示每秒传送的bit的个数 (如 9600 波特 表示每秒发送 9600 bit 的数据)
缓冲区: 指使用串口时,Arduino在SRAM中开辟的一段64B大小的空间

2.6.1 串口传输

使用串口输出数据: Serial.print(val); Serial.println(val); (val: 要输出的各种类型数据,ln表示输出后换行)

2.6.2 串口输入

串口接收到的数据都会被暂存在串口缓冲区,调用Serial.read()函数时,Arduino就会从中取出1B的数据
串口缓冲区中没有可读数据时,Serial.read()函数会返回int型值-1,其对应的char型数据为乱码
故通常使用串口读取数据前,先使用Serial.available()函数检测缓冲区中是否有可读数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 示例用法 */

void setup()
{
Serial.begin(9600); // 初始化串口
}

void loop()
{
if (Serial.available()>0) //检测缓冲区是否有数据: 有则读取,无则等待或跳过
{
char ch = Serial.read(); //读取缓冲区数据
Serial.print(ch); //输出读取的数据
}
}

2.7 时间控制函数

2.7.1 运行时间函数

millis(); 获取Arduino从通电(或复位)后到现在系统运行的时间,单位为毫秒,返回值类型为 unsigned long
micros(); 获取Arduino从通电(或复位)后到现在系统运行的时间,单位为微秒,返回值类型为 unsigned long

使用16MHz晶振的Arduino上,精度为4微秒
使用 8MHz晶振的Arduino上,精度为8微秒

2.7.2 延时函数

使用延时函数可暂停程序,并可通过参数来设定延时时间
delay(); 毫秒级延时,参数数据类型为 unsigned long
delayMicroseconds(); 微秒级延时,参数数据类型为 unsigned int

3. I/O口高级应用

4. 使用和编写类库

5. 通信篇

6. 存储篇

7. 无线通信篇——红外遥控

8. LCD显示篇

9. USB类库的使用

10. Ethernet类库的使用

附录