|
发表于 2012-11-30 21:47:29
|
显示全部楼层
用AT89C2051芯片,同样采用12M晶振,将代码修改为如下:
发射部分:
#include <AT892051.h>
#include "INC\MY_SET.h"
//sbit IR = P3^6; //发射引脚(接PNP三极管基极)
sbit IrOutput = P1^6;
//#define USER_H P2 //用户码高8位
//#define USER_L P0 //用户码低8位
#define USER_H 0x03
#define USER_L 0xFC
//uint8c tab[16] = { //操作码
// 0x12,0x05,0x1e,0x55,
// 0x01,0x1b,0x03,0x6b,
// 0x07,0x08,0x09,0x68,
// 0x22,0xE6,0x33,0xe2};
#define m9 (65536-9000) //9mS
#define m4_5 (65536-4500) //4.5mS
#define m1_6 (65536-1650) //1.65mS
#define m_56 (65536-560) //0.56mS
#define m40 (65536-40000) //40mS
#define m56 (65536-56000) //56mS
#define m2_25 (65536-2250) //2.25mS
void ZZ(uint8 x); //NEC编码发送程序
void Z0(uint8 temp); //单帧(8位数据)发送程序
void TT0(bit BT,uint16 x); //38KHz载波发射 + 延时程序
void delay() //延时程序,大约 1s
{
int i,j;
for(i=0;i<400;i++)
{
for(j=0;j<100;j++)
{
}
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:主程序
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void main(void)
{
TMOD = 0x01; //T0 16位工作方式
IrOutput=1; //发射端口常态为高电平 (接PNP三极管基极)
//IrOutput=0; //发射端口常态为低电平 (接NPN三极管基极)
while(1)
{
ZZ(0x05);
delay();
delay();
delay();
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:NEC编码发送程序
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void ZZ(uint8 Value)
{
TT0(1,m9); //高电平9mS
TT0(0,m4_5); //低电平4.5mS
/*┈ 发送4帧数据┈*/
Z0(USER_H); //用户码高8位
Z0(USER_L); //用户码低8位
Z0(Value); //操作码
Z0(~Value); //操作码反码
/*┈┈ 结束码 ┈┈*/
TT0(1,m_56);
TT0(0,m40);
/*┈┈ 重复码 ┈┈*/
/*while(1)//KEY() != 0xFF)
{
TT0(1,m9);
TT0(0,m2_25);
TT0(1,m_56);
TT0(0,m40);
TT0(0,m56);
} */
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:单帧(8位数据)发送程序
入口:temp
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void Z0(uint8 temp)
{
uint8 v;
for (v=0;v<8;v++) //循环8次移位
{
TT0(1,m_56); //高电平0.65mS
if(temp&0x01) TT0(0,m1_6); //发送最低位
else TT0(0,m_56);
temp >>= 1; //右移一位
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:38KHz载波发射 + 延时程序
入口:(是否发射载波,延时约 x (uS))
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void TT0(bit BT,uint16 x)
{
TH0 = x>>8; //输入T0初始值
TL0 = x;
TF0=0; //清0
TR0=1; //启动定时器0
if(BT == 0) while(!TF0); //BT=0时,不发射38KHz载波只延时;BT=1发射38KHz脉冲且延时;
else while(1) //BT=1时,发射38KHz脉冲+延时;38KHz载波,(低电平)占空比5:26
{
IrOutput = 0; // PNP
// IrOutput = 1; // NPN
if(TF0)break;if(TF0)break;
_nop_(); //频率有些高,降低添加适量的空操作“_nop_();”(注:不要放在大括号两侧)
IrOutput = 1; // PNP
//IrOutput = 0; // NPN
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
}
/*
else while(1) //BT=1时,发射38KHz脉冲+延时;38KHz载波(低电平)占空比约5:26
{
// IrOutput = 0; // PNP
IrOutput = 1; // NPN
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
_nop_();
//IrOutput = 1; // PNP
IrOutput = 0; // NPN
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
}
*/
TR0=0; //关闭定时器0
TF0=0; //标志位溢出则清0
IrOutput =1; //载波停止后,发射端口常态为高 (接PNP三极管基极)
// IrOutput =0; //载波停止后,发射端口常态为高 (接NPN三极管基极)
}
接收部分:
#include <AT892051.h>
#include "INC\MY_SET.H"
#include "INC\IR_NEC.H" //调用NEC解码头文件
sbit IrLED = P1^6; //指示1
sbit LED1 = P1^5; //指示2
sbit LED2 = P1^4; //指示3
void KZ0(); //短按处理
/***************** 主函数 ********************/
void main(void)
{
IRSignal = 1; //P1口引脚写入“1”时,其可用作输入端
IR_Init(); //红外线解码初始化
LED1 = 1;
LED2 = 1;
IR_BT= 0;
while(1)
{
//遥控检测
if ((IR_BT==2)||(IR_BT==3))
{
TR0 = 0;
KZ0(); //短按处理
IR_BT =0; //清有效标志
IRReset();
TR0 = 1;
}
if (!IRSignal)
{
IrLED =0;
}
else
{
IrLED = 1;
}
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:遥控短按处理
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void KZ0()
{
switch(NEC[2])
{
// case 0x12: P10 = !P10; break;
case 0x12:
LED1 = 0;//~LED1;
LED2 = 1;
break;
case 0x05:
LED2 = 0;//~LED2;
LED1 = 1;
break;
case 0x1E: break;
case 0x55: break;
case 0x01: break;
case 0x1B: break;
case 0x03: break;
case 0x6B: break;
case 0x07: break;
case 0x08: break;
case 0x09: break;
case 0x68: break;
case 0x22: break;
case 0xE6: break;
case 0x33: break;
case 0xE2: break;
default:break;
}
}
/********************** 定时器0中断函数************************/
void time0(void) interrupt 1
{
IR_NEC();
}
#ifndef __IR_NEC_H__
#define __IR_NEC_H__
//【用户必填项:USER_H、USER_L、Check_EN、CPU_Fosc、IR】
#define USER_H 0x80 //用户码高8位
#define USER_L 0x7F //用户码低8位
#define Check_EN 0 //是否要校验16位用户码:不校验填0,校验则填1
#define CPU_Fosc 12000000 //输入主频,自适应解码(单位:Hz,范围:6MHz ~ 40MHz)
#define CA_S 8 //长按时间设置,单位:108mS(即 108mS整数倍,10倍以上为宜)
//sbit IR = P3^6; //红外线接口(任意引脚)
sbit IRSignal = P1^7; //红外线接口(任意引脚)
#define Step 400 //红外采样步长:400us
#define TH_H ((65536-Step*(CPU_Fosc/300)/40000)/256) //定时器高8位基准赋值
#define TH_L ((65536-Step*(CPU_Fosc/300)/40000)%256) //定时器低8位基准赋值
uint8 IR_BT; //解码效果返回:0无效,1有效,2短按,3长按
uint8 NEC[4]; //解码存放:16位用户码、操作码正反码
uint8 cntCA; //长按计数
//uint16 cntStep; //步数计
uint8 cntStep; //步数计
bit IRa,IRb; //电位状态保存
bit IRsync; //同步标志
uint8 BitN; //位码装载数
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:红外线解码初始化
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void IR_Init()
{
TMOD &= 0xF0; //清定时器0
TMOD |= 0x01; //定时器0:16位定时器
TL0 = TH_L; //每步时间
TH0 = TH_H;
ET0 = 1;
EA = 1;
TR0 = 1;
}
void IRReset()
{
TL0 = TH_L; //每步时间
TH0 = TH_H;
NEC[0] = 0x00; //解码存放:16位用户码、操作码正反码
NEC[1] = 0x00;
NEC[2] = 0x00;
NEC[3] = 0x00;
cntCA = 0; //长按计数
cntStep = 0; //步数计
IRa =0;
IRb = 0; //电位状态保存
IRsync =0; //同步标志
BitN =0; //位码装载数
}
/*┈┈┈┈┈┈┈┈┈┈ 基准 ┈┈┈┈┈┈┈┈┈┈┈*/
//#define Boot_Limit (((9000+4500) +2000)/Step) //引导码周期上限
//#define Boot_Lower (((9000+4500) -2000)/Step) //引导码周期下限
//#define Bit1_Limit ((2250 +800)/Step) //“1”周期上限
//#define Bit0_Limit ((1125 +400)/Step) //“0”周期上限
//允许误差2000us有点大了,改成1000
#define Boot_Limit (((9000+4500) +1000)/Step) //引导码周期上限
#define Boot_Lower (((9000+4500) -1000)/Step) //引导码周期下限
#define Bit1_Limit ((2250 +800)/Step) //“1”周期上限
#define Bit0_Limit ((1125 +400)/Step) //“0”周期上限
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:红外线NEC周期采样解码法(定时中断,下降沿查询周期时间)
全局变量:IR_BT = 0无效
1有效,待继续判断长、短按(如不需要判断长、短按,则直接使用)
2短按
3长按
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void IR_NEC()
{
TL0 = TH_L; //重赋值
TH0 = TH_H;
IRb = IRa; //上次电位状态
IRa = IRSignal; //当前电位状态
cntStep++; //步数采样
if (IR_BT==1)
{
if(cntStep>300)
{
IR_BT=2;//解码有效后,如果无长按,120ms(400us×300)后默认短按
}
}
// IRb = IRa; //上次电位状态
// IRa = IRSignal; //当前电位状态
if(IRb && !IRa) //是否下降沿(上次高,当前低)
{
if(cntStep > Boot_Limit) //超过同步时间?
{
if(IR_BT==1)
{
if(++cntCA>CA_S)
{
IR_BT=3; //解码有效后,继续按住遥控>CA_S即长按
}
}
IRsync=0; //同步位清0
}
else if (cntStep > Boot_Lower)
{
IRsync=1;
BitN=32;
}//同步位置1,装载位码数
else if (IRsync) //如果已同步
{
if(cntStep > Bit1_Limit)
{
IRsync=0;
}
else
{
NEC[3] >>= 1;
if(cntStep > Bit0_Limit)
NEC[3] |= 0x80; //“0”与“1”
if(--BitN == 0)
{
IRsync = 0; //同步位清0
#if (Check_EN == 1)
if((NEC[0]==USER_H)&&(NEC[1]==USER_L)&&(NEC[2]==~NEC[3])) //校验16位用户码、操作码正反码
{
IR_BT=1;
cntCA=0;
} //解码有效,接下来判断:短按?长按?
#else
if(NEC[2]==~NEC[3])
{
IR_BT=1;
cntCA=0;
} //校验操作码正反码
#endif
}
else if ((BitN & 0x07)== 0) //NEC[3]每装满8位,移动保存一次(即 BitN%8 == 0)
{
NEC[0]=NEC[1];
NEC[1]=NEC[2];
NEC[2]=NEC[3];
}
}
}
cntStep = 0; //步数计清0
}
}
//取消相关宏定义
#undef CPU_Fosc
#endif
其他部分,没有改动!
写入芯片之后, 无法解码出来哦!
拜托各位,看看问题出在哪里?
|
|