Arduino 鶸鷄 • 函数篇

请注意,本文编写于 230 天前,最后修改于 23 天前,其中某些信息可能已经过时。

作为 Arduino 入门系列博文承前启后的一篇,这里详细介绍一些关于 Arduino 函数 的知识。小怪兽也是边写边学,花了好几天,实际效果感觉还不错。文章末尾推荐了一些个人感觉比较全面的 Arduino 学习链接,可以搭配本文食用,补缺补漏,加大学习深度。文章中的错误希望路过的大佬不要笑话,欢迎留言指正,谢谢。
 

附上手动目录:

  1. 数字 I/O 口操作函数
  2. 模拟 I/O 口操作函数
  3. 高级 I/O 口操作函数
  4. 时间函数
  5. 中断函数
  6. 串口通信函数
  7. Arduino 库函数
  8. 推荐链接

 
 

数字 I/O 口操作函数

  • pinMode(pin,mode);

pinMode 函数用于配置引脚与输出或输入模式,为无返回值函数。函数有两个参数:pin 和 mode。一般该函数会放在 setup 里先设置再使用。pin 参数表示要配置的引脚,范围是数字引脚 0~13 或模拟引脚 A0~A5(此时编号 14 对应模拟引脚 A0,15 对应模拟引脚 A1...19 对应模拟引脚 A5)。mode 参数表示设置的参数为 INPUT(输入)或 OUTPUT(输出)。INPUT 值用于读取信号,OUTPUT 值用于输出控制信号。

  • digitalWrite(pin,value);

digitalWrite 函数用于设置引脚的输出电压为高电平(HIGH)或低电平(LOW),也是一个无返回值函数。函数有两个参数 pin 和 value。pin 参数指定要设置的引脚编号。value 参数取 HIGH 和 LOW 之一指定输出的电平高低。值得注意的是 digitalWrite 操作函数使用前必须先用 pinMode 操作函数设置。

  • digitalRead(pin);

digitalRead 函数在引脚设置为输入(INPUT)的情况下用于获取引脚的电压情况(读取 HIGH(高电平)或 LOW(低电平))。

  • 实例
int button = 9;                   // 设置按钮输入引脚为 9 引脚
int LED = 13;                     // 设置 LED 输出引脚为 13 引脚(内部连接与板上的灯)
void setup()
{
  pinMode(button,INPUT);           // 设置按钮为输入
  pinMode(LED,OUTPUT);             // 设置 LED 灯为输出
}
void loop()
{
  if (digitalRead(button) == LOW)  // 如果读取到按钮引脚为高电平
    digitalWrite(LED,HIGH);        // 则设置 13 引脚 LED 灯输出为高电平
  else
    digitalWrite(LED,LOW);         // 否则设置 13 引脚 LED 灯输出为低电平
}

 

模拟 I/O 口操作函数

  • analogReference(type);

analogReference 函数用于配置模拟引脚的参考电压。type 有三种:DEFAULT、INTERNAL、EXTERNAL。DEFAULT 值为默认参考电压 5V;INTERNAL 值为低电压模式,使用片内基准电压 2.56V;EXTERNAL 值为扩展模式,通过 AREF 引脚获取参考电压(使用 AREF 作为参考电压需要接一个 5kΩ 的上拉电阻)。

  • analogRead(pin);

analogRead 函数用于读取引脚的模拟量电压值,每读取一次要花 100μs 的时间。pin 参数表示所要获取模拟量电压值的引脚,取值范围 0~5 对应开发板上的模拟引脚 A0~A5。函数返回值为精度为 10 位 int 类型数据,范围从 0 到 1023。

  • analogWrite(pin,value);

analogWrite 函数通过 PWM(Pulse-Width Modulation) 脉冲宽度调制的方式在引脚上输出一个模拟量。此操作函数主要应用于 LED 亮度控制、电机转速控制等方面。下面图中为 PWM 输出的一般形式,体现在一个脉冲周期内高电平所占的比例(也叫“占空比”)上。

PWM 与占空比示意图
PWM 与占空比示意图

  • 实例
