📄 ir_6121.c
字号:
/**********************************************************************************************
*
* 红外线遥控接收检测控制程序 V1.0
*
* 红外线接收检测用的子程序
*
* 文件名 : IR_KEY.C
* 设计者 : 李东荣(EMAIL:JDLDR@21CN.COM,QQ:20475125)
************************************************************************************************
* 功 能 描 述
*
* 1. 红外接收头必需接在外部中断的引脚上
* 2. 该程序需要占用一个计数器
************************************************************************************************/
/***********************************************************************************************
硬件配置
************************************************************************************************/
#define IR_T 0 //使用使用计时器号;0=使用计时器0;1=计时器1
sbit IR_IN = 0xB4; //红外线输入引脚地址
/***********************************************************************************************
软件配置
************************************************************************************************/
#define IR_USESCAN 1 //是否启用用户码扫描
#define IR_USENO 0x00 //用户码
#define IR_FOSC 11059200 //CPU FOSC
/***********************************************************************************************
参数设置
************************************************************************************************/
sbit IR_EA = 0xAF; //总中断开关
//****************************设置使用计数器地址*******************************//
sfr IR_TMOD = 0x89; //定时器工作方式寄存器
#if IR_T==0 //使用计数器0
#define IR_TINT 1 //设置计数器中断源
sfr IR_TL = 0x8A; //设置使用计数器低8位位置
sfr IR_TH = 0x8C; //设置使用计数器高8位位置
sbit IR_TR = 0x8C; //计数启动开样地址
sbit IR_ET = 0xA9; //计时器中断许可位
sbit IR_TF = 0x8D; //计时器中断溢出位
#endif
#if (IR_T==1) //使用计数器1
#define IR_TINT 3 //设置计数器中断源
sfr IR_TL = 0x8B; //设置使用计数器低8位位置
sfr IR_TH = 0x8D; //设置使用计数器高8位位置
sbit IR_TR = 0x8E; //计数启动开样地址
sbit IR_ET = 0xAB; //计时器中断许可位
sbit IR_TF = 0x8F; //计时器中断溢出位
#endif
//****************************设置时时间相关*******************************//
#if (IR_FOSC==12000000)
#define IR_Start_Time 9000 //同步头长度(单位为机器周期)
#define IR_Exp_Time 2500 //连发高电平的长度
#define IR_New_Time 4500 //为新代码的时高电平长度
#define IR_C0_Time 1120 //为0电平时的时时间长度
#define IR_C1_Time 2250 //为1电平时的时间长度
#define IR_Warp_Time 500 //偏差的最大时间长度
#define IR_RSTOUT 10 //
#endif
#if (IR_FOSC==11059200)
#define IR_Start_Time 8294 //同步头长度(单位为机器周期)
#define IR_Exp_Time 2304 //连发高电平的长度
#define IR_New_Time 4147 //为新代码的时高电平长度
#define IR_C0_Time 1032 //为0电平时的时时间长度
#define IR_C1_Time 2073 //为1电平时的时间长度
#define IR_Warp_Time 460 //偏差的最大时间长度
#define IR_RSTOUT 10 //
#endif
/***********************************************************************************************
IRKEY全局变量声明
************************************************************************************************/
unsigned char IR_RSTNUM;
//****************************按键定义部份*******************************//
/***********************************************************************************************
函数名称: IRKEY 计数器加载子程序
函数原型: void IRKEY_SETT(unsigned int TS,bit ET)
函数功能: 初始化计数器的数值
输入参数: TH :加载到计数器的高8位值
TL :加载到计数器的低8位值
ET :计数器溢出时是否进入中断程序
返回参数: 无
创建日期: 2008年4月10日
修改日期:
有关说明:
编写作者: 李东荣(EMAIL:JDLDR@21CN.COM,QQ:20475125)
************************************************************************************************/
void IR_SETT(unsigned int TS)
{unsigned char TH,TL;
unsigned int TempTS;
IR_TR=0; //停止计数
IR_ET=0; //设置是否中断
TempTS=TS;
TempTS>>=8;
TH=(int)(TempTS);
TL=(int)(TS&0x00FF);
IR_TH=TH; //加载高8位数值
IR_TL=TL; //加载低8位数值
IR_TR=1; //开始计数
}
/***********************************************************************************************
函数名称: IRKEY 读取计数器子程序
函数原型: unsigned int IRKEY_ReadT(void)
函数功能: 初始化计数器的数值
输入参数: TH :加载到计数器的高8位值
TL :加载到计数器的低8位值
ET :计数器溢出时是否进入中断程序
返回参数: 无
创建日期: 2008年4月10日
修改日期:
有关说明:
编写作者: 李东荣(EMAIL:JDLDR@21CN.COM,QQ:20475125)
************************************************************************************************/
unsigned int IR_ReadT(void)
{
unsigned int TimeT;
IR_TR=0;
TimeT=IR_TH;
TimeT<<=8;
TimeT=TimeT|IR_TL;
return(TimeT);
}
/***********************************************************************************************
函数名称: IRKEY启动设置
函数原型: void IRKEY_Start(void)
函数功能: 初始化及启动IR及KEY的设置
输入参数: 无
返回参数: 无
创建日期: 2008年4月10日
修改日期:
有关说明:
编写作者: 李东荣(EMAIL:JDLDR@21CN.COM,QQ:20475125)
************************************************************************************************/
unsigned char IR_Scan(void)
{
unsigned int Time_Width; //脉冲宽度
unsigned char IR_Scan[4]={0xFF,0xFF,0xFF,0xFF}; //存储红外编码用
unsigned char Index1,Index2,TMODT; //用于计数器
IR_EA=0; //关中断
if (!IR_IN)
{
//****************************设置计数器计数方式*******************************//
//设置计数器计数方式为方式1
IR_TR=0;
IR_TF=0;
#if (IR_T==0) //使用计数器0时
TMODT=IR_TMOD;
TMODT=TMODT&0xF0;
TMODT=TMODT|0x01;
IR_TMOD=TMODT;
#endif
#if (IR_T==1) //使用计数器1时
TMODT=IR_TMOD;
TMODT=TMODT&0x0F;
TMODT=TMODT|0x10;
IR_TMOD=TMODT;
#endif
//********************************************************************************************
// 检测同步头(9ms)
//********************************************************************************************
IR_SETT(0xFFFF-IR_Start_Time-IR_Warp_Time); //设置计数为计数初值 9ms+偏差值
while ((!IR_IN)&&(!IR_TF));
//Time_Width=IR_ReadT()-(0xFFFF-IR_Start_Time-IR_Warp_Time);
//********************************************************************************************
// 区分 连发代码 与 新代码
//********************************************************************************************
IR_SETT(0xFFFF-IR_New_Time-IR_Warp_Time); //设置计数为计数初值 4.5ms+偏差值
while ((IR_IN)&&(!IR_TF));
Time_Width=IR_ReadT()-(0xFFFF-IR_New_Time-IR_Warp_Time);
//********************************************************************************************
// 连发代码处理子程序
//********************************************************************************************
if ((Time_Width<(IR_Exp_Time+IR_Warp_Time))&&(Time_Width>(IR_Exp_Time-IR_Warp_Time))) //在如高脉冲长约为2.5ms,则为重复按键已按下
{
//发出重复命令
IR_RSTNUM++;
if (IR_RSTNUM>IR_RSTOUT) {
IR_Scan[2]=0xFE;
IR_RSTNUM=0;}
}
//********************************************************************************************
// 新代码处理子程序
//********************************************************************************************
if ((Time_Width<(IR_New_Time+IR_Warp_Time))&&(Time_Width>(IR_New_Time-IR_Warp_Time))) //在如高脉冲长约为4.5ms,则为新按键按下
{
//检测新的按键码
for(Index1=0;Index1<4;Index1++) //检测四个用户码
{
for(Index2=0;Index2<8;Index2++)
{
IR_SETT(0xFFFF-IR_C1_Time-IR_Warp_Time); //延时2.75ms
while((!IR_IN)&&(!IR_TF));
if (IR_TF) goto IR_SCAN_ERR; //如果超时测退出
while((IR_IN)&&(!IR_TF));
if (IR_TF) goto IR_SCAN_ERR; //如果超时测退出
Time_Width=IR_ReadT()-0xF542;
if((Time_Width<(IR_C0_Time+IR_Warp_Time))&&(Time_Width>(IR_C0_Time-IR_Warp_Time)) )
{
IR_Scan[Index1]>>=1;
}
if((Time_Width<(IR_C1_Time+IR_Warp_Time))&&(Time_Width>(IR_C1_Time-IR_Warp_Time)))
{
IR_Scan[Index1]>>=1;
IR_Scan[Index1]=IR_Scan[Index1]|0x80;
}
}
}
IR_SETT(0xFFFF-IR_C1_Time-IR_Warp_Time); //延时2.75ms 最后的结束码
while(!IR_TF);
IR_RSTNUM=0;
//********************************************************************************************
// 验计用户码及校验
//********************************************************************************************
#if (IR_USESCAN) //用户码校验
if (IR_USENO!=IR_Scan[0]) {
IR_Scan[0]=0xFF;
IR_Scan[1]=0xFF;
IR_Scan[2]=0xFF;
IR_Scan[3]=0xFF;
}
#endif
}
}
IR_SCAN_ERR:
IR_EA=1; //关闭中断
return(IR_Scan[2]);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -