📄 avrusb_ir.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 + -