Operácie

Meranie dĺžky impulzu 2

Z SensorWiki

Verzia z 14:06, 14. apríl 2021, ktorú vytvoril Balogh (diskusia | príspevky)

Toto je staršia verzia, ktorú sme mali na cvičeniach kedysi dávno.


Literatúra


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:

Oscillogram7.png

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]");
}