[ shadow-bg @ 22.07.2012. 22:14 ] @
Kako meriti duzinu impulsa sa PIC-om? Hocu da izmerim duzinu impulsa dizne za benzin na autu. Neki primer na MikroBasic ili MikroC bi bio super.
[ rsinisa @ 22.07.2012. 23:10 ] @
U PBP-u postoji komanda PULSIN, vidi da li postoji nešto takvo u Mikro proizvodima.

Drugo rešenje može da bude npr. uz pomoć TIMER1 tajmera.

Pozdrav.
Sinisha
[ bogdan.kecman @ 23.07.2012. 03:59 ] @
Citat:
shadow-bg:
Kako meriti duzinu impulsa sa PIC-om?


Koristi pic sa CCP modulom. On je idealan za merenje duzene nekog impulsa. Pogledaj datasheet za ccp imas tamo primer.

evo ga neki deo koda za P16F690 koji meri duzinu nekog impulsa ... kod je sto godina star ali bi trebalo da je jasan

Code:


#define interrupt_on() PIR1 = 0x00; PIE1 = 0x04; INTCON = 0xC0
#define interrupt_off() INTCON = 0x00;

unsigned char pokupio;
unsigned char skupljaj;

unsigned int T1;    //timer1 overflow

unsigned long T1_old;
unsigned long T1_new;

unsigned char bafer[25];

#define vd()  Vdelay_ms(100)
#define blink() Vdelay_ms(100)

void Init(){
  //init ports
  ADCON0 = 0;
  ADCON1 = 0;
  ANSEL  = 0;
  ANSELH = 0;

  TRISC = 1<<5; //RC5 is CCP1
  PORTC = 0;
  TRISB = 0;
  PORTB = 0;
  TRISA = 0;
  PORTA = 0;

  //init variables
  pokupio=0;
  skupljaj=0;
  T1 = 0;
  
  //init interrupts, timers
  CCP1CON = 0x05;   // 0000 0101 Capture mode every rising edge
  T1CON   = 0x01;   // 00 00 (prescaler 1:1) 000 1(turn on the timer1)

  T1_old  = 0;
  T1_new  = 0;
}


void main(){
  unsigned long daljina;

  Init();
  daljina = 0;
  pokupio = 0;
  while(1){
    interrupt_off(); 
    Vdelay_ms(200);
    skupljaj = 1;
    
    T1 = 0;
    T1_old = (TMR1H << 8) | TMR1L;
    T1_new = 0;
    
    ping();
    interrupt_on();
    prikazi(daljina); // ovo traje neko vreme
    interrupt_off();
    
    if (pokupio){
      pokupio = 0;

      // 8MHz crystal -> 2000000 ticks in second
      // speed of air at 20deg 340m/s
      // noTicks * 340 / 2000000 = double distance in m
      // (noTicks * 340 / 2000000)*100/2 = distance in cm
      // distance in cm = noTicks * 34 / 4000 = noTicks *17/2000

      if (T1_new < T1_old) continue;
      
      daljina = T1_new - T1_old;
      daljina *= 17;
      daljina /=2000;
    } else {
      daljina = 32000;
      //nothing();
      continue;
    }
  
  }
}

void interrupt(){
  if (PIR1 & (1<<TMR1IF)) {   // timer1 overfow
    PIR1 &= ~(1<<TMR1IF);   // clear timer1 interrupt flag
    T1++;
  }  
  if (PIR1 & (1<<CCP1IF)) { // we captured the echo
    PIR1 &= ~(1<<CCP1IF);
    if (skupljaj){ // if we were waiting for the echo
      skupljaj = 0; //we do not expect another one
      pokupio = 1;
      T1_new = (T1 << 16) | (CCPR1H << 8) | CCPR1L;  // on capture TMR1x is copied into CCPR1x
    }
  }  
}