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

📄 avrusb_ir.c

📁 AVRUSBIR红外遥控器信号波形显示器
💻 C
字号:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

#include "usbdrv.h"

#ifndef uint#define uint   unsigned int#endif

#define getstata	1
#define getcount	2
#define getirdata	3
#define next_run	4

uint irdata[122];
uchar irdataindex;
uchar readindex;
uchar busy;
uchar start;
//================================================
uchar usbFunctionSetup(uchar data[8]) 
{

  uchar len = 0;
  switch(data[1])
   {
     case getstata : usbMsgPtr=&busy;
	 				 len=1;
	 				 break;
     case getcount:  usbMsgPtr=&irdataindex;
	 		         len=1;
	 				 break;
     case getirdata: readindex=0;
	                 len=0xff;
	 				 break;
     case next_run:  irdataindex=0;
					 busy=0;
					 start=1;
					 break;
     default:        break;
   }
  return len;
}
//=================================================
uchar usbFunctionRead(uchar *data, uchar len)
{
  uchar i;
  for(i=0;i<len/2;i++) //len必须是偶数
   {
     data[2*i]=(uchar)(irdata[readindex]>>8);
	 data[2*i+1]=(uchar)(irdata[readindex]);
	 readindex++;
   }
  return len;
}
//==================================================
//定时器T0初始化
void timer0_init(void)
{
	TCCR0  = 0x00;//停止定时器
	TCNT0  = 0x50;//初始值定时时间15MS
	TIMSK=TIMSK & (~(1<<TOIE0)); //禁止产生中断
	TIFR=TIFR | (1<<TOV0); //清除中断标志
	TCCR0  = 0x05;//启动定时器1024分频
}
//==================================================
//定时T1初始化
void timer1_init(void)
{
	TCCR1B = 0x00;//停止定时器
	TIMSK=TIMSK & (~((1<<TOIE1) | (1<<TICIE1)));//定时器1、输入捕捉中断禁止
	TIFR=TIFR | (1<<TOV1); //清除定时器1中断标志(溢出标志)
	TIFR=TIFR | (1<<ICF1); //清除输入捕捉中断标志
	TCNT1H = 0x00;
	TCNT1L = 0x00;//初始值,从0开始,单步时间间隔为:5.33US
	TCCR1A = 0x00;
	TCCR1B = 0x83;//启动定时器64分频,下降沿输入捕捉,输入捕捉噪音抑制
}
//==================================================
int main(void)
{
  uchar   i, j;
  unsigned int itemp;

  PORTB = 0xff;   /* activate all pull-ups */
  DDRB = 0;       /* all pins input */
  PORTD = 0xfa;   /* 1111 1010 bin: activate pull-ups except on USB lines */
  DDRD = 0x07;    /* 0000 0111 bin: all pins input except USB (-> USB reset) */
  j = 0;
  while(--j){     /* USB Reset by device only required on Watchdog Reset */
	i = 0;
	while(--i); /* delay >10ms for USB reset */
	}
  DDRD = 0x02;    /* 0000 0010 bin: remove USB reset condition */


  readindex=0;
  irdataindex=0;
  busy=0;
  start=1;
  TIFR=TIFR | (1<<TOV0); //清除中断标志
  TIFR=TIFR | (1<<TOV1); //清除定时器1中断标志(溢出标志)
  TIFR=TIFR | (1<<ICF1); //清除输入捕捉中断标志
    
  usbInit();
  sei();

  for(;;){	        /* main event loop */
    usbPoll();
//////////////////////////////////////////////////////////////////////////////////
  if(busy==0 && start==1) //启动一次IR数据捕捉
   {
     busy=1; //PC通过该变量获知是否捕捉结束
	 start=0;//PC必须将IR数据读取之后才能进行下一次的捕捉
	 timer1_init();
   }
  if(TIFR & (1<<ICF1)) //有IR信号输入,则保存边沿改变时刻,同时初始化Timer0,并且改变捕捉边沿
   {
     if(irdataindex==0) //第一次捕捉,T1从0开始
	  {
	    TCNT1H = 0x00;
	    TCNT1L = 0x00;//从0开始
		irdata[0]=0;
		irdataindex++;

	    if(TCCR1B & (1<<ICES1)) //改变捕捉边沿
	      TCCR1B=TCCR1B & (~(1<<ICES1));
        else
	      TCCR1B=TCCR1B | (1<<ICES1);
	
	    TIFR=TIFR | (1<<ICF1); //清除输入捕捉中断标志
    
	    timer0_init(); 
	  }
    else //IR信号边沿不是第一次输入
	{
     itemp=ICR1L; //保存IR信号输入边沿时刻
	 itemp=itemp | (ICR1H<<8);
	 irdata[irdataindex]=itemp;
	 irdataindex++;
     
	 if(TCCR1B & (1<<ICES1)) //改变捕捉边沿
	  TCCR1B=TCCR1B & (~(1<<ICES1));
     else
	  TCCR1B=TCCR1B | (1<<ICES1);
	
	 TIFR=TIFR | (1<<ICF1); //清除输入捕捉中断标志
    
	 timer0_init();    
    }
   }
  if(TIFR & (1<<TOV0)) //如果Timer0溢出(15MS),表示IR信号结束了
   {
     TCCR0  = 0x00;//停止定时器0
	 TIFR=TIFR | (1<<TOV0); //清除中断标志
     TCCR1B = 0x00;//停止定时器1
	 busy=0;
   }  
//////////////////////////////////////////////////////////////////////////////////
  }
  return 0;
}


⌨️ 快捷键说明

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