⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ir.c

📁 这是我在学习红外遥控接收时写的代码
💻 C
字号:
#ifndef _IR_C
#define _IR_C


/*****************************说明*****************************************
	该红外线接收代码是针对红外线遥控器设计的,在使用中请根据具体的红外线感应
	 器的说明修改。

*/


#include <stdio.h>
#include <REG768.H> /*Philips 87LPC768 寄存器定义头文件*/
#include "ir.h"


#define REDINT 0x06 /*红外线间隔*/

/*存放消息标志的可位寻址字节Message,Message=NULL 时无任消息*/
unsigned char bdata Message;

/*在接收过程中置位,检测标置位Get 可以有效防止其它进程干扰接收,防止数据丢失.*/
sbit RedMsg=Message^0; /*红外遥控消息*/
sbit RedRead=Message^1; /*位接收过程标志*/
sbit RedBit =Message^2; /*接收到的位值*/
sbit RSend =Message^3; /*红外接收中重新发送标志*/

/*存放遥控的字数据,低4 位存放接收到的bit 的位移,高12 位从低到高存放接收到的bit*/
unsigned char bdata RedDataL,RedDataH;

/*RedDataH 字节低6 位代表指令只有一个1 C1-C3 是用户码H 表示连续S1 S2 分别表示第一二组单发*/
sbit RedData0=RedDataL^4; /*C1*/
sbit RedData1=RedDataL^5; /*C2*/
sbit RedData2=RedDataL^6; /*C3*/
sbit RedData3=RedDataL^7; /*H*/
sbit RedData11=RedDataH^0; /*D6*/
sbit RedData10=RedDataH^1; /*D5*/
sbit RedData9=RedDataH^2; /*D4*/
sbit RedData8=RedDataH^3; /*D3*/
sbit RedData7=RedDataH^4; /*D2*/
sbit RedData6=RedDataH^5; /*D1*/
sbit RedData5=RedDataH^6; /*S2*/
sbit RedData4=RedDataH^7; /*S1*/
unsigned char bdata State; /*状态字节*/
sbit RedControl=State^6; /*遥控状态*/



/*定时器T00 的高位定时参数为Timer 
定时256*Timer+(80--336)个周期共139Timer+(43--182)us<37ms 
定时器T01的高位定时节参数为nTimer 定时256*nTimer+(24--280)个周期139nTimer+(13--152)us<9.1s,
RedCon 存放红外接收时的载波计数*/

unsigned char data RedCon;
unsigned int nTimer; /*定时整型参数*/
/*INT1 用于红外解码状态遥控解码数据处理,nTimer=1 定时152--291us*/
void Inte1() interrupt 2 using 2
{
	for(nTimer=8;nTimer>1;nTimer--);/*使处理周期达到51 机器周期=27.7us 使得RedCon<32*/

	if(RedRead) 
	{
		RedCon++; /*0 信号宽度a=420us,1 信号宽度a=1260us,周期4a=1680us*/
	}
	else
	{ /*开始计数或者重新发送时开始计数*/
		RedBit=0; /*复位接收位*/
		RedCon=0; /*复位载波计数*/
		RedRead=1; /*置位位接收标志*/
		if(!ET1)
		{ /*首次接收时没有启动定时器T01 接收第一个位*/
			TF1=0; /*复位定时器T01 益出标志*/
			ET1=1; /*启动T01 定时*/
			RedDataL=0; /*复位红外数据*/
			RedDataH=0; /*复位红外数据*/
			RSend=0;
		} /*复位重新发送标志*/
	}
}