int sensor = A0;               // 设置电位器引脚为 A0 模拟引脚
int LED = 11;                  // 设置 LED 连接引脚为 11 引脚
void setup()
{
  Serial.begin(9600);          // 设置串口的波特率为 9600bps,后面介绍串口通信函数时会讲
}
void loop()
{
  int v;                       // 定义一个 int 型变量 v 
  v = analogRead(sensor);      // 读取电位器引脚的模拟量电压值存入变量 v 
  Serial.println(v,DEC);       // 以十进制形式输出读取的模拟量的 ASCII 编码值,后面介绍串口通信函数会讲
  analogWrite(LED,v/4);        // 由于 analogWrite 函数 value 参数值范围为 0~255 ,所以此处将读取的值除以 4 
}

 

高级 I/O 口操作函数

  • pulseln(pin,state,timeout);

pulseln 函数用于读取引脚脉冲的时间长度。脉冲电平可以是 HIGH 也可以是 LOW,该函数将等待引脚信号变为高电平(HIGH)然后开始计时,一直到信号变为低电平。返回脉冲持续的时间长度,单位为 ms ,若超时未读取到时间则返回 0。

  • 实例
/*
 * 制作一个按钮脉冲计时器检测按钮按下持续时间,
 */
int button = 3;                    // 设置按钮连接引脚为 3 引脚
int count;                         // 定义一个计时变量 count 
void setup()
{
  pinMode(button,INPUT);           // 设置按钮为输入
}
void loop()
{
  count = pulseln(button,HIGH);    // 读取按钮引脚信号为 HIGH 即按钮按下状态的时间
  if (count != 0)                  // 按钮一旦被按下
  {
    Serial.println(count,DEC);     // 以十进制形式输出变量 count 的 ASCII 编码值,后面介绍串口通信函数会讲
    count = 0;                     // 归零计时变量
  }
}

 

时间函数

  • delay();

delay 函数是一个延时函数,其参数为延时时长,单位为 ms。延时函数的典型例程是跑马灯应用(好像也有人管这叫流水灯?),代码参见此部分结尾实例。

  • delayMicroseconds();

delayMicroseconds 函数与 delay 函数一样也是延时函数,区别在于 delayMicroseconds 函数产生延时的单位为 μs(1ms=1000μs),可以产生更短的延时。

  • millis();

millis 函数为计时函数,可以获取单片机通电到运行该函数时刻之间的时间长度单位为 ms。系统最长的记录时间为 9 小时 22 分,超出则从 0 开始计数。该函数返回值为 unsigned long 类型数据。此函数适合作为定时器使用,不影响单片机其他工作(使用 delay 延时函数期间单片机无法进行其他工作),典型例程代码参见此部分结尾实例。

  • micros();

micros 函数与 millis 函数一样也是计时函数,区别在于 micros 函数计时的单位为 μs(1ms=1000μs),可更精确的计时。系统最长的记录时间为 70min,该函数返回值与 millis 函数一样为 unsigned long 类型数据。

  • 实例
/*
 * delay 函数应用。跑马灯应用,控制 Arduino 开发板上 6、7、8、9 四个 LED 灯依次点亮
 */
void setup()
{
  pinMode(6,OUTPUT);         // 定义 6 号 LED 灯为输出
  pinMode(7,OUTPUT);         // 定义 7 号 LED 灯为输出
  pinMode(8,OUTPUT);         // 定义 8 号 LED 灯为输出
  pinMode(9,OUTPUT);         // 定义 9 号 LED 灯为输出
}
void loop()
{
  int i;
  for(i = 6;i <= 9;i++)      // 利用 for 循环依次点亮 4 盏灯
  {
    digitalWrite(i,HIGH);    // 点亮 i 号 LED 灯
    delay(1000);             // 延时 1000ms
    digitalWite(i,LOW);      // 熄灭 i 号 LED 灯
    delay(1000);             // 延时 1000ms
  }
}
 
/*
 * millis 函数应用
 */
int LED = 13;                // 设置变量 LED 监管 13 引脚
unsigned long i,j;           // 定义 unsigned long 类型变量 i,j 用来存储时间
void setup()
{
  pinMode(LED,OUTPUT);       // 设置 LED 为输出
  i = millis();              // 读入初始时间值
}
void loop()
{
  j = millis();              // 不断读取当前时间值
  if ((j - i) > 10000)       // 如果当前时间值延时超过 10000ms
  {
    digitalWrite(LED,HIGH);  // 则点亮 LED 灯
  }
  else
    digitalWrite(LED,LOW);   // 否则熄灭 LED 灯
}
 
