打印
[51单片机]

新人问红外(菜鸟卡住被虐心,望高手指教)

[复制链接]
5102|41
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
新人一枚,研究红外有一阵子了,从刚开始的什么都不懂,到现在了解了皮毛。现在遇到问题卡住了,特来求助,希望大神不吝惜赐教!
先说一下我现在的状况:首先我想实现红外通信。有两个小模块红外发射和接收,这两个模块都是很简单的那种,没有电路的38K载波信号,得通过软件实现。我用的是51单片机。接收的程序我用的是买来开发板的程序,现在大概能看懂,但是自己还没尝试写过解码程序。另外自己写了个红外发射的程序原本觉得应该是个很简单就能完成的程序,可没想到运行起来后接收不到。后来改了改接收的程序后能接收到了,可一直显示一个固定值(无论我怎么改要发射的数据)。
再来说下我的程序:接收程序解码部分的大概思路是通过判断两个下降沿的时间间隔来确定0、1。同时将解码出来的数据通过串口打印出来,就是赋值给SBUF,然后打印出来。
发射程序我用的是TO中断来实现38K的载波信号,初值给的是FFF2,晶振12M,这样就是13US中断一次,每次我从新赋值后会执行a=~a和counter++的命令,这样就产生了占空比1:2的38K信号。发送数据时执行TX=y&a(TX就是发送端,y是要发送的数据0还是1),counter用来计时,而发送高低电平的时间则用counter_end(每次都会从新赋值)来限制。通过if(counter<counter_end)语句来控制发送数据0、1的时间。
现在遇到的问题大概有几个:
1、红外接收程序中是四个打印命令可下载后实际操作每次只会打印出三个字符。而如果屏蔽掉一个打印命令后在操作打印的数据会出错,对于串口打印不是很懂?
2、红外发射部分,我设置FFF2这样可以么,这样是不是精度不高,太过频繁的进入中断会有什么不良影响么?个人认为接收不到是因为时间控制的不是很准确,大家用软件的时候都是怎么控制0,1发送的时间的?
3、最后想问下用硬件大家都怎么搭建38K的载波信号,除了555还有什么?
附:我尝试加大接收程序中的接收时间宽度也没有有达到效果。现在还不太会传文件,过一阵子我把整个程序发上来大家帮忙看看。

相关帖子

沙发
ningling_21| | 2014-8-28 12:01 | 只看该作者
1、红外接收程序中是四个打印命令可下载后实际操作每次只会打印出三个字符。而如果屏蔽掉一个打印命令后在操作打印的数据会出错,对于串口打印不是很懂?
必须安装说明来操作。

2、红外发射部分,我设置FFF2这样可以么,这样是不是精度不高,太过频繁的进入中断会有什么不良影响么?个人认为接收不到是因为时间控制的不是很准确,大家用软件的时候都是怎么控制0,1发送的时间的?
可以用定时器模式2,调整初始值,配合示波器产生38K载波。 0,1可以用延时或定时器产生对应时间。

使用特权

评论回复
板凳
d865841995|  楼主 | 2014-8-28 12:45 | 只看该作者
ningling_21 发表于 2014-8-28 12:01
1、红外接收程序中是四个打印命令可下载后实际操作每次只会打印出三个字符。而如果屏蔽掉一个打印命令后在 ...

按照说明来操作?
模式二是8位重装的吧,和我这个16位重装的效果不一样么?不就是初值不一样么?(新人不懂)。我是担心初值比较大,这样精度上是不是就不高了,会很影响发射效果,毕竟所有的时间都是以定时器这个为基准的!手头无示波器.......

使用特权

评论回复
地板
wh6ic| | 2014-8-28 14:00 | 只看该作者
  红外使用38K是因为常见的接收头形成了标准,里面都集成了红外透光、光电管、隔直、38KHz的滤波、放大、积分、比较器等一系列功能在里面,抗干扰能力比较强,新手不要轻易自己做,建议选择合适的38KHz接收头。接收头上接收到的可能是比较弱的信号,普通红外接收头很难还原得到与发射同样的占空比波形。
  发射部分可以自己做,只要满足38KHz的调制就行,不过要想发射距离远,一般的做法是用比较窄的占空比,很高的发射电流。有兴趣可以拆个红外的遥控器,通常是一粒8050,加两三欧的小阻值电阻,直接3V电池驱动,新电池瞬态电流可能远超100mA,旧电池也可以轻松做到有效距离超过5米。

使用特权

评论回复
5
d865841995|  楼主 | 2014-8-28 15:44 | 只看该作者
wh6ic 发表于 2014-8-28 14:00
红外使用38K是因为常见的接收头形成了标准,里面都集成了红外透光、光电管、隔直、38KHz的滤波、放大、积 ...

