|
以经过调试可选8mhz/4mhz工作占用1timer,1interrupt
不足之处请指教
------------IR.H--------------------------
#ifndef IR
#define IR
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#define MockIR //使用遥控模仿定义他
#define InceptCustomCode_IR 0 //接收用户码//DVD/VCD:00
#define SendtCustomCode_IR 0 //发送用户码//DVD/VCD:00
#define FirstKeyHoldEventCyc 15
#define SecondKeyHoldEventCyc 1
#define SendHighState_IR 0 //红外发射状态
//发送引脚定义
#define SendPinP_IR PIND
#define SendPin_IR PIND2
#define SendDDR_IR DDRD
#define SendDDD_IR DDD2
#define SendPORT_IR PORTD
#define SendP_IR PD2
//#define SendPin_IR PORTD&(1<<PIND2) //发送引脚定义
#define InceptPin_IR PIND&(1<<PIND2) //接收引脚定义
#define IREXInterrupt SIGNAL(SIG_INTERRUPT0)//定义使用的外部中断(与接收引脚相关)SIGNAL
#define IRTimerInterrupt SIGNAL(SIG_OVERFLOW0)//定义使用定时器INTERRUPT
#ifndef InIRDevice
#ifdef MockIR
extern bool volatile SendMode_IR; //true = 发送模式;当发送结束后自动清0。
extern uchar volatile SendKey_IR; //须发送的码值
extern void SendKeyIR(); //开始发送
#endif
#define GetKey_IR DATA_IR[2] //获取按键码
extern void IniIR(); //初始化IR
//extern uchar GetKey_IR(); //获取按键码
extern bool volatile KeyDown_IR; //分别表示按键的按下状态
extern bool volatile KeyHoldEvent; //当按键按住“KeyHoldEventCyc”个周期(110ms)后被置一,须手动清零;发生于FirstKeyHoldEvent后。
extern bool volatile FirstKeyHoldEvent; //KeyHoldEvent是表示当按键按住过程第一次发生,自动清零
extern bool volatile KeyHold_IR; //当FirstKeyHoldEvent置一时置一,一直到下一次检测的新的按键码输入时自动清零
extern uchar volatile State_IR;
extern uchar volatile DATA_IR[4]; //接收数据储蓄区
#endif
#endif
-------------IR.C---------------
#include "global.h"
#include "display.h"
#include "ir.h"
#define CountSpeed 4 //4MHZ//64us每周期
#define DoubleSpeed DF_CPU/4000000ul
#define CountStop 0
#define Idle_IR 0 //空闲 高电平
#define LeaderL_IR 1 //导入信号 低电平
#define LeaderH_IR 2 //导入信号 高电平
#define CustomCode_IR 3 //开始接收自定义字节
#define Incept_IR 4 //数据接收中
#define KeyDowning_IR 5 //检测到按键按住信号
#define CodeH_IR 6 //数据高电平期间//参照PT2222.pdf
#define CodeL_IR 7 //数据低电平期间
uchar volatile State_IR=Idle_IR; //当前接收状态
uchar volatile DATA_IR[4]; //接收数据储蓄区
uchar volatile KeyHoldEventCyc = FirstKeyHoldEventCyc;
uchar volatile keyHoldCount = 0;
bool volatile KeyDown_IR; //表示按键的按下状态
bool volatile KeyHold_IR; //当FirstKeyHoldEvent置一时置一,一直到下一次检测的新的按键码输入时自动清零
bool volatile KeyHoldEvent; //当按键按住“KeyHoldEventCyc”个周期(110ms)后被置一,须手动清零
bool volatile FirstKeyHoldEvent; //KeyHoldEvent是表示当按键按住过程第一次发生,自动清零
static uchar volatile InceptBitCount; //已经收到的(以发送的)比特数
static uchar volatile hold_tmp; //临时数据用于解决timer无法计时超过110ms问题
static bool volatile DAT_bit_IR; //用于判断当前比特的0/1状态?
#ifdef MockIR
bool volatile SendMode_IR; //true = 发送模式;当发送结束后自动清0。
uchar volatile SendKey_IR; //须发送的码值
//static uchar SendBitCount; //以发送的Bit数
static uchar volatile sendTmp;
void static reversalIRPIN()
{
if(SendPORT_IR&(1<<SendP_IR))
SendPORT_IR&= ~(1<<SendP_IR);//输出低电平
else
SendPORT_IR|= (1<<SendP_IR);//输出高电平
}
void SendKeyIR() //开始发送
{
if(SendMode_IR)
return;
SendMode_IR = true;
GICR &= ~(1<<INT0);//关外部中断0
SendPORT_IR|= (1<<SendP_IR);//输出高电平
SendDDR_IR |= (1<<SendDDD_IR);//配置为输出
reversalIRPIN();//反转输出电平
TCNT0 =256-35*DoubleSpeed;//延时9ms
TCCR0 = 5;
State_IR = LeaderL_IR;
}
#endif
/*uchar GetKey_IR() //获取按下按键的码值
{
//KeyDown_IR = false;
return DATA_IR[2];
}*/
void IniIR() //初始化接收
{
DDRD &=~(1<<DDD2); //使能上拉电阻
PORTD |= (1<<PD2); //使能上拉电阻
MCUCR |= (1<<ISC01);
MCUCR &=~(1<<ISC00);//下降沿有效
GICR |= (1<<INT0); //开外部中断0
TIMSK |= (1<<TOIE0);//开定时器中断
//TCCR0 = CountSpeed;//4MHZ//64us每周期
}
IRTimerInterrupt
{
uchar tmp;
TCCR0 = CountStop; //停计数
#ifdef MockIR
if(SendMode_IR)
{
switch (State_IR)
{
case LeaderL_IR:
{
reversalIRPIN();//反转输出电平 //15周期
TCNT0 =256-70*DoubleSpeed;//延时4.5ms//64us
TCCR0 = CountSpeed;
State_IR = LeaderH_IR;
break;
}
case LeaderH_IR:
{
reversalIRPIN();//反转输出电平 //13周期
TCNT0 =256-9*DoubleSpeed;//延时0.56ms//64us//可能需用8
TCCR0 = CountSpeed;
State_IR = CodeH_IR;
sendTmp = SendtCustomCode_IR;
InceptBitCount = 0;
break;
}
case CodeH_IR:
{
if(InceptBitCount==32)
{
State_IR = Idle_IR;
SendMode_IR = 0;
SendPORT_IR|= (1<<SendP_IR);//输出高电平
IniIR(); //初始化接收
return;
}
reversalIRPIN(); //反转输出电平 //16周期
if(sendTmp&0x01)
{
TCNT0 =256-26*DoubleSpeed; //延时1.69ms//64us
TCCR0 = CountSpeed;
}
else
{
TCNT0 =256-9*DoubleSpeed; //延时0.565ms//64us////可能需用8
TCCR0 = CountSpeed;
}
InceptBitCount++;
sendTmp = sendTmp>>1;
if(!(InceptBitCount%8))
{
switch (InceptBitCount/8)
{
case 1:
{
sendTmp = ~SendtCustomCode_IR;break;
}
case 2:
{
sendTmp = SendKey_IR;break;
}
case 3:
{
sendTmp = ~SendKey_IR;break;
}
}
}
State_IR = CodeL_IR;
break;
}
case CodeL_IR:
{
reversalIRPIN(); //反转输出电平 //12周期
TCNT0 =256-9*DoubleSpeed; //延时0.56ms//64us//可能需用8
TCCR0 = CountSpeed;
State_IR = CodeH_IR;
break;
}
}
return;
}
#endif
switch (State_IR)
{
case LeaderL_IR:
{
//PIND&(1<<PIND2)
tmp = PIND;
if(!(tmp&(1<<PIND2)))
{
State_IR = LeaderH_IR;
TCNT0 =256-70*DoubleSpeed; //延时4.5ms//64us
TCCR0 = CountSpeed;
}
else
{
State_IR = Idle_IR;
}
break;
}
case LeaderH_IR:
{
tmp = PIND;
if(tmp&(1<<PIND2))
{
State_IR = CustomCode_IR;
}
else
{
State_IR = Idle_IR;
}
KeyHold_IR = 0;
break;
}
case Incept_IR:
{
if(DAT_bit_IR) //如果等待4.5ms后EX1仍未清'DAT_bit_IR',则退出接收状态
{
State_IR = Idle_IR;
//ShowNumberEX2(0,GetKey_IR); // 低位位置,数据
break;
}
TCNT0 =256-70*DoubleSpeed; //延时4.5ms//64us
TCCR0 = CountSpeed;
DAT_bit_IR = 1;
break;
}
case KeyDowning_IR:
{
if(hold_tmp>1+1*DoubleSpeed)
{
KeyDown_IR = 0;
//KeyHold_IR = 0;
keyHoldCount = 0;
State_IR = Idle_IR;
break;
}
hold_tmp++;
TCNT0 =256-215; //延时55ms//256us//延时110ms清除'KeyDown_IR'
TCCR0 = 5; //1024
break;
}
}
}
IREXInterrupt
{
uchar bytec,tmp;
switch (State_IR)
{
case KeyDowning_IR:
{}
case Idle_IR:
{
State_IR = LeaderL_IR;
TCNT0 =256-117*DoubleSpeed; //延时7.5ms//64us
TCCR0 = CountSpeed;
return;
}
case LeaderH_IR: //按住信号(9ms导入脉冲后4.5ms内再次发生中断)
{
keyHoldCount++;
if(keyHoldCount>KeyHoldEventCyc)
{
keyHoldCount = 0;
KeyHoldEvent = 1;
if(KeyHoldEventCyc == FirstKeyHoldEventCyc)
{
KeyHold_IR = 1;
FirstKeyHoldEvent = 1;
KeyHoldEventCyc = SecondKeyHoldEventCyc;
}
else
{
FirstKeyHoldEvent = 0;
}
}
State_IR = KeyDowning_IR;
hold_tmp = 0;
TCNT0 =256-215; //延时55ms//256us//延时110ms清除'KeyDown_IR'
TCCR0 = 5; //1024
break;
}
case CustomCode_IR:
{
DAT_bit_IR = 0;
InceptBitCount = 0;
State_IR = Incept_IR;
TCNT0 =256-23*DoubleSpeed; //延时1.5ms//64us
TCCR0 = CountSpeed;
break;
}
case Incept_IR:
{
TCNT0 =256-23*DoubleSpeed; //延时1.5ms//64us
TCCR0 = CountSpeed;
bytec = InceptBitCount/8;
tmp = DATA_IR[bytec]>>1;
if(DAT_bit_IR)
tmp |= 0x80;
DAT_bit_IR = 0; //清零等待如果是'1'timer1将会将其置位
DATA_IR[bytec] = tmp;
if(InceptBitCount==31)
{
uchar aa = DATA_IR[0];
uchar bb = ~DATA_IR[1];
uchar cc = DATA_IR[2];
uchar dd = ~DATA_IR[3];
if((aa == bb)&&(cc == dd)&&(aa==InceptCustomCode_IR))
{
State_IR = KeyDowning_IR;
KeyDown_IR = true;
//ShowNumberEX2(0,GetKey_IR); // 低位位置,数据]
}
else
{
State_IR = Idle_IR;
break;
}
keyHoldCount = 0;
hold_tmp = 0;
KeyHoldEventCyc = FirstKeyHoldEventCyc;
TCNT0 =256-215; //延时55ms//256us//延时110ms清除'KeyDown_IR'
TCCR0 = 5; //1024
}
InceptBitCount++;
break;
}
}
} |
|