📄 pt2221.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 + -