[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);
    }
}
            
                      

