写了个 红外摇控解码
我也是刚玩单片机的,是看时序图 写程序的,大家看看有没有问题。我测试没什么问题。P3.2与P3.0 一起接到红外接收头上。P3.2用来响应。P3.0用来接收数据。
#include <REGX52.H>
#define aa unsigned int //局全变量
#define A unsigned char //全局变量<A的值在0-255>
sbit l1=P0^0;
sbit l2=P0^1;
sbit l3=P0^2;
sbit l4=P0^3;
sbit l5=P0^4;
sbit l6=P0^5;
sbit l7=P0^6;
sbit l8=P0^7;
A xo[40];//新建一个空例表。用来装东东,能放41个东东。
aa n,s,s1;
void ll()
{
l1=xo[19];
l2=xo[20];
l3=xo[21];
l4=xo[22]; //用LED显示数据状况
l5=xo[23];
l6=xo[24];
l7=xo[25];
l8=xo[26];
TR0=0; //关闭定时器
EX0=1; //打开外部冲断,
}
void tin()
{
TMOD=0x01;
TH0=(65536-1680)/256;
TL0=(65536-1680)%256;
ET0=1;//开定时器1冲断。
TR0=1;//启动定时器1。=0时,停止定时。
EX0=0;//关外部冲断0。
}
void xx()
{
TR0=0; //关闭定时器
while(p30==1); //等待高电平过。
while(p30==0); //等待低电平过。<0.56ms>
TH0=(65536-1680)/256; //重装初值,
TL0=(65536-1680)%256;
TR0=1; //启动定时器
s=1; //经过引导码9MS和起始码4.5MS 和0.56MS后 给读取数据的条件。
}
void main() //主函数
{
EA=1;//开总冲断
EX0=1;//开外部冲断0。
while(1);
}
void exter0() interrupt 0 //外部冲断函数<P3.2>
{
tin();
}
void timer0() interrupt 1
{
TH0=(65536-1680)/256; //重新初值。(24MHZ时,=0.84ms)
TL0=(65536-1680)%256;
s1++;
if (s1==15)//等待12.6ms《0.84*15=12.6》
xx();
if (s==1) //如果读取条件成立
{
if (p30==0) //0.56ms低电平完后,在过0.84ms时判断红外波形的高低电平,来确定数据1与0/
xo[n]=0; //得到的数据,1或0,装进xo[]例表中。n是要装的指针位置
else
xo[n]=1;
n++;
if (n==39) //我这里读取39次数据,本来是才有32个数据,但多读几次当一个小延时吧,稳定点,
{
n=0;
s1=0;
s=0; //去掉读取条件
ll(); //用LED显示某8个数据,
}
}
}
解码的关键是如何识别零和一:
“0”和“1”都是以0.56ms 低电平开始的,不同的是高电平
宽度不同,“0”为0.56ms“1”为1.168ms,所以必须根据高电平
宽度来区别“0”和“1”。
如果从0.56ms 低电平过后,开始延时,0.56ms 后,若读到的
电平为低,说明该位为零,反之则为一,可靠其间,延时必须比
0.56ms'长一些,又不能超过1.12ms,否则如果该位为零,读到的
已是下一位高电平,因此取(1.12+0.56)/2=0.84ms 最为可靠,一
般取0.84ms 左右均可。根据码的格式,应该等待9ms 起始码和
4.5ms 结束码完成后才能读码。


表示看不懂
表示不好用,没什么反应。
这是我写的,交流一下。
#include<reg52.h>
#include<intrins.h>
typedef unsigned char uchar; //4个字节 32位
typedef unsigned int uint; //2个字节 16位
typedef unsigned long ulong; //1个字节 8位
sbit P27 = P2^7;
sbit P26 = P2^6;
sbit BEEP = P3^6;
uint time; //下降沿时间
ulong k32; //32位按键码
ulong ck32; //复制32位按键码
uint k16; //16位功能码及反码
uchar L8; //低8位, 功能反码
uchar H8; //高8位, 功能码
uchar cL8; //复制低8位,
uchar cn; //cn用于记录接收到的数据位 34
uchar count,i,n;
uchar code s8[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //0~F
uchar dis_data[2]; //P27,P26显示0~F
void display()
{
ET0 = 0; //关T0
dis_data[1] = H8&0x0f; //取低4位
H8 = H8>>4; //取高4位
dis_data[0] = H8&0x0f; //显示在P26
ET0 = 1; //开T0
}
void decode() //取数
{
k16 = (ck32>>16); //32位按键码右移16,高16位也就是功能码
L8 = k16>>8; //功能码右移8位,得到功能反码
H8 = k16&0X00FF; //高8位反码,功能码
cL8 = L8; //低8位取反
if(~cL8!=H8) //~L8不等于H8
{
ck32 = 0; //错误过滤
H8 = cL8 = 0; //清0,等待
}
else
{
display(); //通过验证,可以显示
BEEP = 0; //回应
for(i=0;i<20;i++);
BEEP = 1;
}
}
void main()
{
TMOD = 0x11; //定时器0、1工作方式1
IT0 = 1; //下降沿触发
EA = 1; //T1计算下降沿时间,
ET0 = 1;
EX0 = 1;
TR0 = 1;
while(1);
}
void int0()interrupt 0 using 1 //遥控中断处理函数
{
TR1 = 0; //关T1、得到两个下降沿之间的时间
time/*下降沿时间*/ = (uint)TH1*256+TL1;
TH1 = 0;
TL1 = 0;
TR1 = 1; //开T1、开始计算两个下降沿之间的时间
if(time>9000&&time<17000) //遇到引导码,就把cn置1,k32清0
{ //(9+4.5ms)/1.085us*1000=1244 加减400.
cn = 1;
k32 = 0;
}
if(cn<34&&cn>0)
{
k32 >>= 1;
if(time>500&&time<1300) //1.125ms ‘0’ (0.56+0.565ms)/1.085*1000=1036 加减100
k32 = k32|0x00000000; //取0
if(time>1500&&time<3000) //2.25ms ‘1’ (0.56+1.685ms)/1.085*1000=2072 加减100
k32 = k32|0x80000000; //取1
cn++; //每次移位cn++
}
if(cn==34) //读完32位按键码,就有新码产生
{
ck32 = k32; //k32赋给ck32,准备清0
decode(); //解码
cn = 0; //清0
}
}
void time0()interrupt 1 using 2
{
static uchar i=0;
if(i>=2) i = 0;
P2 = 0xff; P0 = 0xff;//消隐
P2 = _crol_(0xbf,i);
P0 = s8[dis_data[i]]; //显示数据
i++;
TH0 = (65536-1)/256;
TL0 = (65536-1)%256;
}
可以直接在学习板上用吗。天祥学习板
