/*****************************************************************************************
TC9148 红外解码 C 程序
红外一体化接收头 + 89S52 红外一体化接收头反相后接P3.2 (INT0)
CUP:STC89C52RC 晶振:11.0569MHz
直接如串口输出 波特率:57600
串口输出共两个字节:
IRCode[0]即高字节中的低四位 bit3 bit2 bit1 bit0
对应 C1 C2 C3 H
IRCode[1] 即低字节中的八位 bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
对应 S1 S2 D1 D2 D3 D4 D5 D6
/*******************************************************************************************
基本发送波形 每个发送周期按 C1、C2、C3、H、S1、S2、D1、D2、D3、D4、D5、D6的次序串行发送
C1 C2 C3 H S1 S2 D1 D2 D3 D4 D5 D6
用户码 连发/单发码 键输入码
设定用户码的方法:在T1、T2、T3与CODE之间(T1=10/T2=11/T3=12脚与CODE=13脚)分别接1N4148并分别代表
C1、C2、C3为“1”,若某一端不接二极管则代表“0”。
H、S1和S2 是代表连续发送或单次发送的码,且分别与和T1、T2、和T3列的键对应。
D1~D3~D6 是发送的数据码。
2011-07-13
/*******************************************************************************************/
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
//*************用到的I/O口定义**************
sbit P32 = P3^2; //INT0,红外信号输入
sbit P23 = P1^3; //BZ
//************函数申明*********************
void InitCom(void); //串口初始化
void ComOutChar(unsigned char OutData); //从串口输出一个字符
void delay580us(void); //精确延时580us
void delay1000us(void); //精确延时1000us
/**************** 580us ******************************************/
void delay580us(void)
{
unsigned char a,b;
for(b = 59;b > 0;b--)
for(a = 3;a > 0;a--);
}
/************* 1000us ***********************************************/
void delay1000us(void)
{
unsigned char a,b;
for(b = 102;b > 0;b--)
for(a = 3;a > 0;a--);
}
/*****************************************************************************/
/****************** 向串口输出一个字符(非中断方式) *******************/
void ComOutChar(unsigned char OutData)
{
SBUF = OutData; //输出字符
while(!TI); //空语句判断字符是否发完
TI = 0; //清TI
}
//****************************************************************
//串口初始化 晶振为11.0592M 波特率57600bps
//****************************************************************
void InitCom(void)
{
TMOD |= 0x20;
SCON = 0x50;
PCON |= 0x80;
TH1 = 0xff; //57600bps @ 11.0592MHz
TL1 = 0xff;
TR1 = 1;
}
/************************ 主程序 ***********************************/
void main (void)
{
uint di;
InitCom(); //初始化串口
IT0 = 1; //INT0为负边沿触发, (1:负边沿触发,0:低电平触发)
EX0 = 1; //外部中断INT0开, (1:开, 0:关 )
EA = 1; //开所有中断
ComOutChar(0xff); //向串口发送 0xff ,表示串口正常工作
while(1);
}
/******************************* 外部中断0 红外解码程序 ****************************/
static void decode(void) interrupt 0 using 2
{
unsigned char IRCode[2] = {0,0};
unsigned char count0,count1,count2;
unsigned char m;
EX0 = 0; //外部中断0关闭
for(count0 = 0;count0 < 34;count0++) //起始码前34.5ms的低电平
{
delay1000us();
if(P32) goto exit; //34ms没完就出来高电平则为干扰信号,跳出中断(退出解码)
}
if(!P32) //低电平没完
{
count1 = 0;
for(count2 = 0;count2 < 4;count2++) //每个字节4位
{
while(!P32); //等待高电平到来
delay1000us(); //延时1000us,结束高电平
if(P32) //延时1000us后,若P32还是高电平,则为 位1
{
IRCode[count1] = IRCode[count1]<<1;
IRCode[count1] = IRCode[count1] | 0x01;
delay580us();
}
else //否则为 位0
{
IRCode[count1] = IRCode[count1] << 1;
IRCode[count1] = IRCode[count1] | 0x00;
}
}
count1++;
for(count2 = 0;count2 < 8;count2++) //每个字节8位
{
while(!P32); //等待高电平到来
delay1000us(); //延时1000us,结束高电平
if(P32) //延时1000us后,若P32还是高电平,则为 位1
{
IRCode[count1] = IRCode[count1] << 1;
IRCode[count1] = IRCode[count1] | 0x01;
delay580us();
}
else //否则为 位0
{
IRCode[count1] = IRCode[count1] << 1;
IRCode[count1] = IRCode[count1] | 0x00;
}
}
/***************************************************************************************/
{
if ((IRCode[0] !=0)&&(IRCode[1] !=0)) //数据校验
{
ComOutChar(IRCode[0]); //串口发送数据码
ComOutChar(IRCode[1]);
P23 = 0; //解码成功后BZ响一次
for(m = 0;m < 100;m++)
{
delay1000us();
}
P23 = 1;
}
}
}
exit:
EX0 = 1;
}
|