ndfweb.cn

Arduino定時器配置(Timer0,Timer1,Timer2)


2020-02-22 21:22:23 (36042)



定時器基本概念:


定時器速度(HZ) = Arduino時鍾速度(16MHz) / 預分頻器係數

中斷頻率(Hz)=(Arduino時鍾速度16MHz)/(預分頻器*(比較匹配寄存器+ 1)

比較匹配寄存器= [16,000,000Hz /(預分頻器*所需的中斷頻率)] - 1


定時器配置代碼:

 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來實現這個中斷。


三、定時器配置代碼

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 = 199;// = (16*10^6)/(1000*8) - 1 (must be <65536)
  TCCR1B |= (1 << WGM12);//打開CTC模式
  TCCR1B |= (1 << CS11);//設置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();//打開全局中斷
 
}
 
//中斷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;
  }
}
  
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(){
  
}


本文版权:http://www.ndfweb.cn/news-778.html
  NDF俱乐部
  国际域名注册
  建站咨询
简体中文 NDF网站建设淘宝店 | ICO图标在线生成 | 外贸网站建设 | 联系我们
©2007-2025 NDF Corporation 鲁ICP备08005967号 Sitemap - RSSRSS订阅