一天入门Arduino语言 教程
为什么要写这个文章
为了让有一定编程基础和开发经验的同学能够快速的上手 Arduino 同时Arduino 新手也可以借此巩固下知识
如果你有过类似 51 STM32 NXP 等开发经验,根据本篇文章,可以快速的了解并上手Arduino
,同时对于Arduino新手而言,可以有一个系统的学习。
可结合IDE介绍博客一起学习,更好的掌握Arduino
Arduino IDE使用教程-超详细
文章目录
Arduino语言
Arduino使用C/C++编写程序,虽然C++兼容C语言,但这是两种语言,C语言是一种面向过程的编程语言,C++是一种面向对象的编程语言。早期的Arduino核心库使用C语言编写,后来引进了面向对象的思想,目前最新的Arduino核心库采用C与C++混合编写而成。
通常我们说的Arduino语言,是指Arduino核心库文件提供的各种应用程序编程接口(Application Programming Interface,简称API)的集合。这些API是对更底层的单片机支持库进行二次封装所形成的。例如,使用AVR单片机的Arduino的核心库是对AVR-Libc(基于GCC的AVR支持库)的二次封装。
传统开发方式中,你需要厘清每个寄存器的意义及之间的关系,然后通过配置多个寄存器来达到目的。
而在Arduino中,使用了清楚明了的API替代繁杂的寄存器配置过程,这点在下方的代码中你将深有体会,这也是Arduino能成为简单入门单片机的核心。
C语言基础部分
判断语句:
if
if语句是最常用的选择结构实现方式,当给定表达式为真时,就会运行if内的语句
if(表达式)
{
语句;
}
if…else
若这个表示式为真,语句1部分的代码就会被执行。若这个表示式为假,则执行紧接着else之后的语句2部分代码。
if(表达式)
{
语句1;
}
else
{
语句2;
}
if…else if
若这个表示式1为真,语句1部分的代码就会被执行。若这个表示式1为假,则紧接着判断else if之后的表达式2,如果表达式2为真,则执行语句2 ,否则依次往下循环。
一旦 else if 成功,将不会测试剩余的else if或else语句。
if(表达式1)
{
语句1;
}
else if(表达式2)
{
语句2;
}
else if(表达式3)
{
语句3;
}
else if(表达式4)
{
语句4;
}
……
switch…case
类似于if语句, switch … case 通过允许程序员指定应在各种条件下执行的不同代码来控制程序的流程。 switch 语句将变量的值与 case 语句中指定的值进行比较。当发现一个case语句的值与变量的值匹配时,运行case语句中的代码。如果所有的case都不符合switch的表达式 则执行default语句中的代码。
比起一串冗长的if叙述,使用swith case可使程序代码看起来比较简洁。
switch(表达式)
{
case 常量表达式1:
语句1
break;
case 常量表达式2:
语句2
break;
default : // 以上条件都不符合时,预设执行的动作
语句n
break;
}
-
Switch后的表达式结果只能是整形或字符型
-
switch语句使用 break 关键字退出,通常在每个case语句的结尾使用。如果没有break语句,switch语句将继续执行后续的表达式(“fall-through”),直到到达break语句或达到switch语句的结尾。
循环语句:
while循环
当while之后的条件成立时,执行括号内的程序代码。
while循环将会连续、无限循环,直到括号()内的表达式变为false。或者使用break语句跳出循环,否则while就是死循环。
while(表达式)
{
语句;
}
do…while循环
和while 相似,不同的是while前的那段程序代码会先被执行一次,才会判断特定的条件式为真或为假。如果为真则继续执行,如果为假则跳出循环。因此若有一段程序代码至少需要被执行一次,就可以使用do…while架构。
do
{
语句;
}
while(表达式);
for循环
假如您需要运行代码多次,且每次使用不同的值,那么for循环则非常适用
for (循环变量类型 循环变量名称;循环条件;更新语句)
for(循环变量名称;循环条件;更新语句)
{
语句;
}
每次循环完一次都会执行更新语句 只要还满足循环条件就会一直进行循环
for (i=0; i<5; i++) {
}
就是初始化i=0 当i小于5时运行循环体中的语句,每循环完一次,i自加1,总共循环5次
break语句
当 break 关键字用于 while、for循环时,会终止循环而执行整个循环语句后面的代码。break 关键字通常和 if 语句一起使用,即满足条件时便跳出循环。
while(1){ //循环条件为死循环
sum+=i;
i++;
if(i>100) break;
}
while 循环条件为 1,是一个死循环。当执行到第100次循环的时候,计算完i++;
后 i 的值为 101,此时 if 语句的条件 i> 100 成立,执行break;
语句,结束循环。
一个 break 语句只向外跳一层
continue语句
continue 语句的作用是跳过循环体中剩余的语句而强制进入下一次循环。continue语句只用在 while、for 循环中,常与 if 条件语句一起使用,判断条件是否成立。
i=0;
b=0;
if(i<10)
{
i++;
if(i<5)
b++;
else
continue;
}
上方代码就会在i小于5的时候执行b++ 在i大于5的时候执行continue语句 继续循环 最后i=10,b=5
语法符号
- ; 语句分隔符
- {} 代码块
- // 单行注释
- /* 在这个范围内你可以写一整首诗 */ 多行注释
*/*与/**之间的内容,及 // 之后的内容均为程序注释,使用它可以更好的管理代码。注释不会被编译到程序中,不影响程序的运行。
// 这是一个单行注释
/*
这是一个多行注释
注释内容1
注释内容2
……
*/
运算符:
常见C\C++运算符
Arduuino复合运算符
*+= , -= , = , /=
对一个变量和另一个参数或变量完成一个数学运算。+=(以及其他)可以缩短语法长度。
Syntax语法
x += y; // 等价于 x = x + y;
x -= y; // 等价于 x = x - y;
x *= y; // 等价于 x = x * y;
x /= y; // 等价于 x = x / y;
Parameters参数
x:任何变量类型
y:任何变量类型或常数
Examples范例
x = 2;
x += 4; // x现在为6
x -= 3; // x现在为3
x *= 10; // x现在为30
x /= 2; // x现在为15
Syntax语法
x++; // increment x by one and returns the old value of x
// 将x的值加1并返回原来的x的值。 ++x; // increment x by one and returns the new value of x // 将x的值加1并返回现在的x的值。
x-- ; // decrement x by one and returns the old value of x // 将x的值减1并返回原来的x的值。
–x ; // decrement x by one and returns the new value of x // 将x的值减1并返回现在的x的值。
Parameters参数
x: an integer or long (possibly unsigned)
x:一个整数或长整数(可以无符号)
Returns返回
The original or newly incremented / decremented value of the variable.
返回变量原始值或增加/消耗后的新值。
Examples范例:
x = 2;
y = ++x; // x now contains 3, y contains 3 // x现在为3,y为3
y = x–; // x contains 2 again, y still contains 3 // x现在仍然为2,y将为3
数据类型:
整型:
类型 | 取值范围 | 说明 |
---|---|---|
int | –2,147,483,648 ~ 2,147,483,647 | 整型 |
unsigned int | 0 ~ 4,294,967,295 | 无符号整型 |
long | –2,147,483,648 ~ 2,147,483,647 | 长整型 |
unsigned long | 0 ~ 4,294,967,295 | 无符号长整型 |
short | –32,768 ~ 32,767 | 短整型 |
boolean 布尔类型
布尔类型的值只能为真(true)或是假(false)
boolean会占用1个字节的内存空间。
byte 字节类型
储存的数值范围为0到255。如同字符一样字节型态的变量只需要用一个字节(8位)的内存空间储存。
浮点型
浮点数也就是常说的小数。在Arduino中有float和double两种浮点类型,
float类型占用4个字节(32位)内存空间,
double类型占用8个字节(64位)内存空间。可表达最大值为 1.7976931348623157 x 10308
float最多有8位小数
double最多有16位小数
float 和double 都不能为0
字符型
char
用于存储字符数据 单一字符例如 A 占用一个字节内存空间,存储字符时,字符需要用单引号引用
Arduino使用ASCII 码来存储字符数据 用数字表示一个字符时,它的值有效范围为 -128 到127。
char Str='A';
String
char只能表示一个字符,如果需要多个字符的话,就需要用到String
它是由多个ASCII字符组成 可以用来保存多个字符
如:
String Str = "Helloo,World";
相较于数组形式的定义方法,使用String类型定义字符串会占用更多的存储空间。
数组:
数组是由一组相同数据类型的数据构成的集合。数组概念的引入,使得在处理多个相同类型的数据时,程序更加清晰和简洁。
其定义方式如下:
类型说明符 数组名[常量表达式];
例如:
int a[5];
它表示定义了一个整型数组,数组名为 a,定义的数组称为数组 a
此时数组 a 中有 5 个元素,每个元素都是 int 型变量,而且它们在内存中的地址是连续分配的。也就是说,int 型变量占 4 字节的内存空间,那么 5 个int型变量就占 20 字节的内存空间,而且它们的地址是连续分配的。
数组中的下标是从 0 开始的,例如“int a[5];”表示定义了有 5 个元素的数组 a,这 5 个元素分别为 a[0]、a[1]、a[2]、a[3]、a[4]。
初始化:
在定义时初始化
int a[5] = {1, 2, 3, 4, 5};
int a[5];
a[0]=1; a[1]=2; a[2]=3; a[3]=4; a[4]=5;
要将A[4]的值除以2并将结果赋值给变量x,我们将写:
x = A[ 4 ] / 2;
数据类型转换:
-
char()
-
byte()
-
int()
-
long()
-
float()
也就是类型强制转换 比方说将一个char字符类型强制转化为int整数类型
char str = 'a';
int sch = int(str); //将字符a 转换为整数 按照ASCII码 a的ASCII码数值是97
注意,由高精度想低精度转换,会出现bug 比如把int类型转换为byte类型,就会出现数据缺失的情况 (int最大2,147,483,647 byte最大255)
常量和变量:
常量:在Arduino语言中事先定义了一些具特殊用途的保留字。 其值不能改变
可以用const关键字来定义常量
const 类型 常量名 = 常量值
还可以用宏定义来定义常量
#define 宏名 值
例如:
const int a =0;
#define b = 1;
那么在该程序种,a就只能是0 b就只能是1
变量:变量可以用来储存各种类型数据,并且可以更改数据
其定义方法如下
类型 变量名;
例如,定义一个整型变量i:
int i=95;
Arduino使用的C语言中的变量具有名为scope(范围)的属性。scope是程序的一个区域,有三个地方可以声明变量。它们是:
- 在函数或代码块内部,称为局部变量。
- 在函数参数的定义中,称为形式参数。
- 在所有函数之外,称为全局变量。
局部变量
在函数或代码块中声明的变量是局部变量。局部变量只能在其函数内使用
Void loop () {
int x , y ;
x = 0;
y = 0;
}
y = 2; //这样就是错的
形式参数
作为函数的参数来使用,用来传递其他变量的值
void Led(int a){
a = 0;
}
int b=2;
Led(b); //把b的值传递给形参a
全局变量
全局变量在所有函数之外定义,通常位于程序的顶部。全局变量将在程序的整个生命周期中保持其价值。
全局变量可以被任何函数访问。也就是说,一个全局变量可以在整个程序中声明后使用。
int y = 0; //全局变量
Void loop () {
int x;
x = 0;
y = 1; //这样是对的
}
y = 2; //这样是对的
在Arduino中定义了许多常量,是不可修改的,也是我们常用的
常量PI
Arduino核心库中已定义的常数PI,
#define PI 3.1415926535897932384626433832795
HIGH | LOW
表示数字IO口的电平,HIGH 表示高电平(1),LOW 表示低电平(0)。 HIGH 和LOW 也用来表示你开启或是关闭了一个Arduino的脚位(pin)
INPUT | OUTPUT
表示数字IO口的方向,INPUT 表示输入(高阻态),OUTPUT 表示输出(AVR能提供5V电压 40mA电流)
true | false
true 表示真(1),false表示假(0)。
Arduino 语言部分
此部分我们来探讨Arduino的语言特性,让你来真正的掌握Arduino
Arduino结构
Arduino程序中没有main函数。
main函数的定义隐藏在了Arduino的核心库文件中,所以Arduino开发一般不直接操作main函数,而是使用Setup和loop这个两个函数。
**Arduino软件结构包括两个主要函数:
-
Setup()函数 初始化变量,管脚模式,调用库函数等
-
Loop()函数 连续循环执行loop函数内的程序
void setup()
{
// 在这里加入你的setup代码,它只会运行一次:
}
void loop()
{
// 在这里加入你的loop代码,它会不断重复运行:
}
Void setup ( ) {
}
在程序开始时使用,Arduino控制器通电或复位后,,程序启动时会调用 **setup()**函数。使用它来初始化变量,引脚模式,启用库等。setup函数只能在Arduino板的每次上电或复位后运行一次。
Void loop ( ) {
}
在setup()函数之后,即初始化之后,loop() 让你的程序循环地被执行。使用它来运转Arduino。连续执行函数内的语句,这部份的程式会一直重复的被执行,直到Arduino 板子被关闭。
Arduino I/O函数
数字 I/O
pinMode()函数
pinMode(13,OUTPUT); //定义引脚的模式
数字IO口输入输出模式定义函数,将接口定义为输入或输出接口
pinMode()函数用于将特定引脚配置为输入或输出。可以使用INPUT_PULLUP模式启用内部上拉电阻。此外,INPUT模式显式禁止内部上拉。
- pin - 你希望设置模式的引脚的编号 0~13
- *mode* - INPUT(输入模式),OUTPUT(输出模式)或INPUT_PULLUP(内部上拉输入)。
范例:
pinMode(7,INPUT); // 将脚位 7 设定为输入模式
pinMode(1,INPUT);//将脚位1设定为输入模式
pinMode(2,INPUT);//将脚位2设定为输入模式
pinMode(3,INPUT);//将脚位3设定为输入模式
引脚配置为INPUT
Arduino引脚默认配置为输入 ,输入模式下,由外部器件向Arduino对于引脚输入电平,和数据,Arduino识别电平及数据,进行相应的处理。
引脚配置为OUTPUT
引脚配置为输出模式,Arduino引脚向其他电路提供大量的电流。Arduino引脚可以向其他器件/电路提供(提供正电流)或吸收(提供负电流)高达40mA(毫安)的电流。这是足以点亮LED或者运行许多传感器的电流(不要忘记串联电阻),但不足以运行继电器,螺线管或电机。
上拉电阻
上拉就是将不确定的信号通过一个电阻钳位在高电平,电阻同时起限流作用,增强输出引脚的驱动能力,提高芯片输入信号的噪声容限,增强抗干扰能力。
也就是默认状态下io为高电平 ,下拉电阻与此同理。
digitalWrite()函数
digitalWrite(pin,value); //定义引脚的电平
- pin:你希望设置模式的引脚的编号 0~13
- value :表示为HIGH(高电平)或LOW(低电平)
HIGH为5V(或3.3V在3.3V板上),LOW为0V(接地)
数字IO口输出电平定义函数,将数字接口值至高或低、开或关,即digitalWrite(接口名称, HIGH或LOW)。但脚位必须先透过pinMode明示为输入或输出模式digitalWrite才能生效。比如定义HIGH可以驱动LED。
范例:
digitalWrite(8,HIGH); //将脚位 8设定输出高电位
digitalRead函数
引脚电平读取函数
int digitalRead(pin)
数字IO口读输入电平函数,读出数字接口的值 比如可以读数字传感器。当感测到脚位处于高电位时时回传HIGH,否则回传LOW。
范例:
val = digitalRead(7); // 读出脚位 7 的值并指定给 val
模拟 I/O
analogRead()函数
int analogRead(pin)
- pin 要读取的模拟输入引脚的编号(Arduino Diecimila为0~5,Arduino nano为0~7 Mega上为0至15)
模拟IO口读函数,从指定的模拟接口读取值,Arduino对该模拟值进行10-bit的数字转换。 此函数返回0到1023之间的数字,表示0到5伏特之间的电压。例如,如果施加到编号0的引脚的电压为2.5V,则analogRead(0)返回512。
通过使用**analogRead()**函数,我们可以读取施加到其中一个引脚的电压。比如可以读模拟传感器(10位AD,0~5V表示为0~1023)。
范例:
val = analogRead(2); //读出类比脚位 2 的值并赋值给 val
analogWrite函数
analogWrite(pin, value);
数字IO口PWM输出函数,给一个接口写入模拟值(PWM波)改变PWM脚位的输出电压值可用于电机PWM调速或音乐播放。
-
pin:对于 ATmega168芯片的Arduino(包括Mini或BT),该函数可以工作于 3, 5, 6, 9, 10和 11号接口
-
value表示为0~255
例如:输出电压2.5伏特(V),该值大约是128。
范例 :
analogWrite(9,128); // 输出电压约2.5伏特(V)
扩展 I/O
shiftOut函数
shiftOut(dataPin, clockPin, bitOrder, value)
SPI外部IO扩展函数,通常使用带SPI接口的74HC595做8个IO扩展,把资料传给用来延伸数位输出的暂存器,此函式通常使用在延伸数位的输出。函式使用一个脚位表示资料、一个脚位表示时脉。dataPin为数据口,clockPin为时钟口,bitOrder用来表示位元间移动的方式,为数据传输方向(MSBFIRST高位在前,LSBFIRST低位在前),value会以byte形式输出,表示所要传送的数据(0~255),另外还需要一个IO口做74HC595的使能控制。
范例 :
shiftOut(dataPin, clockPin, LSBFIRST, 255);
pulseIn()函数
unsigned long pulseIn(pin, value)
脉冲长度记录函数,设定读取脚位状态的持续时间,返回时间参数(us),例如使用红外线、加速度感测器测得某一项数值时,在时间单位内不会改变状态。pin表示为0~13,value为HIGH或LOW。比如value为HIGH,那么当pin输入为高电平时,开始计时,当pin输入为低电平时,停止计时,然后返回该时间。
范例:
time = pulsein(7,HIGH); // 设定脚位7的状态在时间单位内保持为HIGH
Arduino 时间函数
Arduino提供四种不同的时间操作函数
delay(ms) 延时函数
delay (ms) ;
delay(ms) 延时函数(单位ms),延时一段时间,暂停晶片执行多少毫秒,
delay(1000)为一秒。
范例:
//LED闪烁实验
void loop() {
digitalWrite(ledPin, HIGH); // 打开LED灯
delay(1000); // 延时1秒钟
digitalWrite(ledPin, LOW); // 关闭LED灯
delay(1000); // 延时1秒钟
}
delayMicroseconds()函数
delayMicroseconds (us) ;
- us 是要暂停的微秒数(无符号整型)。
延时函数(单位us)暂停晶片执行多少微秒
delayMicroseconds()函数接受单个整数(或数字)参数。此数字表示时间,以微秒为单位。一毫秒内有一千微秒,一秒内有一百万微秒
目前,可以产生精确延迟的最大值是16383
范例:
delayMicroseconds(1000); //暂停1豪秒
millis()函数
unsigned long millis()
返回时间函数(单位ms), 回传晶片开始执行到目前的毫秒,此函数用于返回Arduino板开始运行当前程序时的毫秒数,该参数溢出大概需要50天时间。
范例:
void loop() {
Serial.print("Time:"); //延时1S计算运行时间
time = millis();
delay(1000);
}
micros()函数
micros () ;
micros()函数返回Arduino板开始运行当前程序时的微秒数。该数字在大约70分钟后溢出,即回到零。在16 MHz Arduino板(例如Duemilanove和Nano)上,此函数的分辨率为4微秒(即返回值总是4的倍数)。在8 MHz Arduino板(例如LilyPad)上,此函数的分辨率为8微秒。
范例:
void loop() {
Serial.print("Time:"); //延时1S计算运行时间
time = micros();
delay(1000);
}
Arduino数学函数
Arduino数学库(math.h)包含了许多用于操作浮点数的有用的数学函数。
min(x, y)
求最小值 ,回传两数之间较小者
范例:
val = min(10,20); // val=10
max(x, y)
求最大值 ,回传两数之间较大者
范例:
val = max(10,20); // val=20
abs(x)
计算绝对值 ,回传该数的绝对值,
范例:
val = abs(-5); // val=5
constrain(x, a, b)
约束函数,下限a,上限b,判断x变数位于a与b之间的状态。
x若小于a回传a;
介于a与b之间回传x本身;
大于b回传b
范例:
val = constrain(i, 0, 255); // 将i的值赋值给val 并且i的取值为0~255
map(value, fromLow, fromHigh, toLow, toHigh)
约束函数,value必须在fromLow与toLow之间和fromHigh与toHigh之间。将value变数依照fromLow与fromHigh范围,对等转换至toLow与toHigh范围。时常使用于读取类比讯号,转换至程式所需要的范围值。
范例:
val = map(analogRead(0),0,1023,100, 200); // 将analog0 所读取到的讯号0~1023对等转换至100,200之间的数值。
pow(base, exponent)
开方函数,base的exponent次方。回传一个数(base)的指数(exponent)值。
范例:
double x = pow(y, 32); // 设定x为y的32次方
sq(x) 平方
平方函数,返回x的平方值
范例:
val=sq(2); //val等于2的平方
sqrt(x) 开根号
回传double型态的取平方根值。
范例:
double val = sqrt(1138); // 回传1138平方根的近似值 33.73425674438
double log (double __x)
log()函数返回参数x的自然对数。
范例:
double val = log(2);
double round (double __x)
round()函数将x四舍五入到最近的整数,但中间情况不舍入到0(不是到最近的偶数整数)。不可能会溢出。
范例:
double val = round(5.6); //val=6
Arduino三角函数
Arduino提供了传统的三角函数(sin,cos,tan,asin,acos,atan)
double sin(double x); //返回x弧度的正弦
double cos(double y); //返回y弧度的余弦
double tan(double x); //返回x弧度的正切
double acos(double x); //返回A,对应于cos(A)=x的角度
double asin(double x); //返回A,与sin(A)=x相对应的角度
double atan(double x); //返回A,与tan(A)=x相对应的角度
范例:
double sine = sin(2); // 近似值 0.90929737091
double cosine = cos(2); //近似值-0.41614685058
double tangent = tan(2); //近似值-2.18503975868
Arduino 随机数函数
randomSeed()函数
randomSeed(seed)
随机数端口定义函数,seed表示读模拟口analogRead(pin)函数
randomSeed(seed)函数重置Arduino的伪随机数生成器
虽然random()返回的数字的分布本质上是随机的,但是顺序是可预测的。所以如果需要一个真正的乱数,可以呼叫此函式重新设定产生乱数种子。你可以使用乱数当作乱数的种子,以确保数字以随机的方式出现,通常会使用类比输入当作乱数种子,藉此可以产生与环境有关的乱数(例如:无线电波、宇宙雷射线、电话和萤光灯发出的电磁波等)。
范例:
randomSeed(analogRead(5)); //使用来自模拟管脚5的噪声随机化
random()函数
long random(min, max)
随机数函数,返回数据大于等于min,小于max。
long random(max)
返回数据大于等于0,小于max。
范例:
long randnum = random(11); // 回传 0 -10之间的数字
long randnum = random(0, 100); // 回传0 – 99 之间的数字
Arduino外部中断函数
中断:**
中断(interrupt)停止Arduino的当前工作,以便可以完成一些其他工作。
什么是中断:
CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理(中断发生);
CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务);
待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A(中断返回),这一过程称为中断。
通俗点说:你正在家里做家务,突然有人来找你,打断了你的进程,在你们交谈完之后,你就又回去继续进行你的家务活,这其中被打断的过程,就叫做中断,而在中断结束之后,你则会继续进行本来应该做的事情
- 中断是一种使CPU中止正在执行的程序而转去处理特殊事件的操作,这些引起中断的事件称为中断源,它们可能是来自外设的输入输出请求,也可能是计算机的一些异常事故或其它内部原因。
- 中断可以来自各种来源。在这种情况下,我们使用的是由数字引脚上的状态改变触发的硬件中断
- 大多数Arduino设计有两个硬件中断(称为“interrupt0”和“interrupt1”)分别硬连接到数字I/O引脚2和3。
- Arduino Mega有六个硬件中断,包括引脚21,20,19和18上的附加中断(“interrupt2”到“interrupt5”)。
- 你可以定义该程序并指定上升沿,下降沿或两者的条件。在这些特定条件下,将处理中断。
中断类型:
- 硬件中断 - 它们响应外部事件而发生,例如外部中断引脚变为高电平或低电平。
- 软件中断 - 它们响应于在软件中发送的指令而发生。“Arduino语言”支持的唯一类型的中断是attachInterrupt()函数。
具体请参考:
attachInterrupt()函数
attachInterrupt(interrupt,function,mode)
interrupt:中断源(在Arduino中,中断源可选值为0或1,一般分别对应2号和3号引脚)
function:需要中断的函数名
mode:
-
LOW(低电平触发)、
-
CHANGE(在引脚电平变化时触发)、
-
RISING(低电平变为高电平触发)、
-
FALLING(高电平变为低电平触发)
外部中断只能用到数字IO口2和3,interrupt表示中断口初始0或1,表示一个功能函数,mode:LOW低电平中断,CHANGE有变化就中断,RISING上升沿中断,FALLING 下降沿中断。
detachInterrupt()函数
detachInterrupt(interrupt)
中断开关函数,interrupt=1 开,interrupt=0 关。
范例:
detachInterrupt(1)//打开中断
中断使能函数
interrupts()// 使能中断
noInterrupts() //禁止中断
Arduino串口收发函数
Arduino Uno R3开发板上,硬件串口位于Rx(0)和Tx(1)引脚上,Arduino的USB口通过转换芯片与这两个引脚连接。该转换芯片会通过USB接口在PC机上虚拟出一个用于Arduino通讯的串口,我们下载程序也是通过串口进行的。
Serial.begin(speed)
-
串口定义波特率函数,设置串行每秒传输数据的速率(波特率),可以指定Arduino从电脑交换讯息的速率,通常置于setup()函数中。
-
原型:
-
Serial.begin(speed)
-
- Serial.begin(speed, config)
参数:
-
speed:波特率,一般取值9600,115200等。在同计算机通讯时,使用下面这些值:300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600或 115200 bps(每秒位元组)
-
config:设置数据位、校验位和停止位。默认SERIAL_8N1表示8个数据位,无校验位,1个停止位。
-
返回值:无。
范例:
Serial.begin(9600)
Serial.end()
- 描述:禁止串口传输。此时串口Rx和Tx可以作为数字IO引脚使用。
- 原型:Serial.end()
- 参数:无。
- 返回值:无。
Serial.print()
- 描述:串口输出数据,写入字符数据到串口。
- 原型:
- Serial.print(val)
- Serial.print(val, format)
- 参数:
- val:打印的值,任意数据类型。
- config:输出的数据格式。BIN(二进制)、OCT(八进制)、DEC(十进制)、HEX(十六进制)。对于浮点数,此参数指定要使用的小数位数。
- 示例:
- Serial.print(75); // 列印出 “75”
- Serial.print(75, DEC); //列印出 “75”
- Serial.print(75, HEX); // “4B” (75 的十六进位)
- Serial.print(75, OCT); // “113” (75 in的八进位)
- Serial.print(75, BIN); // “1001011” (75的二进位)
- Serial.print(75, BYTE); // “K” (以byte进行传送,显示以ASCII编码方式)
- Serial.print(1.23456, 0) 得到 “1”
- Serial.print(1.23456, 2) 得到 “1.23”
- Serial.print(1.23456, 4) 得到 “1.2346”
- Serial.print(‘N’) 得到 “N”
- Serial.print(“Hello world.”) 得到 “Hello world.”
- 返回值:返回写入的字节数。
Serial.println()
- 描述:串口输出数据并换行。
- 原型:
- Serial.println(val)
- Serial.println(val, format)
- 参数:
- val:打印的值,任意数据类型。
- config:输出的数据格式。
- 返回值:返回写入的字节数。
Serial.available()
- 描述:判断串口缓冲区的状态,返回从串口缓冲区读取的字节数。
- 原型:Serial.available()
- 参数:无。
- 返回值:可读取的字节数, 如果回传值是0代表所有序列埠上资料都已经被read()函式读取。
范例:
int count = Serial.available();
Serial.read()
- 描述:读取串口数据,一次读一个字符,读完后删除已读数据。
- 原型:Serial.read()
- 参数:无。
- 返回值:返回串口缓存中第一个可读字节,当没有可读数据时返回-1,整数类型。
范例:
int data = Serial.read();
Serial.readBytes()
- 描述:从串口读取指定长度的字符到缓存数组。
- 原型:Serial.readBytes(buffer, length)
- 参数:
- buffer:缓存变量。
- length:设定的读取长度。
- 返回值:返回存入缓存的字符数。
Serial.flush()
- 描述:清空缓冲器。 有时候因为资料速度太快,超过程式处理资料的速度,你可以使用此函式清除缓冲区内的资料。经过此函式可以确保缓冲区(buffer)内的资料都是最新的。
- 原型: Serial.flush();
- 参数: 无
- 返回值: 无
范例:
Serial.flush();
Arduino语言库文件
官方库文件
· EEPROM - EEPROM读写程序库
· Ethernet - 以太网控制器程序库
· LiquidCrystal - LCD控制程序库
· Servo - 舵机控制程序库
· SoftwareSerial - 任何数字IO口模拟串口程序库
· Stepper - 步进电机控制程序库
· Wire - TWI/I2C总线程序库
· Matrix - LED矩阵控制程序库
· Sprite - LED矩阵图象处理控制程序库
Arduino 内部集成电路I2C
内部集成电路(I2C)是用于微控制器和新一代专用集成电路之间的串行数据交换系统。当它们之间的距离很短(接收器和发射器通常在同一个印刷电路板上)时使用。通过两根导线建立连接。一个用于数据传输,另一个用于同步(时钟信号)。
Arduino板的I2C引脚
I2C总线由两个信号组成 - SCL和SDA。SCL是时钟信号,SDA是数据信号。当前总线主机总是产生时钟信号。一些从设备可能迫使时钟低电平以延迟主设备发送更多数据(或者在主设备尝试将数据写出之前请求更多的时间来准备数据)。这被称为“时钟伸展”。
以下是不同Arduino板的引脚:
- Uno, Pro Mini A4 (SDA), A5 (SCL)
- Mega, Due 20 (SDA), 21 (SCL)
- Leonardo, Yun 2 (SDA), 3 (SCL)
Arduino I2C
我们有两种模式 - 主代码和从代码 - 使用I2C连接两个Arduino板。它们是:
- Master Transmitter / Slave Receiver 主发射器/从接收器
- Master Receiver / Slave Transmitter 主接收器/从发射器
主发射器/从接收器
让我们现在看看什么是主发送器和从接收器。
主发射器
以下函数用于初始化Wire库,并将I2C总线作为主器件或从器件加入。这通常只被调用一次。
- Wire.begin(地址) - 在我们的例子中,地址是7位从地址,因为未指定主机,它将作为主机加入总线。
- Wire.beginTransmission(地址) - 开始向给定地址的I2C从设备发送数据。
- Wire.write(值) - 用于从主设备传输到从设备的队列字节(在beginTransmission()和endTransmission()之间的调用)。
- Wire.endTransmission() - 结束由beginTransmission()开始的对从设备的传输,并传输由wire.write()排队的字节。
从接收器
使用以下函数:
- Wire.begin(地址) - 地址是7位从地址。
- Wire.onReceive(收到的数据处理程序) - 当从设备从主设备接收数据时调用的函数。
- Wire.available() - 返回Wire.read()可用于检索的字节数,应在Wire.onReceive()处理程序中调用。