2025年1月8日 星期三

Arduino Timer

 Arduino Timer



計算公式:
1.定時器速度(HZ) = Arduino時鐘速度(16MHz) / 預分頻器係數
<註>定時器有Timer0,1,2
2.中斷頻率(Hz)=(Arduino時鐘速度16MHz)/ 預分頻器 *(比較匹配寄存器+ 1)
<註>就是TCNTn計數至滿溢所觸發的中斷
3.比較匹配寄存器= [16,000,000Hz /(預分頻器*所需的中斷頻率)] - 1
<註>比較匹配寄存器OCRnA,B
-----------------------------------------------------------------------------
計算原則:
Arduino UNO ATmega328例,將Timer?降低至2Hz為目標計算式:
1.ATmega328自帶的CPU frequency=16MHz=16,000,000次/秒 (1次63ns)

2.定時器種類(8bits ' 16bits)
Timner0 ,Timer2 ---->8bits計算範圍=0~255
Timer1 --------------->16bits計算範圍=0~65535

3.定時器的速度=16MHz/分頻係數  (係數種類:1,8,32,64,128,256,1024)
<註>由CS10 CS11 CS12決定

4.中斷頻率Hz=16MHz / 預分頻器*(比較匹配寄存器+ 1)
5.比較匹配寄存器OCRnA,B要存放的值
   OCRnA,B要存放值=[16MHz / 預分頻器*中斷頻率] - 1
<註>8bits OCRnA,B要存放值<256 
       16bits OCRnA,B要存放值<65536
6.想得到1Hz的中斷頻率:
   若預除頻為1024
   比較匹配寄存器的值=[16,000,000/(1024*1)] -1=15,624
   256 < 15,624 < 65536 所要選Timer1 16位元的計數器










void setup(){
  cli();//關閉中斷服務函式
  //設置Timer0為10kHz(100us)
  TCCR0A = 0;//TCCR0A暫存器歸0
  TCCR0B = 0;//TCCR0B暫存器歸0
  TCNT0  = 0;//將計數器值初始化為0
  //設置Timer0為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(){
  
}

沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。