Advertisement
TolentinoCotesta

Input Capture Frequency measure

Oct 14th, 2020
1,733
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.62 KB | None | 0 0
  1. // Frequency timer using input capture unit
  2. // Author: Nick Gammon
  3. // Date: 31 August 2013
  4.  
  5. // Input: Pin D8
  6.  
  7. volatile boolean first;
  8. volatile boolean triggered;
  9. volatile unsigned long overflowCount;
  10. volatile unsigned long startTime;
  11. volatile unsigned long finishTime;
  12.  
  13. // timer overflows (every 65536 counts)
  14. ISR (TIMER1_OVF_vect){
  15.   overflowCount++;
  16. }  // end of TIMER1_OVF_vect
  17.  
  18. ISR (TIMER1_CAPT_vect){
  19.   // grab counter value before it changes any more
  20.   unsigned int timer1CounterValue;
  21.   timer1CounterValue = ICR1;  // see datasheet, page 117 (accessing 16-bit registers)
  22.   unsigned long overflowCopy = overflowCount;
  23.  
  24.   // if just missed an overflow
  25.   if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 0x7FFF)
  26.     overflowCopy++;
  27.  
  28.   // wait until we noticed last one
  29.   if (triggered)
  30.     return;
  31.  
  32.   if (first){
  33.     startTime = (overflowCopy << 16) + timer1CounterValue;
  34.     first = false;
  35.     return;  
  36.     }
  37.    
  38.   finishTime = (overflowCopy << 16) + timer1CounterValue;
  39.   triggered = true;
  40.   TIMSK1 = 0;    // no more interrupts for now
  41.   }  // end of TIMER1_CAPT_vect
  42.  
  43. void prepareForInterrupts(){
  44.   noInterrupts ();  // protected code
  45.   first = true;
  46.   triggered = false;  // re-arm for next time
  47.   // reset Timer 1
  48.   TCCR1A = 0;
  49.   TCCR1B = 0;
  50.  
  51.   TIFR1 = bit (ICF1) | bit (TOV1);  // clear flags so we don't get a bogus interrupt
  52.   TCNT1 = 0;          // Counter to zero
  53.   overflowCount = 0;  // Therefore no overflows yet
  54.  
  55.   // Timer 1 - counts clock pulses
  56.   TIMSK1 = bit (TOIE1) | bit (ICIE1);   // interrupt on Timer 1 overflow and input capture
  57.   // start Timer 1, no prescaler
  58.   TCCR1B =  bit (CS10) | bit (ICES1);  // plus Input Capture Edge Select (rising on D8)
  59.   interrupts ();
  60.   }  // end of prepareForInterrupts
  61.  
  62.  
  63. void setup(){
  64.   Serial.begin(115200);      
  65.   Serial.println("Frequency Counter");
  66.   // set up for interrupts
  67.   prepareForInterrupts ();
  68.  
  69.   // Just to have 2 signals with different frequency
  70.   analogWrite(6, 127);  
  71.   analogWrite(11, 127);  
  72.  
  73. } // end of setup
  74.  
  75. void loop(){
  76.   // wait till we have a reading
  77.   if (!triggered)
  78.     return;
  79.  
  80.   // period is elapsed time
  81.   unsigned long elapsedTime = finishTime - startTime;
  82.   // frequency is inverse of period, adjusted for clock period
  83.   float freq = F_CPU / float (elapsedTime);  // each tick is 62.5 ns at 16 MHz
  84.  
  85.   Serial.print ("Took: ");
  86.   Serial.print (elapsedTime);
  87.   Serial.print (" counts. ");
  88.  
  89.   Serial.print ("Frequency: ");
  90.   Serial.print (freq);
  91.   Serial.println (" Hz. ");
  92.  
  93.   // so we can read it  
  94.   delay (1000);
  95.  
  96.   prepareForInterrupts ();  
  97. }   // end of loop
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement