/***************************************************************************
标题: 红外线接收实验引用延时
效果: 运行程序,按遥控器按键,在数码管上显示相应的地址码-控制码(以16进制显示)
分两段,前段是地址码,后段为控制码,用点隔开,显示两字节,忽略反码
工作于:i51开发板
******************************************************************************/
//头文件:
#include "reg51.h"
//IO引脚定义:
sbit hwx=P3^3; //红外接收数据引脚,
sbit SMG_q = P1^0; //定义数码管阳级控制脚(千位)
sbit SMG_b = P1^1; //定义数码管阳级控制脚(百位)
sbit SMG_s = P1^2; //定义数码管阳级控制脚(十位)
sbit SMG_g = P1^3; //定义数码管阳级控制脚(个位)
/********数据定义*************************************************************/
code unsigned char table[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,//共阳数码管段值表 0-9
0x88,0x8c,0xc6,0xa1,0x86,0x8e}; //共阳数码管段值表 a-f
unsigned char l_posit=0; //显示位置
unsigned char ly_disdate[4]={0,0,0,0}; //显示缓冲
unsigned char ly_lhj[4]={1,2,3,4}; //保存红外线输入的四个字节数据
unsigned char ly_ct=0;
bit ly_flag=1; //成功接收标志
//函数声明:
void display();//定义显示函数,直接显示缓冲区数值
void delay(void);
void delay100us(void);
/***********主函数开始********************************************************/
void main(void)
{
EA=1; //首先开启总中断
EX1=1; //开启外部中断1,红外接收数据引脚
IT1=1; //设置成下降沿触发方式
delay100us();
while(1)
{
if(ly_flag)//接收成功处理显示缓冲,以16进制显示
{
ly_flag=0;
ly_disdate[0]=ly_lhj[0]/16;
ly_disdate[1]=ly_lhj[0]%16;
ly_disdate[2]=ly_lhj[2]/16;
ly_disdate[3]=ly_lhj[2]%16;
}
display();//显示缓冲内容
delay100us();
}
}
/***********外中断1入口函数,P33引脚,红外线接收IC数据脚**************************/
void hongwai(void) interrupt 2
{
unsigned char i,ia,N=0;
/***********开始接收四个字节内容**************************************/
for(i=0;i<4;i++)
{
for(ia=0;ia<8;ia++)
{
while(!hwx); //低电平开始,不处理只等待高电平接收
ly_ct=0;
while(hwx)//高电平开始,
{
delay100us();
if(ly_ct>20)
return;
}
//高电平结束,判断数据1或0向变量移入
ly_lhj[i]>>=1; //数据由高位移入低位
if (ly_ct>10)
{
ly_lhj[i] |= 0x80;
}
}
}
ly_flag=1; //接收成功
TF1=0;
}
//显示函数,参数为显示内容
void display()
{
P2=0XFF; //
switch(l_posit){
case 0: //选择千位数码管,关闭其它位
SMG_q=0;
SMG_b=1;
SMG_s=1;
SMG_g=1;
P2=table[ly_disdate[0]]; //输出显示内容
break;
case 1: //选择百位数码管,关闭其它位
SMG_q=1;
SMG_b=0;
SMG_s=1;
SMG_g=1;
P2=table[ly_disdate[1]]&0x7f; //加上小数点
break;
case 2: //选择十位数码管,关闭其它位
SMG_q=1;
SMG_b=1;
SMG_s=0;
SMG_g=1;
P2=table[ly_disdate[2]];
break;
case 3: //选择个位数码管,关闭其它位
SMG_q=1;
SMG_b=1;
SMG_s=1;
SMG_g=0;
P2=table[ly_disdate[3]];
break;
}
l_posit++; //每调用一次将轮流显示一位
if(l_posit>3)
l_posit=0;
}
void delay100us(void)
{
unsigned char i=15;
while(i--);
ly_ct++;
}
线都按手册要求接好了,现在数码显示管一直显示01.03,我用遥控器给红外接收器发命令,数显管没任何反应。没有示波器,我用万用表接在P3^3上测电压,可以看到电压波动。不发命令的时候,是高电平,接近5V,发命令就会跳动,到3.几V,应该是红外接收器接到了命令,并且也往P3^3脚上输出了,但是C51没有正确处理这个信号。
请高人帮忙看看什么问题,感谢!
14 个解决方案
#1
可能原因:
1.硬件电路没有调试通过。
适当调整解码电路,增加带宽。
2.软件发送数据调制信号不规整。就是无法让硬件正常解码。
一般的,通信自调制,采用汇编比较好。抗干扰性强,代码容量小,1K以下ROM即可解决。
1.硬件电路没有调试通过。
适当调整解码电路,增加带宽。
2.软件发送数据调制信号不规整。就是无法让硬件正常解码。
一般的,通信自调制,采用汇编比较好。抗干扰性强,代码容量小,1K以下ROM即可解决。
#2
Ly flag 初始化应该为0 上电时最好加上一个显示特殊符号的函数
测试是否进入到中断函数
测试是否进入到中断函数
#3
不知道你要做到那一步?
如果是一劳永逸的方式, 把你的代码全删了.
先开定时器, 设定一个基本的时间基准, 比如是1us, 在这个基础上对红外信号进行采样.
并一段设定的时间(1ms)内, 返回采样值.
如果是一劳永逸的方式, 把你的代码全删了.
先开定时器, 设定一个基本的时间基准, 比如是1us, 在这个基础上对红外信号进行采样.
并一段设定的时间(1ms)内, 返回采样值.
#4
真的是那个ly_flag的原因,我改过来之后就可以了。
但是程序里面还是有几个地方不是太明白。
1,
ly_disdate[0]=ly_lhj[0]/16;
ly_disdate[1]=ly_lhj[0]%16;
ly_disdate[2]=ly_lhj[2]/16;
ly_disdate[3]=ly_lhj[2]%16;
这里只取了第0 和 第2字节,那第一字节和第三字节都是什么内容呢,不重要吗?
2,就是代码里面以??????开头的三个地方
for(ia=0;ia<8;ia++)
{
while(!hwx); //低电平开始,不处理只等待高电平接收
ly_ct=0;//???????这个计数器是做什么用的
while(hwx)//高电平开始,
{
delay100us();
if(ly_ct>20)//????????这里的大于20就return是根据什么做出的?
return;
}
//高电平结束,判断数据1或0向变量移入
ly_lhj[i]>>=1; //数据由高位移入低位
if (ly_ct>10) //???????为什么是大于10就认为是有效的1?
{
ly_lhj[i] |= 0x80;
}
}
感谢
#5
这里只取了第0 和 第2字节,那第一字节和第三字节都是什么内容呢,不重要吗?
----------\
这个和接受的数据格式有关 应该是第一字节和第三字节或许是年份把 自己查一下
----------\
这个和接受的数据格式有关 应该是第一字节和第三字节或许是年份把 自己查一下
#6
P3^3管脚上最低电压只有3V多,单片机的输入IO并不会把这个电平当成低电平,即不会识别为0,仍然认为是1。
硬件的问题,红外接收头的输出电路再稍微改一下,把低电平拉下来
硬件的问题,红外接收头的输出电路再稍微改一下,把低电平拉下来
#7
这里只取了第0 和 第2字节,那第一字节和第三字节都是什么内容呢,不重要吗?
、、、、
解出的码里好像有生产公司的厂家码、数据码和数据反码,对于普通用户来说只有数据码有用
、、、、
解出的码里好像有生产公司的厂家码、数据码和数据反码,对于普通用户来说只有数据码有用
#8
你可以直接显示一下第一和第三字节的码,第一字节与第零字节的码、第三字节与第二字节的码应该都互为反码。
#9
红外发射端请输出38k频率 否则不能正常识别
#10
用状态机写吧。。。这个方法不好使了。。。单片机计时,太占用资源了。。。。其他的东西都处理不了了。。。响应不过来了都
#11
软件发送数据调制信号不规整。就是无法让硬件正常解码。
#12
NEC协议?
#13
第1个字节和第3个字节的内容分别是第0个字节和第2个字节的反码,所以没用。
#14
硬件电路没设计好吧,3V会被认为是高电平,低电平我记得应该是0.7V以下,所以没有变化,需要修改硬件电路,可以使用电阻分压或者使用三极管实现
#1
可能原因:
1.硬件电路没有调试通过。
适当调整解码电路,增加带宽。
2.软件发送数据调制信号不规整。就是无法让硬件正常解码。
一般的,通信自调制,采用汇编比较好。抗干扰性强,代码容量小,1K以下ROM即可解决。
1.硬件电路没有调试通过。
适当调整解码电路,增加带宽。
2.软件发送数据调制信号不规整。就是无法让硬件正常解码。
一般的,通信自调制,采用汇编比较好。抗干扰性强,代码容量小,1K以下ROM即可解决。
#2
Ly flag 初始化应该为0 上电时最好加上一个显示特殊符号的函数
测试是否进入到中断函数
测试是否进入到中断函数
#3
不知道你要做到那一步?
如果是一劳永逸的方式, 把你的代码全删了.
先开定时器, 设定一个基本的时间基准, 比如是1us, 在这个基础上对红外信号进行采样.
并一段设定的时间(1ms)内, 返回采样值.
如果是一劳永逸的方式, 把你的代码全删了.
先开定时器, 设定一个基本的时间基准, 比如是1us, 在这个基础上对红外信号进行采样.
并一段设定的时间(1ms)内, 返回采样值.
#4
Ly flag 初始化应该为0 上电时最好加上一个显示特殊符号的函数
测试是否进入到中断函数
真的是那个ly_flag的原因,我改过来之后就可以了。
但是程序里面还是有几个地方不是太明白。
1,
ly_disdate[0]=ly_lhj[0]/16;
ly_disdate[1]=ly_lhj[0]%16;
ly_disdate[2]=ly_lhj[2]/16;
ly_disdate[3]=ly_lhj[2]%16;
这里只取了第0 和 第2字节,那第一字节和第三字节都是什么内容呢,不重要吗?
2,就是代码里面以??????开头的三个地方
for(ia=0;ia<8;ia++)
{
while(!hwx); //低电平开始,不处理只等待高电平接收
ly_ct=0;//???????这个计数器是做什么用的
while(hwx)//高电平开始,
{
delay100us();
if(ly_ct>20)//????????这里的大于20就return是根据什么做出的?
return;
}
//高电平结束,判断数据1或0向变量移入
ly_lhj[i]>>=1; //数据由高位移入低位
if (ly_ct>10) //???????为什么是大于10就认为是有效的1?
{
ly_lhj[i] |= 0x80;
}
}
感谢
#5
这里只取了第0 和 第2字节,那第一字节和第三字节都是什么内容呢,不重要吗?
----------\
这个和接受的数据格式有关 应该是第一字节和第三字节或许是年份把 自己查一下
----------\
这个和接受的数据格式有关 应该是第一字节和第三字节或许是年份把 自己查一下
#6
P3^3管脚上最低电压只有3V多,单片机的输入IO并不会把这个电平当成低电平,即不会识别为0,仍然认为是1。
硬件的问题,红外接收头的输出电路再稍微改一下,把低电平拉下来
硬件的问题,红外接收头的输出电路再稍微改一下,把低电平拉下来
#7
这里只取了第0 和 第2字节,那第一字节和第三字节都是什么内容呢,不重要吗?
、、、、
解出的码里好像有生产公司的厂家码、数据码和数据反码,对于普通用户来说只有数据码有用
、、、、
解出的码里好像有生产公司的厂家码、数据码和数据反码,对于普通用户来说只有数据码有用
#8
你可以直接显示一下第一和第三字节的码,第一字节与第零字节的码、第三字节与第二字节的码应该都互为反码。
#9
红外发射端请输出38k频率 否则不能正常识别
#10
用状态机写吧。。。这个方法不好使了。。。单片机计时,太占用资源了。。。。其他的东西都处理不了了。。。响应不过来了都
#11
软件发送数据调制信号不规整。就是无法让硬件正常解码。
#12
NEC协议?
#13
Ly flag 初始化应该为0 上电时最好加上一个显示特殊符号的函数
测试是否进入到中断函数
真的是那个ly_flag的原因,我改过来之后就可以了。
但是程序里面还是有几个地方不是太明白。
1,
ly_disdate[0]=ly_lhj[0]/16;
ly_disdate[1]=ly_lhj[0]%16;
ly_disdate[2]=ly_lhj[2]/16;
ly_disdate[3]=ly_lhj[2]%16;
这里只取了第0 和 第2字节,那第一字节和第三字节都是什么内容呢,不重要吗?
2,就是代码里面以??????开头的三个地方
for(ia=0;ia<8;ia++)
{
while(!hwx); //低电平开始,不处理只等待高电平接收
ly_ct=0;//???????这个计数器是做什么用的
while(hwx)//高电平开始,
{
delay100us();
if(ly_ct>20)//????????这里的大于20就return是根据什么做出的?
return;
}
//高电平结束,判断数据1或0向变量移入
ly_lhj[i]>>=1; //数据由高位移入低位
if (ly_ct>10) //???????为什么是大于10就认为是有效的1?
{
ly_lhj[i] |= 0x80;
}
}
感谢
第1个字节和第3个字节的内容分别是第0个字节和第2个字节的反码,所以没用。
#14
硬件电路没设计好吧,3V会被认为是高电平,低电平我记得应该是0.7V以下,所以没有变化,需要修改硬件电路,可以使用电阻分压或者使用三极管实现