前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Arduino学习笔记】系列1 - 定时器配置一、Arduino定时器简介 二、定时器基本概念三、定时器配置代码

【Arduino学习笔记】系列1 - 定时器配置一、Arduino定时器简介 二、定时器基本概念三、定时器配置代码

作者头像
战神伽罗
发布2021-03-02 16:51:31
6.7K0
发布2021-03-02 16:51:31
举报

Arduino的学习过程中一般使用库函数操作。但是关于定时器的例子常用库却没有。因此,在这里简要通俗的写出定时中断的配置过程。参考资料:http://www.instructables.com/id/Arduino-Timer-Interrupts/。

一、Arduino定时器简介

Arduino UNO有三个定时器,分别是timer0,timer1和timer2。每个定时器都有一个计数器,在计时器的每个时钟周期递增。当计数器达到存储在比较匹配寄存器中指定值时触发CTC定时器中断。一旦定时器计数器达到该值,它将在定时器时钟的下一个定时器上清零(复位为零),然后它将继续再次计数到比较匹配值。通过选择比较匹配值并设置定时器递增计数器的速度,你可以控制定时器中断的频率。

下面引出定时器各个寄存器的配置关系。

二、定时器基本概念

1、预分频系数与比较匹配器

Arduino时钟以16MHz运行。计数器的一个刻度值表示1 / 16,000,000秒(~63ns),跑完1s需要计数值16,000,000。

1、Timer0和timer2是8位定时器,可以存储最大计数器值255。 2、Timer1是一个16位定时器,可以存储最大计数器值65535。

一旦计数器达到其最大值,它将回到零(这称为溢出)。因此,需要对时钟频率进行分频处理,即预分频器。通过预分频器控制定时计数器的增量速度。预分频器与定时器的计数速度如下:

定时器速度(HZ) = Arduino时钟速度(16MHz) / 预分频器系数

因此,1预分频器将以16MHz递增计数器,8预分频器将在2MHz递增,64预分频器= 250kHz,依此类推。

三个定时器的预分频系数配置如表:

我将在下一步中解释CS12,CS11和CS10的含义。

现在您可以用以下步骤计算中断频率。以下公式:

中断频率(Hz)=(Arduino时钟速度16MHz)/(预分频器*(比较匹配寄存器+ 1)

重新排列上面的等式,给出你想要的中断频率,你可以求解比较匹配寄存器值:

比较匹配寄存器= [16,000,000Hz /(预分频器*所需的中断频率)] - 1

记住,当你使用定时器0和2时,这个数字必须小于256,对于timer1小于65536。

所以如果你想每秒一次中断(频率为1Hz):比较匹配寄存器= [16,000,000 /(预分频器 * 1)] -1 预分频器为1024,你得到:比较匹配寄存器= [16,000,000 /(1024 * 1)] -1 = 15,624,因为256 <15,624 <65,536,你必须使用timer1来实现这个中断。

三、定时器配置代码

代码语言:javascript
复制
int toggle0,toggle1,toggle2=0;

void setup(){
 
  cli();//关闭全局中断
 
  //设置定时器0为10kHz(100us)
  TCCR0A = 0;//将整个TCCR0A寄存器设置为0
  TCCR0B = 0;//将整个TCCR0B寄存器设置为0
  TCNT0  = 0;//将计数器值初始化为0
  //设置计数器为10kHZ,即100us
  OCR0A = 24;//比较匹配寄存器= [16,000,000Hz /(预分频器*所需中断频率)] - 1
             //比较匹配寄存器=24,中断间隔=100us即中断频率10khz
  TCCR0A |= (1 << WGM01);//打开CTC模式
  TCCR0B |= (1 << CS01) | (1 << CS00); //设置CS01位为1(8倍预分频)   
  TIMSK0 |= (1 << OCIE0A);//启用定时器比较中断
  
 
  //设置定时器1为1kHz
  TCCR1A = 0;//将整个TCCR1A寄存器设置为0
  TCCR1B = 0;//将整个TCCR1B寄存器设置为0
  TCNT1  = 0;//将计数器值初始化为0
  //设置计数器为10kHZ,即1ms
  OCR1A = 15624;//199;// = (16*10^6)/(1000*8) - 1 (must be <65536)
  TCCR1B |= (1 << WGM12);//打开CTC模式
  TCCR1B |= (1 << CS12) | (1 << CS10);//设置CS11位为1(8倍预分频)
  TIMSK1 |= (1 << OCIE1A);
 
  //设置定时器2为8kHz
  TCCR2A = 0;// set entire TCCR2A register to 0
  TCCR2B = 0;// same for TCCR2B
  TCNT2  = 0;//initialize counter value to 0
  // set compare match register for 8khz increments
  OCR2A = 249;// = (16*10^6) / (8000*8) - 1 (must be <256)
  // turn on CTC mode
  TCCR2A |= (1 << WGM21);//打开CTC模式
  // Set CS21 bit for 8 prescaler
  TCCR2B |= (1 << CS21);   
  // enable timer compare interrupt
  TIMSK2 |= (1 << OCIE2A);
 
  sei();//打开全局中断

  pinMode(13,OUTPUT);
 
}
 
//中断0服务函数
ISR(TIMER0_COMPA_vect){
//产生频率为2kHz / 2 = 1kHz的脉冲波(全波切换为两个周期,然后切换为低)
  if(toggle0){
    digitalWrite(8,HIGH);
    toggle0 = 0;
  }
  else{
    digitalWrite(8,LOW);
    toggle0 = 1;
  }
}
 
ISR(TIMER1_COMPA_vect){// timer1中断1Hz切换引脚13(LED)
//产生频率为1Hz / 2 = 0.5kHz的脉冲波(全波切换为两个周期,然后切换为低)
  if(toggle1){
    digitalWrite(13,HIGH);
    toggle1 = 0;
  }
  else{
    digitalWrite(13,LOW);
    toggle1 = 1;
  }
  delay(2000);
}
  
ISR(TIMER2_COMPA_vect){// timer1中断8kHz切换引脚9
//产生频率为8kHz / 2 = 4kHz的脉冲波(全波切换为两个周期,然后切换为低)
  if(toggle2){
    digitalWrite(9,HIGH);
    toggle2 = 0;
  }
  else{
    digitalWrite(9,LOW);
    toggle2 = 1;
  }
}
 
 
void loop(){
  
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Arduino定时器简介
  • 二、定时器基本概念
    • 定时器速度(HZ) = Arduino时钟速度(16MHz) / 预分频器系数
    • 三、定时器配置代码
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档