我接收用的是一体化接收头,你说的都很对,但是我的问题还是没解决,能帮帮忙么?

使用特权

评论回复
6
gx_huang| | 2014-8-28 16:10 | 只看该作者
帮忙的含义是帮忙解决某个具体的问题,不是帮忙你从头学习,帮你设计。
你自己研究比较长一段时间后,再有什么问题,单独提出来解决。
比如分成几个小问题。

使用特权

评论回复
7
d865841995|  楼主 | 2014-8-28 16:34 | 只看该作者
gx_huang 发表于 2014-8-28 16:10
帮忙的含义是帮忙解决某个具体的问题,不是帮忙你从头学习,帮你设计。
你自己研究比较长一段时间后,再有 ...

呵呵,你有看我写的么!

使用特权

评论回复
8
gx_huang| | 2014-8-28 16:39 | 只看该作者
d865841995 发表于 2014-8-28 16:34
呵呵,你有看我写的么!

看了,太长了。
1、用MCU不加38K振荡,直接MCU产生脉冲波形,是可以的。
2、MCU接收解码一体化遥控信号,也是可以的。
你先一个一个单独实现它。同时实现,几乎不可能。半双工可以的。
不要把串口打印绞在一起。

使用特权

评论回复
9
gx_huang| | 2014-8-28 16:58 | 只看该作者
你的MCU要比较快才可以,要1US可以跑5条左右指令的才好。

使用特权

评论回复
10
a12345678| | 2014-8-28 17:08 | 只看该作者
楼主用STC15系列单片机即可,工作频率选择接近最大的25-30MHz为好,这样有较多的时间处理,也比较好实现

使用特权

评论回复
11
wh6ic| | 2014-8-28 17:13 | 只看该作者
d865841995 发表于 2014-8-28 15:44
我接收用的是一体化接收头,你说的都很对,但是我的问题还是没解决,能帮帮忙么? ...

看你的描述,应该是用的51核的单片机。。
12MHz的51定时12X26T,产生38KHz误差倒是不大,可以接受。
如果是12T的51核,用中断软件来做,软件的办**造成输出间隔误差比较大,是会影响结果......
如果是1T的51核,中断服务函数写简单点,软件误差可能可以接受
不少现在能买到的51,定时器可以实现自动输出翻转功能,不需要软件介入;可以看看你用的51有没有PWM,可以用比较输出功能,这样可以方便做到占空比可调。

使用特权

评论回复
12
d865841995|  楼主 | 2014-8-30 12:59 | 只看该作者
#include <reg52.h>
sbit TX=P0^0;          //输出位
unsigned int y=0;//要输出的二进制数0,1标志位
unsigned int a=0;//38K输出标志位
unsigned char data_shuju;//要发送的数据
unsigned int counter=0;         //中断计数标志
unsigned int counter_end;                //计数结束标志位

void init_timer0()
{
        TMOD&=0XFD;                  //T0工作在方式一
        TMOD|=0x01;
        TH0=0xFF;                  //13us一个周期
        TL0=0xF2;
        EA=1;                  //总中断打开
        ET0=1;                  //定时器中断打开
        TR0=1;                   //定时器开关打开
}
void timer0_38K() interrupt 1         //38K调频信号
{
        TH0=0xFF;
        TL0=0xF2;
        a=~a;                                //一个周期反转一次
        counter++;
}
void send_byte(y,counter_end)         //发送0,1位
        {
                counter=0;
                while(counter<counter_end)
                        {
                                TX=y&a ;
                        }
        }
void send_data(data_shuju)                  //发送字节
{
        if((data_shuju&0x01)==0x01)        //        判断二进制数个位为1还是0
        {
                 send_byte(1,43);          //560us/13us=43
                 send_byte(0,43);
        }
        else
        {
                send_byte(1,43);
                send_byte(0,130);           //(2250-560)/13=130
        }
        data_shuju>>=1;       
}
void main()
{
        while(1){
                 init_timer0();       
                 send_byte(1,700);     //引导码          9000/13=692
                 send_byte(0,350);     //引导码          4500/13=346
                 send_data(0x0F);                   // 地址码   随便写的
                 send_data(0xF0);                   // 地址反码
                 send_data(0xFF);                   // 数据码
                 send_data(0xFE);                   // 数据反码
                 }

}


这是我红外发射的程序,大家帮忙看下,哪里有问题。本人菜鸟用的是STC89C52RC,晶振12M。不知道这样可以发射出来么。手边有一个红外避障的小模块,上面的接受头接收到红外信号小灯会闪烁,用遥控器发射小灯会变化,可用我的程序和发射模块就不好用了!

使用特权

评论回复
13
d865841995|  楼主 | 2014-8-30 13:04 | 只看该作者
这是我在红外发射的电路图(万用表量出来的)。还有就是红外的协议了。

QQ截图20140830130205.png (18.08 KB )

QQ截图20140830130205.png

QQ截图20140830130148.png (34.02 KB )

QQ截图20140830130148.png

使用特权

评论回复
14
d865841995|  楼主 | 2014-8-30 13:08 | 只看该作者
gx_huang 发表于 2014-8-28 16:39
看了,太长了。
1、用MCU不加38K振荡,直接MCU产生脉冲波形,是可以的。
2、MCU接收解码一体化遥控信号, ...

接受部分我先换成了一个红外避障的小模块用来观察有没有接收到红外信号。你看现在我这样是哪里出错了?

使用特权

评论回复
15
d865841995|  楼主 | 2014-8-30 13:08 | 只看该作者
a12345678 发表于 2014-8-28 17:08
楼主用STC15系列单片机即可,工作频率选择接近最大的25-30MHz为好,这样有较多的时间处理,也比较好实现 ...

饿,这个晶振我用12M的一定不可以么?

使用特权

评论回复
16
d865841995|  楼主 | 2014-8-30 13:33 | 只看该作者
wh6ic 发表于 2014-8-28 17:13
看你的描述,应该是用的51核的单片机。。
12MHz的51定时12X26T,产生38KHz误差倒是不大,可以接受。
如果 ...

额,说实话,没太懂你的意思,新人不慎很懂,嘿嘿。
第一句:你说的12X26T什么意思?我产生38K用的是定时器13US一个周一反转一次,也就是占空比1:2的载波。
第二句:软件的成什么造成误差比较大?
第三句:你说的1T是一个机器周期就是一个时钟周期的一次么?
最后我用的是STC89C52RC,手册有,不过我感觉看的不是很懂的样子。似乎这个型号是12T的对么?

使用特权

评论回复
17
ningling_21| | 2014-8-30 14:21 | 只看该作者
d865841995 发表于 2014-8-30 13:33
额,说实话,没太懂你的意思,新人不慎很懂,嘿嘿。
第一句:你说的12X26T什么意思?我产生38K用的是定时 ...

第一句:你说的12X26T什么意思?我产生38K用的是定时器13US一个周一反转一次,也就是占空比1:2的载波。

这个38K的频率准确吗,误差多少?

使用特权

评论回复
18
gx_huang| | 2014-8-30 14:27 | 只看该作者
这个程序肯定有问题的了,输出的波形肯定不是你想要的波形了。
定时器中断,不需要再次赋值定时器寄存器的,定时器中断里给a取反,主程序里取这个值,波形不对了。
要考虑程序的运行时间。
12MHz,12T的话,1US,光定时器中断执行时间就很可能超过0X100-0XF2=14个机器周期了。
主程序都只能执行1条指令然后马上近中断了。
实在不行,先老老实实的不用中断,直接延时输出波形,可以调整延时的时间满足波形要求。

使用特权

评论回复
19
wh6ic| | 2014-8-30 14:30 | 只看该作者
d865841995 发表于 2014-8-30 13:33
额,说实话,没太懂你的意思,新人不慎很懂,嘿嘿。
第一句:你说的12X26T什么意思?我产生38K用的是定时 ...

1、13uS X 2 = 26,一条指令12个时钟周期,你产生的是13uS + 13uS的占空比为1:1
2、软件中断服务响应时间是不确定的,所以你出来的波形会有宽有窄,误差
3、是的。
  你用的片子支持 6T 模式,另外它的 T2 支持 PWM 模式,可以用PWM来做38KHz,见T2MOD寄存器的T2OE标志位说明。

使用特权

评论回复
20
coody| | 2014-8-30 14:48 | 只看该作者
以下的描述,跟用什么MCU无关,效果一样。
在所有无线遥控中,红外收发是最简单的,只要按其时序参数,并允许一定的误差来处理,最经典的就是NEC码,非常的容易可靠发送接收,一般超过10米距离。
接收我一直使用100us左右查询,比外中断接收简单得多(用在PWM控制的灯具尤其明显),中断对us级的干扰都能响应,所以你得识别好,而查询一般不需要,可以很简单的就引入去毛刺的几句代码。

发送载波38KHZ还用外部IC发生555的,我认为是落后的设计(现在的MCU基本都能发出这个信号),MCU直接再不调制38K发出。占空比最好是1/3~1/5。
接收头如果是脉冲型的,则不能连续接收38KHZ,这个新手要注意,别拿着接收头找卖家说:你的接收头垃圾,接收不了。。。:lol

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

54

主题

293

帖子

6

粉丝