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

📄 infraredray_basic_change.c

📁 80C52单片机上用C语言实现的双机红外通信程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*-------------------------

红外遥控嵌入式系统设计
By zheyu

Copyright 2008/12/27
All rights reserved.

----------------------------*/

/*$$$$$$$$$$$$$$$$$$$$$$$$$

功能:(按K1(P3.2)切换功能)
1、	使用配发的红外遥控器进行测试,能够识别遥控器发送出来的控制信号,用数码管显示(采用俱乐部长虹遥控器,P2为段码(P2.7接dp),P1为位码(P0.1接1),红外接收入器
	接P3.3),			LED接,用于确认接收成功。
2、	使用实验板上的按键实现一个红外遥控器,能够实现电视机的遥控,K2接P1.3(用于加1,选频道),K3接P1.2(用于确认发射),P3.7接红外发射器。
3、	使用实验板上的按键实现一个红外遥控接收器,能够实现对另外一组实验板的红外控制。(一机为SFR(发送状态),一机为CIE(接收状态),SFR机K2用于加1选数,
	K3用于确认发送,CIE机接收仅可。
4、	学习型遥控器功能,K2用于更改要替换的频道,K3用于发射,K4接P1.1,用于表示现在开始接收,进入进入学习状态,		LED,绿灯亮表示进入学习状态,闪两下表示学习成功

$$$$$$$$$$$$$$$$$$$$$$$$$$*/

#include <absacc.h>
#include <reg52.h>

#define uint unsigned int
#define uchar unsigned char

sbit output=P3^7;//发送
sbit sign=P1^5;//LED标志
sbit Inttrupt1=P3^3;//中断1
sbit Inttrupt0=P3^2;//中断0
sbit AddOne=P1^3;//加1操作,K2
sbit TransSure=P1^2;//确认发射操作,K3


sbit P00=P0^0;
sbit P01=P0^1;
sbit P02=P0^2;
sbit P03=P0^3;
sbit P04=P0^4;
sbit P05=P0^5;
sbit P06=P0^6;
sbit P07=P0^7;

//十个数		{0,1,2,3,4,5,6,7,8,9,空}
int numbers[11]={0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF};
// 状态提示字符(用于提示,如CHL(channel)){L,H,C,O,S,I,A,E,F}
int Chars[9]={0xc7,0x89,0xc6,0xc0,0x92,0xf9,0x88,0x86,0x8e};
char StoreCodes[10][2]={{0x40,0x00},
						{0x40,0x01},
						{0x40,0x02},
						{0x40,0x03},
						{0x40,0x04},
						{0x40,0x05},
						{0x40,0x06},
						{0x40,0x07},
						{0x40,0x08},
						{0x40,0x09}
					};//用于储存不同的频道码
int buffer[6];//用于储存数码管显示的段码
int buffer1[2];//用于储存收到的值(0功能)仅需存储用户码和数据码
int buffer2[2];//用于储存第几个段码(即段码实际显示值)(2功能)仅变最后两位
int Model;
int channel;//当前为第几个频道
int sign1;//B代替sign1用于学习功能的中断开关


void InitCom(void);//初始化
void ComOutChar(void);//发送数据
void OutOne(void);
void OutZero(void);
void PreCode(void);
void delay528us(void);
void Delay8_44ms(void);
void Delay4_22ms(void);
void Delay3_5ms(void);
void Delay800us(void);
void Delay1ms(uint z);
void Display(void);
void Delay100us(void);
void reBuffer(void);

