⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 f_13_24_irdet_biphase.c

📁 * Use 10 MHz crystal frequency. * Use Timer0 for ten millisecond looptime. * Blink "Alive" LED e
💻 C
字号:
#include "config.h"
#include "serial.c"
#include "serio.c"
#include "i2cmsu.c"


// decodes IR signal using Timer1 and CCP capture capability 
// uses  biphase mode

//prototypes
void do_ircap(void);
void reset_ir(void);

volatile unsigned int last_capture, this_capture;
volatile unsigned long delta;
volatile unsigned char tmr1_ov;  // timer 1 overflow cnt
#define MAXBYTES 8
volatile unsigned char cbuff[MAXBYTES];
volatile unsigned char bitcount, bytecount,bit_edge;
volatile unsigned char state,edge_capture,current_bit;
volatile unsigned char this_byte;

void do_ircap(void);

#define IDLE_TIME 4
#define BITCHANGE   10000
#define IDLE         0
#define START_PULSE  1
#define BIT_CAPTURE  2
#define IO_FINISH    3

#if defined(HI_TECH_C)
void interrupt timer_isr(void)
#endif
#if defined(__18CXX)
#pragma interrupt timer_isr
void timer_isr(void)
#endif
{
  if (TMR1IF) {
    tmr1_ov++;  // increment timer1 overflow
  }
  if (CCP1IF) {
    this_capture = CCPR1;
    if (!tmr1_ov) { 
      // no overflow at all
      delta = this_capture - last_capture ;
    } else {
      delta = tmr1_ov-1;
      delta = (delta << 16);
      last_capture = 0 - last_capture; 
      delta = delta + last_capture;
      delta = delta + this_capture;
    }
    last_capture = this_capture;
    tmr1_ov = 0;  // clear timer 1 overflow count
    if (CCP1CON & 0x01)  {
      CCP1CON = 0x0; //reset first
      CCP1CON = 0x4; //falling edge
    }
    else {
      CCP1CON = 0x0; //reset first 
      CCP1CON = 0x5; // rising edge
    }
    edge_capture = 1;
  }
  do_ircap();
}

// decode IR biphase
void do_ircap(void){
  TMR1IF = 0; CCP1IF = 0; 
  switch (state) {
  case IDLE: 
    // wait for line to become idle
    if (tmr1_ov > IDLE_TIME){
      tmr1_ov = 0;
      state = START_PULSE;
      edge_capture = 0;
    }
   break;
  case START_PULSE: 
    if (edge_capture) { // wait for edge
      edge_capture = 0;
      bit_edge = 0;
      state = BIT_CAPTURE;
    }
   break;
  case BIT_CAPTURE: 
    // wait for edge or idle condition
    if (tmr1_ov > 1) { // finished
      // disable capture,timer1 interrupts
      CCP1IE = 0; TMR1IE = 0; TMR1ON = 0;  
      state = IO_FINISH;
    } else if (edge_capture) {
      edge_capture = 0;
      //accumulating bits, MSB to LSB
      if ((delta > BITCHANGE) || bit_edge) {
	if (delta > BITCHANGE) {
	  // toggle current bit if wide pulse
	  current_bit = ~current_bit;
	}
	if (current_bit) this_byte = this_byte | 0x01; //set LSbit
	bitcount++;
	bit_edge = 0; // next edge is not a bit
	if (bitcount == 8) {
	  bitcount = 0;
	  cbuff[bytecount] = this_byte;
	  bytecount++;
	  this_byte = 0;
	} else{
	  this_byte = this_byte << 1;
	}
      } else if (!bit_edge)
                 bit_edge = 1;
    }
   break;
  }//end switch
}// end do_ircap()

void reset_ir(void) {
    state = IDLE;    // look for idle
    CCP1CON = 0;  // turn off when changing modes
    CCP1CON = 0x4; // capture every falling edge 
    current_bit = ~(0);
    bitcount = 0; bytecount = 0;
    tmr1_ov = 0;  // clear timer 1 overflow count
    last_capture = 0;
    // enable capture and timer1 interrupts
    CCP1IF = 0; CCP1IE = 1; 
    TMR1IF = 0; TMR1IE = 1; TMR1ON = 1; 
}
      
unsigned char i, t_bytecount, t_bitcount, t_this_byte, cnt;
unsigned char  tbuff[MAXBYTES]; 

void main(void){
  serial_init(95,1); // 19200 in HSPLL mode, crystal = 7.3728 MHz 
  // initialize timer 1, prescale by 1, internal clock
  T1CKPS1 = 0; T1CKPS0 = 0; T1OSCEN = 0; TMR1CS = 0;  
  // set CCP1 as input, 
  bitset(TRISC,2);
  IPEN = 0; PEIE = 1;  GIE = 1;  
  cnt = 0;
  reset_ir();
  pcrlf(); printf("Ready for capture\n");  pcrlf();
  while(1) {
    // wait for IR data to arrive
    while (state != IO_FINISH);
    // copy interrupt data to safe place
    t_bytecount = bytecount;
    t_bitcount = bitcount;
    t_this_byte = this_byte;
    for (i = 0;i < t_bytecount;i++) {
      tbuff[i] = cbuff[i];
      cbuff[i] = 0;
    }
    reset_ir();
    // print out last captured data
    if (t_bitcount != 0) {
      // adjust last byte assuming input bits are zero
      for (i=t_bitcount; i < 7; i++) t_this_byte = t_this_byte << 1;
      tbuff[t_bytecount] = t_this_byte;
      t_bytecount++;
    }
    printf("(%d): Received %d bytes, %d bits.",
	   cnt,t_bytecount, t_bitcount); pcrlf();
    for (i = 0;i < t_bytecount;i++) {
    printf("  Byte RX: %x", tbuff[i]);pcrlf();
    }
    cnt++;
  }
}

//for MCC18, place the interrupt vector goto
#if defined(__18CXX)
#if defined(HIGH_INTERRUPT)
#pragma code HighVector=HIGH_INTERRUPT
#else
#pragma code HighVector=0x0008  
#endif
void HighVector (void)
{
    _asm goto timer_isr _endasm
}
#pragma code
#endif



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -