admin 管理员组文章数量: 887021
2024年2月19日发(作者:django跨域解决方案)
Arduino程序的总体结构
Arduino程序基本结构由setup() 和loop() 两个函数组成:
Arduino控制器通电或复位后,即会开始执行setup() 函数中的程序,该部分只会执行一次。
通常我们会在setup() 函数中完成Arduino的初始化设置,如配置I/O口状态,初始化串口等操作。
在setup() 函数中的程序执行完后,Arduino会接着执行loop() 函数中的程序。而loop()函数是一个死循环,其中的程序会不断的重复运行。通常我们会在loop() 函数中完成程序的主要功能。
void setup()
{
// 在这里加入你的setup代码,它只会运行一次:
}
void loop()
{
// 在这里加入你的loop代码,它会不断重复运行:
}
loop()函数的功能相当于MSC-51语言里main()函数中的while(1){}死循环。Arduino语言中不需要编写main()函数,它已经通过上述两个函数封装了,对程序员是不可见的。
数据类型
整数与字符类型
int类型
整数是数值存储的主要类型。int类型的长度在8位Arduino板中为16位(2字节),表示范围为-32,768至32,767(-215到215-1)。在16位Arduino板(如Due)中,int类型的长度为32位(4字节)。
int counter = 32 ;
short类型
short类型同int类型一样,长度为16位(2字节)。short类型在所有Arduino板(8位及16位)中的长度都是16位(2字节)。
short counter = 32 ;
unsigned int类型
无符号整数,长度与int相同,在8位Arduino板中为16位(2字节),在16位Arduino板(如Due、Zero)中,int类型的长度为32位(4字节)。由于为无符号数,故16位的unsigned int类型表示范围为0到65,535(216-1)。
unsigned int counter = 60 ;
long类型
长整型,长度为32位(4字节),从-2,147,483,648到2,147,483,647,约±20亿的范围。
long velocity = 102346 ;
unsigned long类型
无符号长整型,长度与long类型相同,32位(4字节),由于是无符号数,表示范围为0到4,294,967,295 (232 – 1),约42亿。
unsigned Long velocity = 101006 ;
这产生-32,768至32,767的范围(最小值为-2 ^ 15,最大值为(2 ^ 15)-1)。
char类型
字符类型,长度为1个字节,本质为8位整型,表示范围为-128到127,可被赋值为字符或上述范围内的整数。
Char chr_a = ‘a’ ;
Char chr_c = 97 ;
unsigned char类型
无符号字符类型,长度为1个字节,相当于8位无符号数,表示范围为0到255,可被赋值为字符或上述范围内的整数。
虽然Arduino所采用的单片机芯片RAM容量高于MCS-51单片机,但相比
PC仍然是非常有限的,因此,依然要遵照单片机程序设计中对变量的使用“能省则省”的原则,根据变量可能的取值范围合理选择变量类型。
浮点类型
float类型
浮点数是指具有小数点的数字,浮点数通常用于近似模拟值和连续值,因为它们的分辨率高于整数。Arduino中的浮点数长度为32位(4字节),表示范围为3.4028235E + 38到3.4028235E - 38。
float num = 1.352;
double类型
在16位Arduino板上,double与float类型的长度相同,因此表示范围和精度也完全相同。在32位Arduino板(如Due)上,双精度长度为64位(8字节),精度更高。
double num = 45.352 ;
布尔类型
Boolean类型
C语言中是没有布尔类型的,C语言使用0或NULL代表“逻辑假”(false),使用非零值代表“逻辑真”(true)。Arduino里设置了布尔类型,每个布尔变量占用1字节的内存,取值为true或false。布尔类型使得逻辑表达式或代码更易读。
boolean val = false ;
boolean state = true ;
字节与字类型
byte类型
byte类型等同于unsigned char类型,长度为1字节,存储一个8位无符号数,表示范围从0到255。
byte m = 25 ;
word类型
与unsigned int类型相同。在8位Arduino板中为16位(2字节),在16位Arduino板(如Due、Zero)中,长度为32位(4字节)。
word w = 10000 ;
空类型
void
void关键字仅用于函数声明。它表示该函数不会向调用它的函数返回任何信息。
数组类型
array
Arduino中数组的定义与使用与C语言完全相同。
int myInts[6];
int myPins[] = {2, 4, 8, 3, 6};
int mySensVals[6] = {2, 4, -8, 3, 2};
char message[6] = "hello";
字符串(字符数组)
string
Arduino对字符串的处理有两种方式:一是与传统C语言完全相同的字符数组方式,二是String对象方式。
char Str1[15];
char Str2[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o'};
char Str3[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o', '0'};
char Str4[ ] = "arduino";
char Str5[8] = "arduino";
char Str6[15] = "arduino";
也可以使用二维数组的形式来实现多行字符串的存储:
char* myStrings[]={"This is string 1", "This is string 2",
"This is string 3",
"This is string 4", "This is string 5","This is string 6"};
void setup(){
(9600);
}
void loop(){
for (int i = 0; i < 6; i++){
n(myStrings[i]);
delay(500);
}
}
常量和变量
变量
Arduino的变量命名规则与C语言完全相同,变量名只能由字母、数字和下划线组成,且只能由字母和下划线开头。与C语言一样,变量名是大小写敏感的。
与C语言相同,Arduino的变量按照作用范围分为全局变量和局部变量,全局变量在所有函数的外部声明,所有函数都可以访问全局变量的值,局部变量在函数形参及函数体内部声明,仅在声明的函数体内部可以访问。全局变量在整个程序运行过程中始终存在,而局部变量在函数调用结束后其所占用的空间就会被释放,其值将随之消失。
常量
常量的命名规则同变量。按照C语言的编程规约,一般常量名用全大写字母,以便于与变量名区分。
Arduino有一些内置的常量定义:
1. HIGH | LOW
通常用于表示某个引脚的高低电平,HIGH表示高电平,LOW表示低电平。
这对常量经常配合数字引脚输入输出函数(digitalWrite()、digitalRead())使用。
2. INPUT | OUTPUT | INPUT_PULLUP
用于表示某个引脚工作在输入或输出模式,INPUT表示输入,OUTPUT表示输出,INPUT_PULLUP表示启用内部上拉电阻的输入。
当某引脚被设定为INPUT后,如果外接到电源的上拉电阻(一般阻值为10K),则按键按下后该引脚的输入值为LOW,按键断开时该引脚的输入值为HIGH,如果接到地的下拉电阻,则相反。如果没有外接的上拉或下拉电阻,当按键断开时,引脚将处于“浮空”状态,输入究竟是高电平还是低电平是不确定的。为了避免这种不确定性,可以将该引脚输入模式设定为INPUT_PULLUP,这时将会启用单片机内部的上拉电阻,起到与外接上拉电阻同样的作用。
上述三个常量与pinMode()函数配合使用,综合举例如下:
int ledPin = 13; //将LED连接到13号引脚
void setup()
{
pinMode(ledPin, OUTPUT); //将ledPin引脚设置为输出状态
}
void loop()
{
digitalWrite(ledPin, HIGH); //向ledPin引脚输出高电平
delay(1000); //延时1000毫秒
digitalWrite(ledPin, LOW); //向ledPin引脚输出低电平
delay(1000); //延时1000毫秒
}
int ledPin = 13; //将LED连接到13号引脚
int inPin = 7; //将一个按键连接到7号引脚
int val = 0; //用于保存按键输入状态的变量
void setup()
{
pinMode(ledPin, OUTPUT); //将ledPin设置为输出状态
pinMode(inPin, INPUT); //将inPin设置为输入状态
}
void loop()
{
val = digitalRead(inPin); //将按键的状态读取到val变量
digitalWrite(ledPin, val); //将val变量的值输出到LED
}
整型常量
数制
十进制
二进制
八进制
十六进制
123
B11010011
0123
0x123
举例
以“B”开头,八个0、1组成
以“0”开头,数字范围为0-7
以“0x”开头,数字范围为0-9,A-F或a-f
格式
浮点常量
类型
纯小数
普通浮点数
科学计数法
.123
1.234
1.23e4、1.23E-4
举例
E或e均可
格式
纯小数可以省略小数点前的0
运算符
Arduino的运算符类型与用法与C语言完全相同。
类型
算术运算符
运算符
=、+、-、*、/、%
比较运算符
逻辑运算符
位运算符
复合运算符
指针运算符
==、<、>、<=、>=、!=
&&、||、!
&、|、~、^、>>、<<
++、--、+=、-=、*=、/=、%=、&=、|=
*、&
分支结构
Arduino的分支结构语法与C语言完全相同,包括if、if…else、switch case三种结构。
单分支if结构:
if (表达式)
{
// 若表达式为真,则执行{}内语句
}
双分支if…else结构:
if (表达式)
{
// 若表达式为真,则执行{}内语句
}
else
{
//若表达式为假,则执行else后面{}内语句
}
多分支switch case结构:
switch (变量) {
case 常量1:
// 若变量的值等于常量,则执行
break; // 跳出switch结构,应确保每个case分支最后有break
case 常量2:
// 语句
break;
default: // 若前面所有常量值均不匹配,则执行default后面语句
// 语句
break;
}
循环结构
Arduino的循环结构与C语言完全相同,包括for、while、do…while三种结构。也允许在循环体中使用break、continue,但为了保持结构化程序设计规则,一般不推荐使用这两条语句。
for循环:
for (初始化部分; 进入循环的条件; 循环变量值的修改) {
//一条或多条语句;
}
while循环:
while(表达式){
// 循环体,若表达式值为真,则执行
}
do…while循环:
do
{
// 循环体
} while (表达式);
while循环的循环体有可能没有被执行的机会(当括号中的表达式为假时),do…while循环的循环体则至少被执行一次。
Arduino编程语言本质上是一种面向过程的语言,与传统C语言类似,函数是构成Arduino程序的基本结构单位,Arduino内置函数涵盖了常用的输入输出、中断处理、数值计算、类型转换、字符处理、延时与定时等功能。对各种外部传感器及扩展接口的支持,主要通过类库来实现,这使得Arduino语言具备了“基于对象”的特性——仅引入了类、对象、方法(函数)等面向对象的基本特性,因而并非真正“面向对象”的语言。
正是由于丰富的函数和类库的存在,极大地降低了Arduino应用系统的编程难度,诸如串行通信、I2C接口、中断处理、各种外接传感器模块的使用等都可以找到相应的函数或类库,编程者无需了解低层操作细节,只需要调用相应函数或对象的方法即可。Arduino允许用户开发类库,Arduino社区有大量用户贡献和维护的类库。
函数
基本输入输出函数
Arduino的基本输入输出函数主要用于实现对通用I/O接口的读写操作,可以分为数字输入输出和模拟输入输出两类。数字输入输出即向引脚读写高低电平。模拟输入输出的含义是:模拟输入仅适用于具有模数转换功能的引脚,即Arduino控制板上通常标注的A0、A1等引脚,其本质是模数转换,即将外加在该引脚上的电压值转换为数值存储到相应变量中;所谓模拟输出,并非真正输出连续变化的电压或电流,而是输出一定频率的PWM信号,主要用于电机调速、舵机转向、LED调光等场景。
数字输入输出函数
与数字信号输入输出相关的函数主要有pinMode()、digitalWrite()与digitalRead()三个,其中pinMode用来设定某个引脚为输入还是输出状态,也可以用来切换某个引脚的输入或输出状态,digitalWrite()与digitalRead()则用来实现输出与输入操作。
int ledPin = 13; //将LED连接到13号引脚
void setup()
{
pinMode(ledPin, OUTPUT); //将ledPin引脚设置为输出状态
}
void loop()
{
digitalWrite(ledPin, HIGH); //向ledPin引脚输出高电平
delay(1000); //延时1000毫秒
digitalWrite(ledPin, LOW); //向ledPin引脚输出低电平
delay(1000); //延时1000毫秒
}
int ledPin = 13; //将LED连接到13号引脚
int inPin = 7; //将一个按键连接到7号引脚
int val = 0; //用于保存按键输入状态的变量
void setup()
{
pinMode(ledPin, OUTPUT); //将ledPin设置为输出状态
pinMode(inPin, INPUT); //将inPin设置为输入状态
}
void loop()
{
val = digitalRead(inPin); //将按键的状态读取到val变量
digitalWrite(ledPin, val); //将val变量的值输出到LED
}
模拟输入函数
如前所述,模拟输入的本质是模数转换,8位Arduino控制板(如Uno、NANO等)具有6-8个模数转换引脚(编号为A0、A1等),也叫6-8个模数转换通道,每通道包含一个10位模数转换器,默认参考电压为5V的情况下,可以将加到引脚上的0-5V范围的电压对应转换为0-1023(210-1)范围的整数。
模数转换示例:
运行以下程序,调节可变电阻器,即可在串口监视器看到0-1023范围内变化的数值。
int analogPin = 3; //可变电阻器中间引脚接Arduino控制板A3引脚
//可变电阻器另外两端分别接+5V和GND
int val = 0; //用于存储转换结果的变量
void setup()
{
(9600); //初始化串口,以便输出转换结果
}
void loop()
{
val = analogRead(analogPin); //实现模数转换
n(val); //从串口输出转换值
}
模拟输出函数
如前所述,模拟输出的本质是输出PWM信号。并非所有的数字引脚内部都有能够支持PWM输出的硬件结构,基于ATMega328单片机的Arduino控制板(如Uno、Nano),A3、A5、A6、A9、A10及A11引脚可用于analogWrite函数的输出。analogWrite函数有两个参数:第一个参数指定输出的引脚,第二个参数指定PWM信号占空比,取值范围为0-255。
运行下列程序,将会看到LED的亮度随可变电阻的改变而改变。
int ledPin = 9; // LED连接到数字引脚D9
int analogPin = 3; // 可变电阻器中间引脚连接到模拟引脚A3
// 可变电阻器其余两脚分别接+5V和GND
int val = 0; // 用于存储模数转换值的变量
void setup()
{
pinMode(ledPin, OUTPUT); // ledPin(D9)设置为输出
}
void loop()
{
val = analogRead(analogPin); //模数转换
analogWrite(ledPin, val / 4); //用模数转换值控制PWM占空比
// 由于模数转换结果在0-1023之间,而PWM占空比的取值范围为0-255,因此要val/4
}
ATmega328
引脚名称
PD0
PD1
PD2
PD3
PD4
PD5
PD6
PD7
PB0
PB1
PB2
PB3
PB4
PB5
PC0
PC1
PC2
PC3
PC4
PC5
用作数字输入输出时Arduino编程语言中使用的编号
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14 或 A0
15 或 A1
16 或 A2
17 或 A3
18 或 A4
19 或 A5
用作模拟输入时Arduino编程语言中使用的编号
不可用
不可用
不可用
不可用
不可用
不可用
不可用
不可用
不可用
不可用
不可用
不可用
不可用
不可用
0
1
2
3
4
5
Arduino板上标注的名称
0
1
2
3~
4
5~
6~
7
8
9~
10~
11~
12
13
A0
A1
A2
A3
A4
A5
高级输入输出函数
tone()与noTone()
用于输出一定频率的方波(占空比50%)信号,对Uno及近似型号,其频率范围为31-65535Hz。
语法:tone(pin, frequency, duration)
pin:输出引脚号,frequency:频率,duration:输出持续时间,单位为毫秒,数据类型为unsigned long。
其中第三个参数为可选项,如省略,则直到调用noTone(pin)函数,相应的引
脚上才停止输出。
注意,由于这两个函数均是利用了ATmega单片机中的一个定时器来实现的,所以同时只能在一个引脚上使用,如果要在多个引脚上输出,只能先停止正在输出的引脚。例程如下:
void setup() {
}
void loop() {
// 将引脚8上的输出关闭
noTone(8);
// 在引脚6上输出频率为440Hz,持续时间200ms的方波
tone(6, 440, 200);
delay(200);
// 将引脚6上的输出关闭
noTone(6);
// 在引脚7上输出频率为494Hz,持续时间500ms的方波
tone(7, 494, 500);
delay(500);
//将引脚7上的输出关闭
noTone(7);
// 在引脚8上输出频率为523Hz,持续时间300ms的方波
tone(8, 523, 300);
delay(300);
}
shiftOut()与shiftIn()
这两个函数可以实现将一个或多个字节的数据诸位串行输出或输入,通常配合74HC595这类“串入并出”或“并入串出”芯片使用,达到节约单片机IO口线的目的。
语法:shiftOut(dataPin, clockPin, bitOrder, value)
dataPin:数据引脚,clockPin:时钟引脚,提供驱动74HC595芯片进行移位动作的时钟脉冲,bitOrder:移位的顺序,若从最高位开始移位,则可用系统常量MSBFIRST(Most Significant Bit First)表示,若从最低位开始移位,则用LSBFIRST(Least Significant Bit First),value待移位输出或输入的数据,长度为1字节。
int data = 500;
// 若输出的数据长度为2字节,则先通过移位运算取得其高字节(高8位)
shiftOut(dataPin, clock, MSBFIRST, (data >> 8));
// 然后再输出其低8位。注意,不管data是几个字节,shiftOut()仅能输出其低8位
shiftOut(dataPin, clock, MSBFIRST, data);
下面是一个完整的示例,依次在74HC595的Q0-Q7引脚上输出0-255:
//*******************************************************//
// Name : shiftOutCode //
// Author : Carlyn Maw,Tom Igoe //
// Date : 25 Oct, 2006 //
// Version : 1.0 //
// Notes : Code for using a 74HC595 Shift Register //
// : to count from 0 to 255 //
//*******************************************************//
//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;
void setup() {
//set pins to output because they are addressed in the main
loop
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop() {
//count up routine
for (int j = 0; j < 256; j++) {
//ground latchPin and hold low for as long as you are
transmitting
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, j);
//return the latch pin high to signal chip that it
//no longer needs to listen for information
digitalWrite(latchPin, HIGH);
delay(1000);
}
}
pulseIn()
该函数可测量输入某引脚的两次高低电平反转之间的时间间隔。例如,当某引脚由低电平跳转为高电平时开始计时(以微秒为单位),当再次跳转为低电平时停止计时,并返回计时值。可计时的范围为(10微秒-3分钟),若返回值为0,则表示没有检测到第二次跳变。
延时函数
数学函数
字符处理函数
中断处理函数
类库
版权声明:本文标题:5-Arduino编程语言基础 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1708328625h519960.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论