void reBuffer(void)
{
	//使用配发的红外遥控器进行测试,能够识别遥控器发送出来的控制信号,用数码管显示
	if(Model==0)
	{
		buffer[0]=numbers[buffer1[0]];
		buffer[1]=numbers[0];
		buffer[2]=numbers[10];
		buffer[3]=Chars[0];//CHL(channel)
		buffer[4]=Chars[1];
		buffer[5]=Chars[2];
	}
	//使用实验板上的按键实现一个红外遥控器,能够实现电视机的遥控
	if(Model==1)
	{
		buffer[0]=numbers[channel];//此处仅设计了0-9十个频道
		buffer[1]=numbers[0];
		buffer[2]=numbers[10];
		buffer[3]=Chars[0];//COL(Control)
		buffer[4]=Chars[3];
		buffer[5]=Chars[2];
	}
	//使用实验板上的按键实现一个红外遥控接收器,能够实现对另外一组实验板的红外控制。
	if(Model==2)//Transfer
	{
		buffer[0]=numbers[buffer2[0]];
		buffer[1]=numbers[buffer2[1]];
		buffer[2]=numbers[10];
		buffer[3]=Chars[7];//SFE(transfer)
		buffer[4]=Chars[8];
		buffer[5]=Chars[4];
	}
	if(Model==3)//Recieve
	{
		buffer[0]=buffer[0];//直接接收到的是段码
		buffer[1]=buffer[1];
		buffer[2]=numbers[10];
		buffer[3]=Chars[7];//CIE(recieve)
		buffer[4]=Chars[5];
		buffer[5]=Chars[2];
	}	
	
	//学习型红外遥控器
	if(Model==4)
	{
		buffer[0]=numbers[channel];
		buffer[1]=numbers[0];
		buffer[2]=numbers[10];
		buffer[3]=Chars[6];//LEA(learn)
		buffer[4]=Chars[7];
		buffer[5]=Chars[0];
	}
}


void Display(void)
{
/*%%%%%%%%%%%%%%%%%%%%%%%
P2=段码
P0=位码
//%%%%%%%%%%%%%%%%%%%%%%*/
	int i;
	P0=0xfe;
	for(i=0;i<6;i++)
	{
		P2=buffer[i];
		P0=P0<<1;
		P0=P0|0x01;
		Delay100us();
	}
}

void main(void)
{
//	uint TempCyc;

/*	while(1)
	{
		sign=1;
		Delay8_44ms();
		sign=0;
		Delay4_22ms();
	}*/

	InitCom();
	EA=1;//允许CPU中断
	IT0=0;//INT0下降沿有效
	EX0=1;//开INT0中断
	EX1=0;//关INT1中断,在需要的时候打开
	Model=0;
	sign1=0;
//	ComOutChar();
	while(1)
	{
		if(Model==0)
		{
			EX1=1;
		}
		if(Model==1)//对电视机遥控
		{
			EX1=0;
			if(!AddOne)//加1命令
			{
				Delay8_44ms();
				while(!AddOne);
				if(channel++==0x09)
				{
					channel=0;
				}
			}
			if(!TransSure)
			{
				Delay8_44ms();
				P2=0xff;
				while(!TransSure);
				ComOutChar();
			}
		}
		if(Model==2)//P3.2(外部中断)接K1,P3.3接接收器,P1.3接K2(加1),P1.4接K3(发射确认)
		{
			EX1=0;
			if(!AddOne)//加1命令
			{
				Delay8_44ms();
				while(!AddOne);
				if(buffer2[0]++==0x09)
				{
					buffer2[0]=0;
					if(buffer2[1]++==0x09)
						buffer2[1]=0;
				}
			}
			if(!TransSure)
			{
				Delay8_44ms();
				P2=0xff;
				while(!TransSure);
				ComOutChar();
			}
		}
		if(Model==3)
		{
			EX1=1;
		}

		if(Model==4)//学习功能,P3.2(外部中断)接K1,P3.3接接收器,P1.3接K2(加1),P1.4接K3(学习开始确认)
		{
			if(!sign1)	EX1=0;
			else	EX1=1;
			if(!AddOne)//加1命令
			{
				Delay8_44ms();
				while(!AddOne);
				if(channel++==0x09)
				{
					channel=0;
				}
			}
			if(!TransSure)
			{
				Delay8_44ms();
				while(!TransSure);
				sign=0;
				sign1=1;
			}
		}
		reBuffer();//更改缓冲区(段码)的值
		Display();//显示
	}
}

//外部中断0,用于切换不同的模式(如通信、学习等状态),同时通信的两台机子应保持相同的状态
void INT0Fun(void) interrupt 0
{
	P2=0xff;
	Delay8_44ms();
	if(!Inttrupt0)
	{
		Model++;//调至下一状态
		if(Model==5)//四种状态切换完毕,回到第一种状态
			Model=0;
		while(!Inttrupt0);
	}

}



