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

📄 pt2221.c

📁 PT2221 红外解码 C 程序
💻 C
字号:
/********************************************************************
name: PT2221 红外解码 C 程序
红外一体化接收头 + 89S51
用c做延时的32路红外遥控解码程序,程序中提供了两种实现延时的方法:
1. 加入 intrins.h 头文件后,用for循环和_nop_ 联合组成的精确延时;
2. 用 while(--i); 实现的精确延时
红外一体化接收头接P3.2 (INT0)
P1.7作工作指示用,解码成功后BZ响一次,同时,若解码值为01的话,会取反P1.5
**********************************************************************/
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
//*************用到的I/O口定义**************
sbit P32=P3^2;	//INT0,红外信号输入
sbit P23=P2^3;	//BZ
sbit P15=P1^5;
sbit P17=P1^7; //工作指示灯
//************函数申明*********************
void InitCom(void);		//串口初始化
void ComOutChar(unsigned char OutData);	//从串口输出一个字符
void delay882us(void);	//精确延时882us
void delay4740us(void);	//精确延时4740us
void delay1000us(void);	//精确延时1000us
//************************主程序***********************************
//向串口输出一个字符(非中断方式)
//***************************************************************
void ComOutChar(unsigned char OutData)
{
	SBUF = OutData; //输出字符
	while(!TI); //空语句判断字符是否发完
	TI = 0; //清TI
}
//****************************************************************
//串口初始化 晶振为11.0592M 方式1 波特率9600
//****************************************************************
void InitCom(void)
{
	SCON = 0x50; //串口方式1,允许接收
	TMOD = 0x21; //定时器1定时方式2,定时0为模式1,16位模式
	TH1 = 0xFd;	//设波特率为9600
	TL1 = 0xFd;
	PCON = 0x00; //波特率不加倍控制,SMOD为0
	RI = 0;	//清收发标志
	TI = 0;
	TR1 = 1; //启动定时器
}

//*****************************************
//	用 for 循环和 _nop_ 配合实现的精确延时
//*****************************************
//****************882us********************
void delay882us(void)
{
	uchar i;
	for(i=0;i<202;i++)
	{
		_nop_();
	}
}
//****************4740us*******************
void delay4740us(void)
{
	uint j;
	for(j=0;j<670;j++)
	{
		_nop_();
	}
}
//*************1000us**********************
void delay1000us(void)
{
	uchar k;
	for(k=0;k<230;k++)
	{
		_nop_();
	}
}

void main (void)  
{
	uint di;
	InitCom(); //初始化串口
	EA=1;
  	EX0=1; // 设定接受INT0的中断
	IT0=1;
  	ComOutChar(1);	//向串口发送 1 ,表示串口正常工作
	do
	{
        P17=~P17;	//工作指示灯,这个LED闪烁表示主程序在运行
		for(di=0;di<1000;di++)
		{
			delay1000us();
		}
	}while(1);
}
//*******************外部中断0 红外解码程序**************** 
static void decode(void) interrupt 0 using 2
{
	unsigned char IRCode[4]={0,0,0,0};
	unsigned char count0,count1,count2;
	unsigned char m;
	EX0 = 0; //外部中断0关闭
	for(count0=0;count0<10;count0++)	//起始码前9ms的低电平
	{
		delay882us();
		if(P32) goto exit;	//9ms没完就出来高电平则为干扰信号,跳出中断(退出解码)
	}
	if(!P32)	//低电平没完
	{
		delay4740us();	//9ms没结束再延时4740us,加上前面的8820us,已跳过起始码的13.5ms
		for(count1=0;count1<4;count1++)	//开始读数据,4个字节,32位
		{
			for(count2=0;count2<8;count2++)	//每个字节8位
			{
				while(!P32);	//等待高电平到来
				delay882us();
				if(P32)	//延时882us后,若P32还是高电平,则为 位1
					{
						IRCode[count1]=IRCode[count1]>>1;
						IRCode[count1]=IRCode[count1]|0x80;
						delay1000us();	//延时1000us,结束高电平
					}
				else	//延时882us后,若P32为低电平,则为 位0
				{
					IRCode[count1]=IRCode[count1]>>1;
					IRCode[count1]=IRCode[count1]|0x00;
				}
			}
		}	//到这里已读完所有32位数据
		//if ((IRCode[0]==0x00)&&(IRCode[1]==0xff))	//判断用户码和用户反码是否正确
		//if ((IRCode[0]==0x02)&&(IRCode[1]==0xBD))	//判断用户码和用户反码是否正确
		 //if ((IRCode[0]==0x01)&&(IRCode[1]==0xff)) //判断用户码和用户反码是否正确
		{
			if (IRCode[2]==~IRCode[3])	//数据校验
			{
				ComOutChar(IRCode[0]);
				ComOutChar(IRCode[1]);
				ComOutChar(IRCode[2]);	//串口发送数据码
				ComOutChar(IRCode[3]);
                P23=0;					//解码成功后BZ响一次
				for(m=0;m<100;m++)
				{
					delay1000us();
				}
                P23=1;
				if(IRCode[2]==0x01)
				{
                    P15=~P15; //这里可加入控制命令,比如这里的当解码为01时取反P1.5
					for(m=0;m<100;m++)
					{
						delay1000us();
					}
				}
			}
		}
	}
exit:
	EX0 = 1;	
}

⌨️ 快捷键说明

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