欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

NEC 协议红外线遥控器

最编程 2024-05-24 13:58:52
...
  • /***************************Infrared.c 文件程序源代码*****************************/
  • #include <reg52.h>
  • sbit IR_INPUT = P3^3; //红外接收引脚
  • bit irflag = 0; //红外接收标志,收到一帧正确数据后置 1
  • unsigned char ircode[4]; //红外代码接收缓冲区
  • /* 初始化红外接收功能 */
  • void InitInfrared(){
  • IR_INPUT = 1; //确保红外接收引脚被释放
  • TMOD &= 0x0F; //清零 T1 的控制位
  • TMOD |= 0x10; //配置 T1 为模式 1
  • TR1 = 0; //停止 T1 计数
  • ET1 = 0; //禁止 T1 中断
  • IT1 = 1; //设置 INT1 为负边沿触发
  • EX1 = 1; //使能 INT1 中断
  • }
  • /* 获取当前高电平的持续时间 */
  • unsigned int GetHighTime(){
  • TH1 = 0; //清零 T1 计数初值
  • TL1 = 0;
  • TR1 = 1; //启动 T1 计数
  • while (IR_INPUT){ //红外输入引脚为 1 时循环检测等待,变为 0 时则结束本循环
  • //当 T1 计数值大于 0x4000,即高电平持续时间超过约 18ms 时,
  • //强制退出循环,是为了避免信号异常时,程序假死在这里。
  • if (TH1 >= 0x40){
  • break;
  • }
  • }
  • TR1 = 0; //停止 T1 计数
  • return (TH1*256 + TL1); //T1 计数值合成为 16bit 整型数,并返回该数
  • }
  • /* 获取当前低电平的持续时间 */
  • unsigned int GetLowTime(){
  • TH1 = 0; //清零 T1 计数初值
  • TL1 = 0;
  • TR1 = 1; //启动 T1 计数
  • while (!IR_INPUT){ //红外输入引脚为 0 时循环检测等待,变为 1 时则结束本循环
  • //当 T1 计数值大于 0x4000,即低电平持续时间超过约 18ms 时,
  • //强制退出循环,是为了避免信号异常时,程序假死在这里。
  • if (TH1 >= 0x40){
  • break;
  • }
  • }
  • TR1 = 0; //停止 T1 计数
  • return (TH1*256 + TL1); //T1 计数值合成为 16bit 整型数,并返回该数
  • }
  • /* INT1 中断服务函数,执行红外接收及解码 */
  • void EXINT1_ISR() interrupt 2{
  • unsigned char i, j;
  • unsigned char byt;
  • unsigned int time;
  • //接收并判定引导码的 9ms 低电平
  • time = GetLowTime();
  • //时间判定范围为 8.5~9.5ms,
  • //超过此范围则说明为误码,直接退出
  • if ((time<7833) || (time>8755)){
  • IE1 = 0; //退出前清零 INT1 中断标志
  • return;
  • }
  • //接收并判定引导码的 4.5ms 高电平
  • time = GetHighTime();
  • //时间判定范围为 4.0~5.0ms,
  • //超过此范围则说明为误码,直接退出
  • if ((time<3686) || (time>4608)){
  • IE1 = 0;
  • return;
  • }
  • //接收并判定后续的 4 字节数据
  • for (i=0; i<4; i++){ //循环接收 4 个字节
  • for (j=0; j<8; j++){ //循环接收判定每字节的 8 个 bit
  • //接收判定每 bit 的 560us 低电平
  • time = GetLowTime();
  • //时间判定范围为 340~780us,
  • //超过此范围则说明为误码,直接退出
  • if ((time<313) || (time>718)){
  • IE1 = 0;
  • return;
  • }
  • //接收每 bit 高电平时间,判定该 bit 的值
  • time = GetHighTime();
  • //时间判定范围为 340~780us,
  • //在此范围内说明该 bit 值为 0
  • if ((time>313) && (time<718)){
  • byt >>= 1; //因低位在先,所以数据右移,高位为 0
  • //时间判定范围为 1460~1900us,
  • //在此范围内说明该 bit 值为 1
  • }else if ((time>1345) && (time<1751)){
  • byt >>= 1; //因低位在先,所以数据右移,
  • byt |= 0x80; //高位置 1
  • }else{ //不在上述范围内则说明为误码,直接退出
  • IE1 = 0;
  • return;
  • }
  • }
  • ircode[i] = byt; //接收完一个字节后保存到缓冲区
  • }
  • irflag = 1; //接收完毕后设置标志
  • IE1 = 0; //退出前清零 INT1 中断标志
  • }