/*
 * micros 函数应用。打印开机时间
 */
unsigned long time;          // 定义 unsigned long 类型变量 time 用于存储开机时间
void setup()
{
  Serial.begin(9600);
}
void loop()
{
  Serial.print("Time:");
  time = micros();            // 读取单片机通电时刻至当前时刻之间的时间微秒值
  Serial.println(time);       // 打印单片机通电时刻至当前时刻之间的时间微秒值
  delay(1000);                // 延时 1000ms 再次循环
}
 
/*
 * micros 函数应用。跑马灯应用的另一种实现思路
 */
int LED = 13;                 // 设置变量 LED 监管 13 引脚
unsigned long i,j;            // 定义 unsigned long 类型变量 i,j 用来存储时间
void setup()
{
  pinMode(13,OUTPUT);         // 设置 LED 为输出
  i = micros();               // 读入初始时间值
}
void loop()
{
  j = micros();               // 不断读取当前时间值
  if ((j - i) > 1000000)      // 如果延时超过 1000000μs
  {
    digitalWrite(LED,HIGH);   // 则点亮 LED
  }
  else
    digitalWrite(LED,LOW);    // 否则熄灭 LED
}

 

中断函数

计算机或者单片机中的 中断 是指:由于某个随即事件的发生,机器暂停原程序的运行转而去执行另外一个程序,处理完毕后又自动返回原程序继续执行的过程。换句话说这是由于高优先级的任务出现中断了低优先级的任务执行过程。在计算机中中断包括以下几个部分:①中断源——引起中断的原因,能发生中断申请的来源;②主程序——计算机现运行的程序;③中断服务子程序——处理突发事件的子程序。Arduino 单片机中关于处理程序中断的函数有以下几个:

  • attachInterrupt(interrupt,function,mode);

attachInterrupt 函数用于设置中断,函数的三个参数以此表示中断源中断处理函数触发模式。interrupt 中断源参数可选 0 或者 1,对应 2 或者 3 号数字引脚;function 中断处理函数参数是一段子程序,当中断发生时执行该子程序部分代码。mode 触发模式参数有 4 种:① LOW(低电平触发) ② CHANGE(变化时触发) ③ RISING(低电平变为高电平时触发) ④ FALLING(高电平变为低电平时触发) 。

  • detachInterrupt(interrupt);

detachInterrupt 函数用于取消中断,参数 interrupt 表示所要取消的中断源。

  • 实例
// D2 引脚连接按钮开关,D4 引脚连接 LED1(红色),D5 引脚连接 LED2(绿色),LED3 为 Arduino 板载 LED,每秒闪烁一次。
// 使用中断 0 来控制 LED1 ,使用中断 1 来控制 LED2 ,按下按钮立即响应中断。LED3 由于中断响应速度很快不受影响继续闪烁。
// 下面两个应用实例分两组试验 LOW CHANGE / RISING FALLING 四种触发模式。
 
/*
 * attachInterrupt 函数应用1。
 */
volatile int state1 = LOW,state2 = LOW;
int LED1 = 4;
int LED2 = 5;
int LED3 = 13;
void setup()
{
  pinMode(LED1,OUTPUT);
  pinMode(LED2,OUTPUT);
  pinMode(LED3,OUTPUT);
  attachInterrupt(0,LED1_Change,LOW);       // 这里使用 LOW 低电平触发
  attachInterrupt(1,LED2_Chande,CHANGE);    // 这里使用 CHANGE 电平变化触发
}
void loop()
{
  digitalWrite(LED3,HIGH);
  delay(500);
  digitalWrite(LED3,LOW);
  delay(500);
}
void LED1_Change()
{
  state1 = !state1;
  digitalWrite(LED1,state1);
  delay(100);
}
void LED2_Change()
{
  state2 = !state2;
  digitalWrite(LED2,state2);
  delay(100);
}
 
/*
 * attachInterrupt 函数应用2。
 */
