日照市东港区创新电子技术中心
外贸网站建设
域名注册
案例中心
知识学堂
联系我们
arduinoTimer1定时中断
2019-11-22 18:46:01 (12922)
arduino定时器包含定时器/计数器0,定时器/计数器1,定时器/计数器2三个。定时器/计数器0和定时器/计数器2是一个8位的计数器,定时器/计数器1是一个16位长的计数器。timer1最大值为65535,在使用之前我们需要进行一些设置,从而使得timer1可以运行起来。进行这些设置,我们需要用内置的寄存器来存储这些设置。每一个定时器都有很多寄存器,本篇文章主要侧重timer1 的介绍和使用。存储这些初始值的寄存器的两个寄存器TCCRXA,TCCRXB(其中X代表序号定时器的编号0,1,2).其中TCCR是英文
Timer/Counter
Control Register
简写,
下面是TCCR1A和TCCR1B的具体情况。每个寄存器共8位,每位都存储了一些值来进行定时器的设置。表引用自:
http://www.atmel.com/dyn/product ... 60&part_id=4198
开始使用timer1的话,
CS12, CS11和CS10的设置是很重要的。这三个值得设置可以让定时器工作在不同的频率。不同的设置的频率如下表所示:
默认的,这些值都是为0的,我们用一个例子来说明问题。下边这个例子是设置定时器1溢出中断,在溢出的时候我们让2号引脚连接的LED灯亮灭转换。首先我们来进行初始化timer1。
//包含avr-lib库
#include <avr/io.h>
#include <avr/interrupt.h>
#define LEDPIN 2
void setup()
{
pinMode(LEDPIN, OUTPUT);
// 初始化timer1
cli(); //禁止全局中断
TCCR1A = 0; //设置TCCR1A全为0
TCCR1B = 0;
// 设置允许timer溢出中断
TIMSK1 = (1 << TOIE1);
//设置CS10位为1从而使定时器以时钟的速度运行。
TCCR1B |= (1 << CS10);
/允许全局中断
sei();
}
在上边这段代码中TIMSK1代表的是
Timer/Counter1 Interrupt Mask Register
.这个寄存器控制着timer允许怎样的中断。其中TOIE1表示的溢出中断。其他的后边会继续介绍。
由于我们上班设置了CS10,定时器1就会开始工作。当定时器1溢出时就会执行中断服务程序中断服务程序如下:
ISR(TIMER1_OVF_vect)
{
digitalWrite(LEDPIN, !digitalRead(LEDPIN));
}
这样,我们就可以让loop不做任何事情了,加入我们要停止中断只用设置TCCR1B为0就可以了。
上班每次的中断时间大概为((1/16)*e-6)*
65535=0.0041us,时间比较短,假若我们想要更长的时间,我们可以设置CS11,CS12,组合来进行设置。这样我们的时间就可以变化了。
比如下边的例子:
void setup()
{
pinMode(LEDPIN, OUTPUT);
// 初始化timer1
cli(); //禁止全局中断
TCCR1A = 0; //设置TCCR1A全为0
TCCR1B = 0;
// 设置允许timer溢出中断
TIMSK1 = (1 << TOIE1);
//设置CS10位为1从而使定时器以时钟的速度运行。
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS12);
sei();
}
[size=1em]这样我们的时间就(1/16000000)*1024*65536=4.1s,
再者,加入我们想要确定的时间而不是定时器溢出来做中断,怎么做呢,
在定时器中断有另外一个模式叫做CTC(
Clear Timer on Compare Match
),在这个模式下,timer1不在是溢出中断了,而是在寄存器中设定好的值进行比较,若大于则进入中断,这种模式的设置例子如下:
void setup()
{
pinMode(LEDPIN, OUTPUT);
// 初始化timer1
cli(); // 进制全局中断
TCCR1A = 0; //设置TCCR1A全为0
TCCR1B = 0; //
[size=1em]设置TCCR1B全为0
//设置比较的值得大小
OCR1A = 15624;
// 开启CTC模式
TCCR1B |= (1 << WGM12);
// 设置 CS10和CS12位
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS12);
// 允许比较中断
TIMSK1 |= (1 << OCIE1A);
sei(); // 允许全局中断
}
ISR(TIMER1_COMPA_vect)
{
digitalWrite(LEDPIN, !digitalRead(LEDPIN));
}
在这里:
目标时间=时间周期*(时钟次数+1)
时钟次数+1=
目标时间/时钟周期,
比如说我们要获取一秒的时间,则定时器1 的数值改变次数为1000/((1/16000000)*1024)
如果想要获取更长的时间;
比如说10秒,又要防止溢出,
可以这样写
ISR(TIMER1_COMPA_vect)
{
seconds++;
if (seconds == 10)
{
seconds = 0;
readMySensor();
}
}
了解更多请访问:
http://www.ndfweb.cn/news-737.html
NDF俱乐部
• 所有分类
• 公告与动态
(24)
• 国际外贸
(65)
• 网站优化(SEO)
(50)
• 外贸B2C学堂
(16)
• 商业摄影
(9)
• 美国主机教程
(17)
• PHP网站设计
(66)
• 科技学堂
(14)
• 网站设计技术分享
(192)
• 开店创业
(26)
• 音乐学堂
(6)
• 美食
(7)
• 互联网创业
(98)
• 安卓程序开发
(18)
• Python
(11)
• 单片机与无线电
(65)
• VB.net程序开发
(13)
国际域名注册
新网.COM域名注册
80元/年
建站咨询
QQ
旺旺
其他方式
合作伙伴:
万网
|
新网
|
新网互联
NDF网站建设淘宝店
|
实用工具
|
外貿網站建設
|
联系我们
鲁公网安备 37110202000336号
Sitemap
-
RSS