//INT1中断,当数据发送过来时,会中断
void INT1Fun(void) interrupt 2
{
	uchar IRCode[4],IROK;//IRCode用于储存接收的数据,IROK用于计数接收的数据个数。
	uint TempCyc,TempCycB,TempCycA,si;
	EX1=0;//外部中断0关闭
	P2=0xff;
	IROK=0;
	si=0;
	Delay3_5ms();//延时7ms
	Delay3_5ms();
	if(!Inttrupt1)//若经过延时,其仍为低电平,表明可能不是干扰,要处理,若为高电平,表明是干扰,跳到ENDCHK,此时由于IDOK=0,故其不会进行操作,仅会跳出该中断
	{	
		Delay3_5ms();
		for(TempCycA=0;TempCycA<4;TempCycA++)//用于计数接收到了几个有效数据,此处是要接收两个
		{   
			if(!si)	Delay800us();
			if(Inttrupt1||si)//若经过延迟,其还为0,则表明其引导码前半部分太长——超时,故其跳出,若为1,表明其已有电平拉高,引导码已进入后半部分
			{
				si=0;
				for(TempCyc=0;TempCyc<300;TempCyc++)
					if(!Inttrupt1) break ;//若为0,则表明已经开始传数据了,则跳出该循环,若为1表明还没有开始(引导码还没有结束)
				if(TempCyc<300)//若是没有<300,则表明其不是在P3_2口为0时跳出,而是超时了,此时就要跳出了。
				{
					for(TempCyc=0;TempCyc<8;TempCyc++)//接收一个有数据的8位
					{
						//此时应有一个超时的判定
						while(!Inttrupt1);//等待P3_2为1,就是前半个高位已结束,开始用后面的低电平的长度来判断该位为0还是1
						Delay800us();//跳过一个0位的0电平的长度
						IRCode[TempCycA]=IRCode[TempCycA]>>1;//将当前所接收到的数据右移一位,将已经确定的数据保存起来。
						if(Inttrupt1)//当延迟750us后,若其仍为低则其已释放又开始下一个数据了,若为高则其已释放,为1
						{
							IRCode[TempCycA]=IRCode[TempCycA]|0x80;//将当前已经成功确定为1的位置为1
							for(TempCycB=0;TempCycB<300;TempCycB++)
								if(!Inttrupt1)	
							 {
							 		si=1;
								  break; 
							  }//若又有数据来(0电位),则跳出该循环去接收下一位。
							if(TempCycB>300)//若接收完一位,之后又没有在规定时间内收到,则超时,退出。							
								goto endchk;
						}
					}
		        }
				else
					goto endchk;
         	}
			else
				goto endchk;					
			IROK++;//当自定码和数据码都完成时加2
		}
	}
	
endchk://若成功发送完,这部分为显示成功,否则这时为超时

	if(IROK==4)//若不为2,表明没有发送成功,是超时跳到这里,退出
	{
		if(Model==0)//若为判断遥控器信号状态,则接收到的值用于更改缓冲区的值
		{
			buffer1[0]=IRCode[2];
			sign=0;
			Delay1ms(500);	
			sign=1;
		}
		if(Model==3)//若为红外遥控接收器,则接收到的值用于更改缓冲区的值
		{
			buffer[0]=IRCode[0];
			buffer[1]=IRCode[2];
			sign=0;
			Delay1ms(500);	
			sign=1;
		}		//判断用户码与用户反码,数据码与数据反码是否是互反的。
		
		if(Model==4)//若为学习功能,则接收到的值用于更改当前的频道值
		{
			if(channel==0)
			{
				StoreCodes[0][0]=IRCode[0];
				StoreCodes[0][1]=IRCode[2];
			}
			if(channel==1)
			{
				StoreCodes[1][0]=IRCode[0];
				StoreCodes[1][1]=IRCode[2];
			}
			if(channel==2)
			{
				StoreCodes[2][0]=IRCode[0];
				StoreCodes[2][1]=IRCode[2];
			}
			if(channel==3)
			{
				StoreCodes[3][0]=IRCode[0];
				StoreCodes[3][1]=IRCode[2];
			}
			if(channel==4)
			{
				StoreCodes[4][0]=IRCode[0];
				StoreCodes[4][1]=IRCode[2];
			}
			if(channel==5)
			{
				StoreCodes[5][0]=IRCode[0];
				StoreCodes[5][1]=IRCode[2];
			}
			if(channel==6)
			{
				StoreCodes[6][0]=IRCode[0];
				StoreCodes[6][1]=IRCode[2];
			}
			if(channel==7)
			{
				StoreCodes[7][0]=IRCode[0];
				StoreCodes[7][1]=IRCode[2];
			}
			if(channel==8)
			{
				StoreCodes[8][0]=IRCode[0];
				StoreCodes[8][1]=IRCode[2];
			}
			if(channel==9)
			{
				StoreCodes[9][0]=IRCode[0];
				StoreCodes[9][1]=IRCode[2];
			}			
			sign=0;
			Delay1ms(500);	
			sign=1;
			Delay1ms(200);	
			sign=0;
			Delay1ms(500);	
			sign=1;
			sign1=0;
		}		//判断用户码与用户反码,数据码与数据反码是否是互反的。
	}
//	EX1=1;
}

