/**********************************************************************************************
*
* 红外线遥控接收检测控制程序 V1.0
*
* 红外线接收检测用的子程序
*
* 文件名 : IR_KEY.C
* 设计者 : 李东荣(EMAIL:JDLDR@21CN.COM,QQ:20475125)
************************************************************************************************
* 功 能 描 述
*
* 1. 红外接收头必需接在外部中断的引脚上
* 2. 该程序需要占用一个计数器
************************************************************************************************/
#include"reg51.h"
#ifdef DEBUG
sbit P2_7 = P2^7; //十位数码管选通
sbit P2_6 = P2^6; //个位数码管选通
unsigned char code Tab[]={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //共阳极数码管
#endif
/***********************************************************************************************
硬件配置
************************************************************************************************/
#define IR_T 0 //使用使用计时器号;0=使用计时器0;1=计时器1
sbit IR_IN = P3^2; //红外线输入引脚地址
/***********************************************************************************************
软件配置
************************************************************************************************/
#define IR_USESCAN 0 //是否启用用户码扫描
#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 //偏差的最大时间长度 0.5ms
#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 //偏差的最大时间长度 0.5ms
#define IR_RSTOUT 10 //
#endif
/***********************************************************************************************
IRKEY全局变量声明
************************************************************************************************/
unsigned char IR_RSTNUM;
unsigned char DisplayData = 0;
unsigned char Data;
sbit J1 = P1^4;
sbit J2 = P1^5;
sbit BUZZER = P1^6;
sbit LED_Run = P2^0; //运行指示
sbit LED_Strong = P2^1;
sbit LED_Weak = P2^2;
sbit LED_Half = P2^3;
sbit LED_One = P2^4;
sbit LED_Tow = P2^5;
#ifdef BUTTON
sbit BUTTON_Run = P1^4; // 开关
sbit BUTTON_Strong = P1^5;
sbit BUTTON_Weak = P1^6;
sbit BUTTON_Time = P1^7;
#endif
bit On_Off = 0;
bit Strong = 1;
unsigned int Ts;
bit Tc = 1;
unsigned char Time = 0;
unsigned char T_num = 0;
//****************************按键定义部份*******************************//
/***********************************************************************************************
函数名称: IRKEY 计数器加载子程序
函数原型: void IR_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=(unsigned char)(TempTS);
TL=(unsigned char)(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)
************************************************************************************************/
void IR_Start(void)
{
EX0 = 1;
ET0 = 0;
IR_EA = 1;
}
/************************************************************************************************
函数名称: IR扫描程序
函数原型: unsigned char IR_Scan(void)
函数功能: 扫描IR
输入参数: 无
返回参数: 用户码
创建日期: 2009年10月19
修改日期:
有关说明: 需用INT0调用
编写作者
*******************************************************************************************************/
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(65535-IR_Start_Time-IR_Warp_Time); //设置计数为计数初值 9ms+偏差值
while ((!IR_IN)&&(!IR_TF));
Time_Width=IR_ReadT()-(65535-IR_Start_Time-IR_Warp_Time);
if (!((Time_Width<(IR_Start_Time+IR_Warp_Time))&&(Time_Width>(IR_Start_Time-IR_Warp_Time))))
{
goto IR_SCAN_ERR;
} |