[IR.c]
#include <iom16v.h>
#include <macros.h>
#include "delay.h"
#include "UART.h"
#include "IR.h"
unsigned int hightime,lowtime;
unsigned char tlow;
unsigned char IRCode[4];
unsigned char IRDataBuffer[8];
unsigned int IRDataLength=0;
unsigned int IRStrID=0;
void IR_Init(void)
{
SEI();
IR_INT_ON;
IR_OFF;
MCUCR=0x02; //外中断0下降沿触发
TCCR1A=0x00;
TCCR1B=0x02; //定时器1设为8分频,也就相当于51单片机接12M晶振
}
//键码引导码
void IR_KeyCodeBegin(void)
{
IR_ON;
delay(9); //9ms高电平
IR_OFF;
delay(4); //4.5ms低电平
delay500us();
}
//数据引导码
void IR_DataBegin(void)
{
IR_ON;
delay(3);
IR_OFF;
delay(1);
}
//发送0
void IR_Send0(void)
{
IR_ON;
delay560us();
IR_OFF;
delay560us();
}
//发送1
void IR_Send1(void)
{
IR_ON;
delay560us();
IR_OFF;
delay560us();
delay560us();
delay560us();
}
//发送尾码,使接收端能确定最后一位是0还是1
void IR_Stop(void)
{
IR_ON;
delay560us();
IR_OFF;
}
//发送一个字节
void IR_SendByte(unsigned char Data)
{
unsigned char i;
for (i=0;i<8;i++)
{
if (Data&BIT(i))
IR_Send1();
else
IR_Send0();
}
}
//发送一个字符串
void IR_SendString(char* pStr)
{
unsigned int i;
unsigned int len=0;
char* tp=pStr;
while (*tp!='\0')
{
len++;
tp++;
}
IR_DataBegin();
IR_SendByte(len%256);
IR_SendByte(len/256);
for (i=0;*pStr!='\0';i++)
{
if (i>5 && i%8==0)
{
IR_Stop();
delay(108);
IR_DataBegin();
}
IR_SendByte(*pStr);
pStr++;
}
IR_Stop();
}
//★发送一个完整的按键码
//usercode为用户码,16位
//keycode为键码,8位
void IR_SendKeyCode(unsigned int usercode, unsigned char keycode)
{
IR_KeyCodeBegin();
IR_SendByte(usercode/256); //用户码高8位
IR_SendByte(usercode%256); //用户码低8位
IR_SendByte(keycode); //键码
IR_SendByte(~keycode); //键码的反码
IR_Stop(); //使接收端能区分最后一位是1还是0
}
void IR_PressKey(unsigned char keycode)
{
IR_SendKeyCode(IR_USERCODE,keycode);
}
//红外接收中断
void IR_Receive(void)
{
unsigned char tmp;
unsigned char flag=0x00;
IR_INT_OFF;
IR_ReceiveBegin();
if (lowtime>2650 && lowtime<3350 && hightime>650 && hightime<1350)
{
//红外数据接收
if (IRStrID==0)
{
IR_ReceiveByte(&tmp);
IRDataLength=tmp;
IR_ReceiveByte(&tmp);
IRDataLength+=tmp*256;
flag|=BIT(7);
}
for (tmp=0;tmp<8;tmp++)
{
IR_ReceiveByte(&IRDataBuffer[tmp]);
IRStrID++;
if (IRStrID>=IRDataLength)
{
IRStrID=0;
flag|=BIT(6);
break;
}
}
//在108ms的间隔时间中趁机把数据发给电脑
if (flag&BIT(7))
{
//起始码
UART_Send(0x40);
UART_Send(0xf5);
UART_Send(IRDataLength/256);
UART_Send(IRDataLength%256);
}
for (tmp=0;tmp<8;tmp++)
UART_Send(IRDataBuffer[tmp]);
if (flag&BIT(6))
{
//终止码
UART_Send('E');
UART_Send(0x00);
}
}
else if (lowtime>9200 && lowtime<9500 && hightime>4600 && hightime<4900)
{
//红外遥控解码
IR_ReceiveByte(&IRCode[0]);
IR_ReceiveByte(&IRCode[1]);
IR_ReceiveByte(&IRCode[2]);
IR_ReceiveByte(&IRCode[3]);
UART_Send(0x40);
UART_Send(0xf1); //finish
UART_Send(IRCode[0]);
UART_Send(IRCode[1]);
UART_Send(IRCode[2]);
UART_Send(IRCode[3]);
}
else
{
//UART_Send(0x40);
//UART_Send(0x4f);
}
IR_INT_ON;
}
void IR_ReceiveBegin(void)
{
TCNT1H=0x00;
TCNT1L=0x00;
while (!IR); //给低电平计时
tlow=TCNT1L;
lowtime=TCNT1H;
lowtime=lowtime*256+tlow;
IR_CLEAR_TIMER; //定时器1清除标志位,注意是写1清零
TCNT1H=0x00;
TCNT1L=0x00;
while (IR && !IR_TIMER_OUT); //给高电平计时
tlow=TCNT1L;
hightime=TCNT1H*256+tlow;
IR_CLEAR_TIMER;
}
void IR_ReceiveByte(unsigned char* Data)
{
unsigned char i;
for (i=0;i<8;i++)
{
TCNT1H=0x00;
TCNT1L=0x00;
while (!IR); //给低电平计时
tlow=TCNT1L;
lowtime=TCNT1H;
lowtime=lowtime*256+tlow;
IR_CLEAR_TIMER;
TCNT1H=0x00;
TCNT1L=0x00;
while (IR && !IR_TIMER_OUT); //给高电平计时
tlow=TCNT1L;
hightime=TCNT1H*256+tlow;
IR_CLEAR_TIMER;
if (hightime>1150)
*Data|=BIT(i);
else
*Data&=~BIT(i);
}
}