//向串口输出一个字符
void ComOutChar(void) using 0
{
//	int i;

	
	if(Model==1)//电视控制
	{
		while(1)
		{
				//这里似乎不支持用一个变量作为索引
				if(channel==0) B=StoreCodes[0][0];
				if(channel==1) B=StoreCodes[1][0];
				if(channel==2) B=StoreCodes[2][0];
				if(channel==3) B=StoreCodes[3][0];
				if(channel==4) B=StoreCodes[4][0];
				if(channel==5) B=StoreCodes[5][0];
				if(channel==6) B=StoreCodes[6][0];
				if(channel==7) B=StoreCodes[7][0];
				if(channel==8) B=StoreCodes[8][0];
				if(channel==9) B=StoreCodes[9][0];
//				B=StoreCodes[4][0];
				PreCode();
				#pragma ASM
				;发送原码
				jb B.0,Out101
				lcall OutZero
				ajmp next10
			Out101:
				lcall OutOne
			next10:
				jb B.1,Out111
				lcall OutZero
				ajmp next11
			Out111:
				lcall OutOne
			next11:
				jb B.2,Out121
				lcall OutZero
				ajmp next12
			Out121:
				lcall OutOne
			next12:
				jb B.3,Out131
				lcall OutZero
				ajmp next13
			Out131:
				lcall OutOne
			next13:
				jb B.4,Out141
				lcall OutZero
				ajmp next14
			Out141:
				lcall OutOne
			next14:
				jb B.5,Out151
				lcall OutZero
				ajmp next15
			Out151:
				lcall OutOne
			next15:
				jb B.6,Out161
				lcall OutZero
				ajmp next16
			Out161:
				lcall OutOne
			next16:
				jb B.7,Out171
				lcall OutZero
				ajmp next17
			Out171:
				lcall OutOne
			next17:
			
			
				;发送反码
				jnb B.0,Out100
				lcall OutZero
				ajmp next1001
			Out100:
				lcall OutOne
			next1001:
				jnb B.1,Out110
				lcall OutZero
				ajmp next1101
			Out110:
				lcall OutOne
			next1101:
				jnb B.2,Out120
				lcall OutZero
				ajmp next1201
			Out120:
				lcall OutOne
			next1201:
				jnb B.3,Out130
				lcall OutZero
				ajmp next1301
			Out130:
				lcall OutOne
			next1301:
				jnb B.4,Out140
				lcall OutZero
				ajmp next1401
			Out140:
				lcall OutOne
			next1401:
				jnb B.5,Out150
				lcall OutZero
				ajmp next1501
			Out150:
				lcall OutOne
			next1501:
				jnb B.6,Out160
				lcall OutZero
				ajmp next1601
			Out160:
				lcall OutOne
			next1601:
				jnb B.7,Out170
				lcall OutZero
				ajmp next1701
			Out170:
				lcall OutOne
			next1701:
			#pragma ENDASM
			
				if(channel==0) B=StoreCodes[0][1];
				if(channel==1) B=StoreCodes[1][1];
				if(channel==2) B=StoreCodes[2][1];
				if(channel==3) B=StoreCodes[3][1];
				if(channel==4) B=StoreCodes[4][1];
				if(channel==5) B=StoreCodes[5][1];
				if(channel==6) B=StoreCodes[6][1];
				if(channel==7) B=StoreCodes[7][1];
				if(channel==8) B=StoreCodes[8][1];

⌨️ 快捷键说明

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