Arduino编程之---周期性任务
Arduino在编程使用过程中,有一种情况非常常见。那就是某一项任务需要周期性的执行。可能是获取传感器的数值,也可能是控制灯的亮灭,或者发送串口数据等等。 那么现在就来介绍下编写这些周期性任务的方法吧。一、中断概念。 很多使用Arduino的童鞋都没有用过其他种类的单片机,可能对中断的概念不是很了解。这里简要的说一下。 大家都知道,程序在Arduino里是顺序执行的。一个循环走完,再继续下一个循环。当执行一个函数的时候,会跳转到那个函数的代码段去执行。中断与函数类似,也是在执行的过程中,会跳转到某一个函数去执行。但是中断的最大特点是他不是由代码来触发的,而是由一个“中断条件”来触发。也就是说当设置好“中断条件”之后,这个中断所跳转的函数不需要代码来触发,而是由“中断条件”来触发。 那么中断条件有哪些?
大概有两类软件中断和硬件中断。
软件中断就是写个特定代码,让中断产生,这种方式与函数调用非常类似。所以一般只用在调试中。 硬件中断是主要有实际意义的方式,常用的包含IO口产生的中断,定时器产生的中断,以及其他外设如:串口,I2C,SPI等产生的中断。
中断产生之后,去执行的那段代码,我们称为“中断函数”。至此,中断相关的概念介绍的就差不多了。
二、利用定时器中断 我们要完成一个周期性任务,需要的便是设置定时器中断。此时“中断条件”为定时器时间到。“中断函数”为你所要执行的任务。 下面的程序是用定时器中断让13引脚 led灯每500ms变化一次。
ARDUINO 代码// led灯接UNO的13管脚
#include <MsTimer2.h>//定时器库的 头文件
void flash() //中断处理函数,改变灯的状态
{
static boolean output = HIGH;
digitalWrite(13, output);
output = !output;
}
void setup()
{
pinMode(13, OUTPUT);
MsTimer2::set(500, flash);// 中断设置函数,每 500ms 进入一次中断
MsTimer2::start(); //开始计时
}
void loop()
{
}
例子中MsTimer2::set(500,flash)便是设定中断条件500ms,中断函数为flash.二、用一种简单的替代方式。
在此再提供一种方法,利用mills()同样函数可以实现中断的功能。mills()函数功能是获取系统运行的时间长度,单位ms。最大为9小时22分,如果超出时间将从0开始。函数的返回值为unsigned long型。
下面程序的功能让led灯亮灭各500ms :
ARDUINO 代码unsigned long ledOn=500,ledOff=500;
//定义led灯变化的时间长度,每500ms变化一次
int ledStatus;
//定义LED灯的状态,HIGH or LOWm
void setup()
{
pinMode(13,OUTPUT);
digitalWrite(13,HIGH);
ledStatus=HIGH;
}
void loop()
{
unsigned long nowtime=millis(); //获取当前的系统运行时间长度
if(ledStatus==HIGH)
//如果当前lled灯状态为高电平,则执行该程序
{
if(nowtime>ledOn)
//检测系统运行时间长度是否到500ms
{
ledOn=nowtime;
//记录当前时间长度,第一次为500ms,赋值给ledOn
ledOff=nowtime+500;
//计算出下一次led灯变化的时刻,第一次运行程序时应该在1000ms时关灯
digitalWrite(13,LOW); //关掉led灯
ledStatus=LOW;
//记录当前led灯状态,下一次使用
}
}
else{
if(nowtime>ledOff)
{
ledOff=nowtime;
ledOn=nowtime+500;
digitalWrite(13,HIGH);
ledStatus=HIGH;
}
}
}
该方式同样可以在大部分情况下达到500ms执行一次任务,但是该方式与之前中断的思想是完全不同的,同时也有一定的风险。即,当整个循环的时间大于500ms的时候,那么这个任务可能就没法及时的执行了,有被阻塞的风险。 PS:使用mills()函数虽然没有中断可靠,但相比于delay()函数还是有很大优势的。其占用的整个程序运行时间短,如果用用delay()函数,在延时的时间内,CPU不能干别的事儿。
我来消灭0回复吧~很好的帖子啊
页:
[1]