Meranie dĺžky impulzu 3
Zo stránky SensorWiki
Toto je staršia verzia, ktorú sme mali na cvičeniach kedysi dávno.
Literatúra
- AVR130: Setup and Use the AVR® Timers. Aplication Note, Atmel Corporation 2002.
+ software download - AVR135: Using Timer Capture to Measure PWM Duty Cycle. Aplication Note, Atmel Corporation 2005.
+ software download
Príklad (avrdemo7.hex)
Na vstupe ICP1 (na doske Acrob D8, na čipe ATmega328P je to PB0, pin 14) máme pripojený zdroj externého kmitočtu cca 1Hz:
Nastavené máme spúšťanie ICR dobežnou hranou, počítadlo počíta 16 MHz:1024, vypisujeme niekoľkokrát za sekundu stavy všetkých registrov
Input D8 = 1 TCNT1 = 353 ICR = 0
Input D8 = 1 TCNT1 = 1543 ICR = 0
Input D8 = 1 TCNT1 = 2749 ICR = 0
Input D8 = 1 TCNT1 = 3956 ICR = 0
Input D8 = 1 TCNT1 = 5163 ICR = 0
Input D8 = 0 TCNT1 = 6369 ICR = 6070 D = 6070 T = 388.4800 ms
Input D8 = 0 TCNT1 = 7706 ICR = 6070
Input D8 = 0 TCNT1 = 8961 ICR = 6070
Input D8 = 0 TCNT1 = 10216 ICR = 6070
Input D8 = 0 TCNT1 = 11488 ICR = 6070
Input D8 = 0 TCNT1 = 12759 ICR = 6070
Input D8 = 1 TCNT1 = 14031 ICR = 6070
Input D8 = 1 TCNT1 = 15303 ICR = 6070
Input D8 = 1 TCNT1 = 16574 ICR = 6070
Input D8 = 1 TCNT1 = 17846 ICR = 6070
Input D8 = 1 TCNT1 = 19117 ICR = 6070
Input D8 = 1 TCNT1 = 20389 ICR = 6070
Input D8 = 1 TCNT1 = 21661 ICR = 21591 D = 15521 T = 993.3441 ms
Input D8 = 0 TCNT1 = 23046 ICR = 21591
Input D8 = 0 TCNT1 = 24334 ICR = 21591
Input D8 = 0 TCNT1 = 25622 ICR = 21591
Input D8 = 0 TCNT1 = 26910 ICR = 21591
Input D8 = 0 TCNT1 = 28197 ICR = 21591
Input D8 = 1 TCNT1 = 29485 ICR = 21591
Input D8 = 1 TCNT1 = 30773 ICR = 21591
Input D8 = 1 TCNT1 = 32061 ICR = 21591
Input D8 = 1 TCNT1 = 33349 ICR = 21591
Input D8 = 1 TCNT1 = 34636 ICR = 21591
Input D8 = 1 TCNT1 = 35924 ICR = 21591
Input D8 = 1 TCNT1 = 37212 ICR = 37110 D = 15519 T = 993.2161 ms
Input D8 = 0 TCNT1 = 38597 ICR = 37110
Input D8 = 0 TCNT1 = 39885 ICR = 37110
Input D8 = 0 TCNT1 = 41173 ICR = 37110
Input D8 = 0 TCNT1 = 42461 ICR = 37110
Input D8 = 0 TCNT1 = 43749 ICR = 37110
Input D8 = 1 TCNT1 = 45037 ICR = 37110
Input D8 = 1 TCNT1 = 46324 ICR = 37110
Input D8 = 1 TCNT1 = 47612 ICR = 37110
Input D8 = 1 TCNT1 = 48900 ICR = 37110
Input D8 = 1 TCNT1 = 50188 ICR = 37110
Input D8 = 1 TCNT1 = 51476 ICR = 37110
Input D8 = 1 TCNT1 = 52763 ICR = 52630 D = 15520 T = 993.2800
Input D8 = 0 TCNT1 = 54149 ICR = 52630
Input D8 = 0 TCNT1 = 55437 ICR = 52630
Input D8 = 0 TCNT1 = 56724 ICR = 52630
Input D8 = 0 TCNT1 = 58012 ICR = 52630
Input D8 = 0 TCNT1 = 59300 ICR = 52630
Input D8 = 1 TCNT1 = 60588 ICR = 52630
Input D8 = 1 TCNT1 = 61876 ICR = 52630
Input D8 = 1 TCNT1 = 63163 ICR = 52630
Input D8 = 1 TCNT1 = 64451 ICR = 52630
Input D8 = 1 TCNT1 = 203 ICR = 52630
Input D8 = 1 TCNT1 = 1458 ICR = 52630
Input D8 = 1 TCNT1 = 2730 ICR = 2619 D = 15525 T = 993.6000
Input D8 = 0 TCNT1 = 4083 ICR = 2619
Ak chceme merať aj striedu, musíme meranie realizovať s prerušením a v obsluhe prerušenia preklopiť konfiguračný bit, ktorý rozhoduje o prepise TCNT do ICR registra. Je to bit ICES1, ktorý je v TCCR1B.6.
#include <avr/interrupt.h>
volatile int newTick = 0; // The variable for interrupt should be declared as a volatile one!
ISR(TIMER1_CAPT_vect) // Timer 1 Capture Interrupt Service Routine
{
TCCR1B = ?? // toggle Edge Select bit
newTick = ICR1;
};
main()
{
DDRB = ?? // Set ICR - Port B, pin0 as INPUT
TCCR1B = ?? // T1 clk = F_CPU : 1024, falling edge pin ICP1,
TCCR1A = ?? // T1 in timer mode !! Note: if You omit this, TCNT1 will be only 8-bit !!
TCNT1 = 0x0000; // initialize the counter (16-bit! Low+High bytes)
TIFR1 = ?? // (1<<ICF1); if a 1 is written to a ICF1 bit
// - the ICF1 bit will be cleared
TIMSK1 = ?? // Enable ICR interrupt
sei(); // Enable ALL interrupts
.... // TODO: display measured value somewhere
}
Ukážka pre Arduino využíva zabudovaný príkaz PulseIn:
#define SWITCH 8 // select the pin for Switch
unsigned long duration;
void setup()
{
pinMode(SWITCH, INPUT); // this pin is an INPUT
Serial.begin(9600);
Serial.println("PulsIn test:");
}
void loop() // endless loop
{
duration = pulseIn(SWITCH, HIGH);
Serial.print(" T1 = ");
Serial.print(duration,DEC);
Serial.print(" [us]");
duration = pulseIn(SWITCH, LOW);
Serial.print(" T0 = ");
Serial.print(duration,DEC);
Serial.println(" [us]");
}