volatile int state1 = LOW,state2 = LOW;
int LED1 = 4;
int LED2 = 5;
int LED3 = 13;
void setup()
{
  pinMode(LED1,OUTPUT);
  pinMode(LED2,OUTPUT);
  pinMode(LED3,OUTPUT);
  attachInterrupt(0,LED1_Change,RISING);    // 这里使用 RISING 电平上升沿触发
  attachInterrupt(1,LED2_Chande,FALLING);   // 这里使用 FALLING 电平下降沿触发
}
void loop()
{
  digitalWrite(LED3,HIGH);
  delay(500);
  digitalWrite(LED3,LOW);
  delay(500);
}
void LED1_Change()
{
  state1 = !state1;
  digitalWrite(LED1,state1);
  delay(100);
}
void LED2_Change()
{
  state2 = !state2;
  digitalWrite(LED2,state2);
  delay(100);
}

 

串口通信函数

串行通信接口(Serial Interface)是指数据一位位地顺序传送,通信线路简单,只需要一对传输线就可以实现双向通信的接口。串行通信接口出现在 1980 年前后,数据传输速率为 115~230kbps。它出现的初期是为了实现在计算机外部设备的通信,一般用来连接鼠标、外置 Modem、老式摄像头、写字板等设备。
由于串行通信接口(COM)不支持热插拔而且传输数据较低,目前部分新主板和大部分便携电脑已经取消该接口,目前串口多用于工业控制和测量设备以及部分通信设备中,包括各种传感器采集装置、GPS 信号采集装置、多单片机通信系统、门禁刷卡系统等的数据传输,机械手臂控制,操纵面板控制电机等,尤其广泛应用于低速数据传输工程。

  • Serial.begin();

Serial.begin 函数用于设置串口的波特率(数据传输速率,用每秒传输的符号个数表示)。一般的波特率有 9600、19200、57600、115200 等。

  • Serial.available();

Serial.available 函数用于判断端口是否收到数据,返回为 int 类型值,不带参数。

  • Serial.read()

Serial.read 函数用于读取串口数据,返回值为 int 类型串口数据,不带参数。

  • Serial.print();

Serial.print 函数用于向串口发送数据(可以是变量,也可以是字符串)。关于此函数输出数据的多种形式请自行百度。

  • Serial.println();

Serial.println 函数与 Serial.print 函数类似,多一项换行的功能。关于此函数输出数据的多种形式请自行百度。

  • 实例
/*
 * 串口通信函数应用
 */
int x = 0;
void setup()
{
  Serial.begin(9600);                    // 设置串口波特率为 9600bps
}
void loop()
{
  if (Serial.available())                // 检查串口是否收到数据
  {
    x = Serial.read();                   // 读取收到的数据并存入变量 x
    Serial.print("I have received:");    // 使用 Serial.print 函数打印 I have received:
    Serial.println(x,DEC);               // 使用 Serial.println 函数打印变量 x 存储的数据并换行
  }
  delay(1000);                           // 延时 1000ms
}

 

Arduino 库函数

与 C/C++ 一样 Arduino 也有相关的库函数提供给开发者使用,这些库函数的使用与 C 语言的头文件使用类似,需要 #include 语句。在 Arduino 开发中主要库函数有:

  • 数学库,主要包括数学运算
  • EEPROM 库,用于向 EEPROM 中读写数据
  • Ethernet 库,用于以太网的通信
  • LiquidCrystal 库,用于液晶屏幕的显示操作
  • Firmata 库,实现 Arduino 与 PC 串口之间的编程协议
  • SD 库,用于读写 SD 卡
  • Servo 库,用于舵机的控制
  • Stepper 库,用于步进电机的控制
  • Wi-Fi 库,用于 Wi-Fi 的控制和使用

诸如此类的库函数有很多,还有其他 Arduino 爱好者自己开发的库函数也可以使用,下面列举一些数学库中的函数:

 · min(x,y);  max(x,y);               // 求两者之间最小值、最大值
 · abs(x);                            // 求绝对值
 · sin(rad);  cos(rad);  tan(rad);    // 求角度的正弦值、余弦值、正切值
 · random(min,max);                   // 求两者之间随机数,返回 long 类型数据

 

推荐链接

添加新评论