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