void Count1(void) interrupt 3 using 3
{ 
	/*定时器T01 中断,最大定时9.1s*/
	if(nTimer!=0)
	{ /*检测定时器T01 的扩展高位*/
		nTimer--;
		return;
	}

	ET1=0; /*关闭T01 定时*/

	if(RedRead)
	{ /*红外接收状态*/
		if((RedDataL&0xF)==12)
		{ /*第一阶段接收已经结束*/
			RSend=1; /*置位重新发送标志以便校验*/
			RedDataL&=0xF0;
		} /*复位位指针以便校验*/
		
		if(RedCon>27-REDINT&&RedCon<27+REDINT) RedBit=1;
		else RedBit=0; /*低电平计数9 表示0 27 表示1*/
		
		if(RSend)
		{ /*检验重复发送的数据是否与第一次符合*/
			switch(RedDataL&0xF)
			{
				case 0: /*检验重复发送的第1 位数据*/
					if(RedBit!=RedData0) goto RClear;
					break;
				case 1: /*检验重复发送的第2 位数据*/
					if(RedBit!=RedData1) goto RClear;
					break;
				case 2: /*检验重复发送的第3 位数据*/
					if(RedBit!=RedData2) goto RClear;
					break;
				case 3: /*检验重复发送的第4 位数据*/
					if(RedBit!=RedData3) goto RClear;
					break;
				case 4: /*检验重复发送的第5 位数据*/
					if(RedBit!=RedData4) goto RClear;
					break;
				case 5: /*检验重复发送的第6 位数据*/
					if(RedBit!=RedData5) goto RClear;
					break;
				case 6: /*检验重复发送的第7 位数据*/
					if(RedBit!=RedData6) goto RClear;
					break;
				case 7: /*检验重复发送的第8 位数据*/
					if(RedBit!=RedData7) goto RClear;
					break;
				case 8: /*检验重复发送的第9 位数据*/
					if(RedBit!=RedData8) goto RClear;
					break;
				case 9: /*检验重复发送的第10 位数据*/
					if(RedBit!=RedData9) goto RClear;
					break;
				case 10: /*检验重复发送的第11 位数据*/
					if(RedBit!=RedData10) goto RClear;
					break;
				case 11: /*检验重复发送的第12 位数据*/
					if(RedBit!=RedData11) goto RClear;
					RedMsg=1; /*接受到经过检验正确的编码后置位遥控消息*/
					RedBit=0; /*复位接收位*/
					RSend=0; /*复位重新发送标志*/
					RedRead=0; /*复位接收过程标志*/
					RedCon=0; /*复位载波计数*/
					return;
				default: /*重复发送的数据多于12 位时判断为错误*/
					goto RClear;
			}
		}
		else
		{
			switch(RedDataL&0xF)
			{
				case 0: /*保存首次发送的第1 位数据*/
					RedData0=RedBit;
					break;
				case 1: /*保存首次发送的第2 位数据*/
					RedData1=RedBit;
					break;
				case 2: /*保存首次发送的第3 位数据*/
					RedData2=RedBit;
					break;
				case 3: /*保存首次发送的第4 位数据*/
					RedData3=RedBit;
					break;
				case 4: /*保存首次发送的第5 位数据*/
					RedData4=RedBit;
					break;
				case 5: /*保存首次发送的第6 位数据*/
					RedData5=RedBit;
					break;
				case 6: /*保存首次发送的第7 位数据*/
					RedData6=RedBit;
					break;
				case 7: /*保存首次发送的第8 位数据*/
					RedData7=RedBit;
					break;
				case 8: /*保存首次发送的第9 位数据*/
					RedData8=RedBit;
					break;
				case 9: /*保存首次发送的第10 位数据*/
					RedData9=RedBit;
					break;
				case 10: /*保存首次发送的第11 位数据*/
					RedData10=RedBit;
					break;
				case 11: /*保存首次发送的第12 位数据*/
					RedData11=RedBit;
					break;
				default: /*首次发送的数据多于12 位时判断为错误*/
					goto RClear;
			}
		}
		RedDataL++; /*位位移加1*/
		RedBit=0; /*复位接收位*/
		RedRead=0; /*复位接收过程标志*/
		RedCon=0; /*复位载波计数*/
		nTimer=423; /*用定时140a 检测同步信号208a*/
		TF1=0; /*复位定时器T01 益出标志*/
		ET1=1;/*启动定时器*/
	} 
	else if(RSend)
	{ /*在位接收没有结束时发生定时中断需要复位接收信息(同步)*/
		RClear:
		RedDataL=0; /*复位红外数据*/
		RedDataH=0; /*复位红外数据*/
		RedBit=0; /*复位接收位*/
		RedRead=0; /*复位接收过程标志*/
		RSend=0; /*复位重新发送标志*/
		RedCon=0; /*复位载波计数*/
		ET1=0; /*关闭T01 定时*/
	}
}

void ir_init()
{
	/*看门狗陷阱复位时无需初始化*/
		Message=0; /*无消息*/
		State=0; /*正常复位无任何状态*/

		return;
}

unsigned char ir_read()
{
		EX1= RedControl; /*设置遥控中断INT1 */	
		if(RedMsg) 
		{ /*执行遥控指令*/
			EX1=0; /*在指令没有处理完之前不能重复中断*/
			switch(RedDataH)
			{ 
				/*这里加入红外指令的控制过程*/
				case 0x82: /*Channel 1*/
					break;
				case 0xA0: /*Channel 2*/
					break;
			}
			EX1=1;
			RedDataL=0; /*复位红外数据*/
			RedDataH=0; /*复位红外数据*/
			RedMsg=0;
		} /*复位红外遥控消息*/

		return SOMEBODY_COMMING;
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -