yihui184 发表于 2012-10-11 23:30:54

请教学习型遥控器,波形拷贝式,发射和接收的问题。

本帖最后由 yihui184 于 2012-10-12 09:35 编辑

做遥控器做了三个月来了,
还没有做到让自己满意的地步!特地来这里请教高人,
帮助帮助我,鳖的急了,真是有点恨自己了,
怎么就做不出来,在网上找资料感觉没有什么收获,这么久了,
现在我就想快点把这个学习型遥控器做出来,
尽快,我再也等不了,再拖,我自己都原谅不了我自己,
很郁闷,真的.现在确实是碰到了瓶颈了!

我做的第一个遥控器程序是专门解NEC的,参考了本论坛楼主BXAK的程序.





第二个做的是看到51hei论坛上的一个学习型遥控器,我把它该造成了存入eeprom中去,但是感觉这个路波型的学习型遥控器,感觉时间不是很准确,不是用定时器录波的,感觉不可靠,但是试了试所有的身边的电视都可以实现
接收码,再发射码都能控制电视。代码如下:有遇到点问题,里面都有注释:



第三个是我现在做的,根据百度文库上面的一个文章写的,文章如下:




我写的程序如下:
/*
   时间:2012.10.10
   功能:学习型遥控器
*/

#include <reg52.h>

#define uchar unsigned char   
#define uintunsigned int
#define ulong unsigned long

sbitstudy_key=P1^0;                      //学习按键
sbitstudylamp=P2^1;                             //学习状态指示灯
sbitsend_key=P1^1;                      //发射键
sbitremotein=P2^0;                      //遥控信号输入口
sbitremoteout= P3^4;                  // 遥控信号输出口
sbittxkey=P1^1;                         //待定
bit   flag=0;

uchar dat;                            //用于记录高低电平的记时值!80个.一的电平要2个字节.


void Delay1ms(uint t)
{
                uint x,y;
        for(x=0;x<t;x++)
           for(y=0;y<120;y++);
}

void delete_dat()
{
               uchar t;
        for(t=0;t<80;t++)
        {
          dat=0;
        }
}

void init_io()
{
               TMOD=0x21;
        TH1=0xF3;                              
        TL1=0xF3;
        remotein=1;
        remoteout=1;
        studylamp=0;       
        EA=1;
}


void main()
{
   uchar i=0;
   init_io();
   delete_dat();
   while(1)
   {

           if(!study_key)                                                                            //学习键按下,开始接收红外码.用于记录整个码的高低电平.
           {
                          Delay1ms(10);
                  if(!study_key)
                  {
                                 while(!study_key);
                                    while( remotein );                   //当红外接收端为 1 时一直等待,为 0 跳入循环.开始接收程序.
                                      while(1)
                                {                       
                                  TH0=0;                              
                                  TL0=0;
                                  TR0=1;
                                  while(!remotein);                         //当为 1 时 跳出循环.
                                  TR0=0;
                                  dat=TH0;                           //保存 0的记时时间.
                                  dat=TL0;
                                  TH0=0;                                    //重新赋初值.
                                  TL0=0;               
                                  TR0=1;
                                  while(remotein)                      //当接收的时候,1 的值是否有溢出,有的话,跳出当前循环,给一个标志位,用于跳出大循环,不再接收.
                                  if(TF0)
                                  {
                                            TF0=0;
                                            TR0=0;
                                              flag=1;
                                              dat=0;
                                            studylamp=1;
                                            break;
                               }
                               if(flag)
                                      break;
                               TR0=0;
                               dat=TH0;
                                         dat=TL0;                  
                        }
                  }
           }
       
           if(!send_key)                                                //发射键按下,用于发射接收到的码的高低电平.
           {
                          Delay1ms(10);
                  if(!send_key)
                  {
                          while(!send_key);
                          if(flag)
                          {          
                                          i=0;                                                                                             
                                          ET1=1;                                                                                 //把发送载波的中断开启.
                                          while(1)
                                  {                       
                                               TH0=256-dat;                                                       //先发 1 ,给定时器赋初值,取反,                                          
                                               TL0=256-dat;
                                               TR0=1;
                                               TR1=1;                                                                     //启动载波
                                        while(!TF0);                                                               //溢出后,发下一组.
                                               TF0=0;
                                               TR0=0;
                                               TR1=0;
                                        remoteout=0;                                                      //发送 低 电平
                                        TH0=256-dat;                                                 //发 0
                                        TL0=256-dat;
                                       if( dat == 0 )                                                   //当发的数据中没有植,为0时,停止发送.
                                       {
                                                    delete_dat();
                                              flag=0;
                                                    studylamp=0;
                                             ET1=0;
                                             break;
                                        }
                                        TR0=1;
                                        while(!TF0);
                                        TF0=0;       
                                        TR0=0;                                                                                 
                                }
                          }
                  }
           }

   }
      
}

//40KHz发生器      
void time_intt1(void) interrupt 3
{
   remoteout=~remoteout;
}
请问一下:

我上面的这个程序,我根据PDF那份文档,写的程序:

看了这么多程序,我觉得要做学习型遥控器,我现在是要做记录波形的这种,我觉得只要把高低电平保存起来就可以了嘛,
我上面的这个程序,根据上面那份PDF文档写的,我感觉逻辑上没有错,可是就是控制不了,硬件上面没有问题,希望有经验的
大侠能教教我。

帮我看下我上面写的那个接收码和发射码,哪里是不是有问题呢?还是思路有问题呢?

yihui184 发表于 2012-10-12 07:37:12

自己顶一下!

yihui184 发表于 2012-10-12 07:39:47

请大家看看,给点建议!

yihui184 发表于 2012-10-12 07:47:09

希望大家可以看看我的问题!

benfenshusheng 发表于 2012-10-12 08:34:12

问题太抽象拉,同学

perfugee 发表于 2012-10-12 08:39:15

真不知道LZ想问什么东西。

yihui184 发表于 2012-10-12 09:08:00

恩,好像是,我修改一下。

xiaozuowei118 发表于 2012-10-12 09:33:06

估计是载波频率不对,而不是编码的问题,建议楼主对比编码输出后的调制电路。

yihui184 发表于 2012-10-12 09:38:22

xiaozuowei118 发表于 2012-10-12 09:33 static/image/common/back.gif
估计是载波频率不对,而不是编码的问题,建议楼主对比编码输出后的调制电路。 ...

我上面打包的那个程序也是这个频率,可以发射,只不过现在我想用另外一种方式处理 ,可是不行哇,你做过么?朋友。谢谢你的建议。

yihui184 发表于 2012-10-12 09:41:01

在网上找资料,想找一点基于这种记录波形和发射波形的核心代码都没找到,很多时间都花在找资料上,感觉时间很浪费,心痛哇,我不想再这样找下去了,求帮助,求指点,以后我也常来论坛帮忙解决我能帮助解决的问题。

xiaozuowei118 发表于 2012-10-12 09:42:16

我原来做过电视机的自动学习遥控器,只是好久了,不太记得了,载波频率好像是38KHZ吧,要去查查才知道

xiaozuowei118 发表于 2012-10-12 09:43:49

我原来是把标准的遥控器用逻辑分析议分析出来,人为解码做的。后面的调制电路也比较简单,跟电视机遥控做的差不多

xiaozuowei118 发表于 2012-10-12 09:47:23

这是我以前的调制电路,忘记频率是多少了,你自己参考下
你也可以用晶振

yihui184 发表于 2012-10-12 09:51:04

xiaozuowei118 发表于 2012-10-12 09:42 static/image/common/back.gif
我原来做过电视机的自动学习遥控器,只是好久了,不太记得了,载波频率好像是38KHZ吧,要去查查才知道 ...

载波是38KHZ的,我用示波器抓出来看了,我现在是,在红外接收时,用定时器把低电平和高电平保持多久的时间记录下来,红外发射的时候再根据记录的值发射出去.载波是没有问题,
我就觉得我记录波形那有哪是不是没有考虑到呢?

yihui184 发表于 2012-10-12 09:54:53

xiaozuowei118 发表于 2012-10-12 09:47 static/image/common/back.gif
这是我以前的调制电路,忘记频率是多少了,你自己参考下
你也可以用晶振 ...

恩,谢谢你热心的解答,应该不是硬件上面的问题,我已经做出了NEC的解码和发射,还有另外一个记录波形的,都可以实现控制电器,发射电路很简单,就是一个三极管驱动.
我想主要还是软件上.

yihui184 发表于 2012-10-12 09:57:23

上班中还在解决这个问题,希望能快点解决这个问题,拖得人都慌,天天弄这个,新东西都没学到,我很对自己很失望啊。

yihui184 发表于 2012-10-12 09:59:25

自己顶!

xiaozuowei118 发表于 2012-10-12 10:00:41

电路没问题就简单了,软件上,你用逻辑分析仪对比下标准的遥控器和你自己做的遥控器输出的编码不就知道了,很简单的事。

yihui184 发表于 2012-10-12 10:07:28

xiaozuowei118 发表于 2012-10-12 10:00 static/image/common/back.gif
电路没问题就简单了,软件上,你用逻辑分析仪对比下标准的遥控器和你自己做的遥控器输出的编码不就知道了, ...

恩,我再研究下。

yihui184 发表于 2012-10-12 10:20:50

到底是什么问题呢?

BXAK 发表于 2012-10-12 10:35:03

yihui184 发表于 2012-10-12 09:57 static/image/common/back.gif
上班中还在解决这个问题,希望能快点解决这个问题,拖得人都慌,天天弄这个,新东西都没学到,我很对自己很 ...

没看程序(估计除了也在正在做学习型遥控器的,少有人有这个耐心和闲心)。你有没有和原遥控器做个对比,比如:学习某个键后发现无法正确遥控,就拿示波器捕捉对比 学习型遥控器 和 原遥控器 的波形,看看学习后那个环节的波形 变形 了,再查找程序哪里出了问题

还有如果你用单片机如果带有捕获功能的话 用捕获方式会方便许多

yihui184 发表于 2012-10-12 10:47:54

BXAK 发表于 2012-10-12 10:35 static/image/common/back.gif
没看程序(估计除了也在正在做学习型遥控器的,少有人有这个耐心和闲心)。你有没有和原遥控器做个对比, ...

1. BXAK,很高兴你回复,你的那个捕获的程序我看了,也去理解了,呵呵,然后我把捕获到的值,再用定时器控制发出去,也没实现发射,
我在想用捕获捕获到的波形数据,用的定时器是定时器方式1的方式吧?我发射的时候选用的的定时器发射用的也是定时器方式1,控制发射的。应该没问题吧?

2.我用你的帖子那个捕获程序添加了用定时器控制捕获到的数据,再发射出去,BXAK你的那个捕获程序应该没错,我用我我能确定的方式确定了。

3.我做的另外一个记录波形,参考的是51hei论坛里面的开发板的程序,它那个程序,再记录波形的时候用来好多nop指令,通过设置一个变量,感觉它那个那么不精确,
但是也能把波给录下来,太神奇了,还没体会其中的奥妙,那个程序我改了下 ,把它记录的高低电平的数据值保存到eeprom中去了。可以实现录波和发射控制电器。
可是觉得那程序不严谨。不好理解。于是参考了百度文库的一些只写设计思路,自己写了上面这个程序。

liujinhan 发表于 2012-10-12 11:14:49

之前也是用51的方案做了一个遥控学习,载波不准是肯定的,而且延时也不会很准。后来改用M32了,效果好很多,没发现问题。

对于PHILIPS的RC6码,编码要求比较严格,就会出现解码和发码错误的现象,但几率不高。 NEC的码应该比较简单。改程序吧。

载波频率一般都是38K,RC6是36K,SONY的很多都是40K。

BXAK 发表于 2012-10-12 11:31:42

yihui184 发表于 2012-10-12 10:47 static/image/common/back.gif
1. BXAK,很高兴你回复,你的那个捕获的程序我看了,也去理解了,呵呵,然后我把捕获到的值,再用定时器 ...

你还没有说到第三个方案中你有没有和原遥控器做个对比,
比如:学习某个键后发现无法正确遥控,拿示波器或者逻辑分析仪捕捉对比 学习型遥控器 和 原遥控器 的波形,看看学习后那个环节的波形 变形 了,这样排除比较容易找到程序出问题的地方

另:你现在用哪个型号的51在做,晶振多少,有时间我弄个简单学习一键的发上来

ddcchh 发表于 2012-10-12 12:30:11

我原来做过八路灯具遥控器,用NECM50462 ,接收用AT89C2051,不是用C的.

zhonggp 发表于 2012-10-12 13:00:47

没看懂,但是如果是要做一个学习型的遥控器很简单啊,
1.会做发送IR的程序吧,就4个码;
2.会做NEC解码程序吧!就解四个码;
3.头吗就一个,然后是反码;
4.命令就一个,然后是反码;一共四个吗.然后存一个头码和需要保存的学码到EEPROM.
这样就可以了吧.
怎么会涉及到存波形呢?如果你采集到的波形有误差,你产生的波形也有误差,那这样不就出现更大的误差了.

yihui184 发表于 2012-10-12 13:55:28

BXAK 发表于 2012-10-12 11:31 static/image/common/back.gif
你还没有说到第三个方案中你有没有和原遥控器做个对比,
比如:学习某个键后发现无法正确遥控,拿示波器 ...

我有用示波器抓了波形看来一下,相差大,我觉得用定时器把高低电平的时间记录下来,
然后再打开定时器发射载波和低电平应该就没问题吧。

参考的那个51hei论坛做的,也是记录高低电平的,学习NEC制式的遥控器可以控制电器,51hei论坛的那个记录波形的学习型遥控器,感觉他们记录的波形的高低电平的时间太不严谨了,我把电路搭起来了,事实证明可以用。那个程序我传上去了,我就觉得那个程序不够严谨,所以我想自己原创一个记录波形的,可是却实现不了,我觉得逻辑上都没有错呢。

51hei论坛的那个记录波形的程序思路是这样:

1.这是记录波形的函数。判断高低电平的接收,然后用15个NOP作为延时的基数,再用一个变量计数有多少个基数。
void receive()
{
                ET1=0;
                TR1=0;
                EX0=0;
                EA=0;
                head=0;          
                studylamp=1;
                delay1ms(100);
                studylamp=0;
                while(remotein==1);                                 
                head=0;                                 
                while(remotein==0)                                 //低电平到来,接收起始码。
                      {
                              _nop_();_nop_();_nop_();_nop_();_nop_();                     //15个NOP作为延时的基数,用head变量计数。
                        _nop_();_nop_();_nop_();_nop_();_nop_();
                        _nop_();_nop_();_nop_();_nop_();_nop_();
                        head++;
                }
                n=0;
                remdata=0x0000;
                while(1)
                {
                        while(remotein==1)                                                    //高电平到来,同样15个nop作为延时的基数,用remdata计数。
                        {
                                _nop_();_nop_();_nop_();_nop_();_nop_();
                                _nop_();_nop_();_nop_();_nop_();_nop_();
                                _nop_();_nop_();_nop_();_nop_();_nop_();
                                remdata++;
                        }
                        if(remdata>m)                                                         //高电平>5毫秒退出
                        {
                                remotedata=0x00;
                                EX0=1;
                                EA=1;
                                goto end;
                        }
                        remotedata=remdata;                                           //保存计数
                        n++;            
                        remdata=0x0000;               
                        while(remotein==0)
                        {
                                _nop_();_nop_();_nop_();_nop_();_nop_();
                                _nop_();_nop_();_nop_();_nop_();_nop_();
                                _nop_();_nop_();_nop_();_nop_();_nop_();
                                remdata++;
                        }                     
                        remotedata=remdata;
                        n++;
                        remdata=0x00;
                }
                                       
                end: studylamp=1;

                           
}2.发送波形的函数。
感觉51hei论坛做的这个记录波形的程序,他们这样做很麻烦,好像是用经验试出来的,延时的时候用多少个nop,太不好确定了!但是他们做出来的就是能达到效果。
我现在看来他们的,感觉原理就是高低电平的记录嘛!我现在用定时器的方式来实现,感觉比他们精确,为什么就不能实现呢,我很苦恼!
void send_red()
{
        ET1=1;
        TR1=1;                                             //打开定时器1,发送载波
                for(i=head;i>0;i--);                              //head的值是记录了起始码中高电平的计数值。
        remoteout=0;                                    //开始发送低电平,发射端口为0
        ET1=0;
        TR1=0;
        n=0;
        while(1)
        {      
                if(remotedata==0x00)                           //当计数值为0停止发送。
                {
                        delay1ms(10);
                        break;                  
                }
                for(i=remotedata;i>0;i--)                                       //从数组中取值发送。
                {
                        _nop_();_nop_();_nop_();_nop_();_nop_();
                        _nop_();_nop_();_nop_();_nop_();
                      }
                n++;                     
                ET1=1;
                TR1=1;   
                for(i=remotedata;i>0;i--);
                      remoteout=0;
                ET1=0;
                TR1=0;
                n++;
        }                                               
                                         
}BXAK,我知道你做遥控器很厉害,希望你也能研究研究这录波的学习型遥控器。我还想发射程序的时候用你那个仿真里面的函数,试试看,接收和发送波形可以允许一定的误差,几十个us应该可以吧。我会坚持做完这个,做出来了会来分享的。

yihui184 发表于 2012-10-12 13:58:57

zhonggp 发表于 2012-10-12 13:00 static/image/common/back.gif
没看懂,但是如果是要做一个学习型的遥控器很简单啊,
1.会做发送IR的程序吧,就4个码;
2.会做NEC解码程序吧! ...

恩,我现在是做一个把遥控器发送过来的码,用单片机把那些嘛的波形给录制下来,然后再原样发送出去,可是实现不了,感觉逻辑都没错,朋友,有空你也试试,看下能不能实现。我为这个问题苦恼了好久呢,打击太大了。

yihui184 发表于 2012-10-12 14:00:01

ddcchh 发表于 2012-10-12 12:30 static/image/common/back.gif
我原来做过八路灯具遥控器,用NECM50462 ,接收用AT89C2051,不是用C的.

恩,是学习型的方式实现得么?

yihui184 发表于 2012-10-12 14:06:54

BXAK 发表于 2012-10-12 11:31 static/image/common/back.gif
你还没有说到第三个方案中你有没有和原遥控器做个对比,
比如:学习某个键后发现无法正确遥控,拿示波器 ...

我有用STC89C52 和 STC12C5A60S2做!

1.STC89C52是在51hei论坛的那个记录波形的程序基础上做的。我感觉51hei论坛那个不严谨,在理解了他的原理,并且发现他的那个原理可以实现,我自己就用定时器写了贴在上面的那个程序来实现,可是实现不了。感觉没有我想的那么简单哇!我再研究一下。

2.STC12C5A60S2是在你的那个捕获解码NEC和RC6的基础上延伸的,我想记录波形的时候用你的那个捕获程序里的捕获那段程序,发射的时候用你仿真发射波形的那个程序,两个结合一下,看下能不能成功!你觉得呢?BXAK。

BXAK,谢谢你这么热心。

yihui184 发表于 2012-10-12 14:08:59

liujinhan 发表于 2012-10-12 11:14 static/image/common/back.gif
之前也是用51的方案做了一个遥控学习,载波不准是肯定的,而且延时也不会很准。后来改用M32了,效果好很多 ...

恩,还没用STM32呢,我刚花了468买了一个STM32开发板学习,有空和你交流哈!

yihui184 发表于 2012-10-12 14:10:47

liujinhan 发表于 2012-10-12 11:14 static/image/common/back.gif
之前也是用51的方案做了一个遥控学习,载波不准是肯定的,而且延时也不会很准。后来改用M32了,效果好很多 ...

恩,改程序,光解NEC的我是做出来了,我想问下发送RC6码的波形,不是38KHZ的载波么?

BXAK 发表于 2012-10-12 14:21:58

yihui184 发表于 2012-10-12 14:06 static/image/common/back.gif
我有用STC89C52 和 STC12C5A60S2做!

1.STC89C52是在51hei论坛的那个记录波形的程序基础上做的。我感觉5 ...

有个错误,uchar dat;   最大学习才40个电平,这不够,就拿常用的NEC编码来说:
引导码(高9ms,低4.5ms) + 32位编码(高0.56ms,低0.56ms 或者1.68ms ) + 结束码(高0.56ms,低40ms),不算重复码 就有68电平,也就需要136字节装载,你看看你少了多少?

你看看 常用NEC编码 、长虹RC5遥控编码 波形:
(点击图片看大图)

yihui184 发表于 2012-10-12 14:25:05

恩,是啊,我再看下!呵呵!

yihui184 发表于 2012-10-12 14:49:24

BXAK 发表于 2012-10-12 14:21 static/image/common/back.gif
有个错误,uchar dat;   最大学习才40个电平,这不够,就拿常用的NEC编码来说:
引导码(高9ms,低4. ...

BXAK,还是不行,我再研究下,用单片机做的逻辑分析仪看下,我去找个网上有网友做的逻辑分析仪弄到我开发板上,发射后看下波形!
谢谢BXAK,我继续研究。

yihui184 发表于 2012-10-12 15:06:25

自己顶下!

15813191501 发表于 2012-10-12 15:44:25

zhonggp 发表于 2012-10-12 13:00
没看懂,但是如果是要做一个学习型的遥控器很简单啊,
1.会做发送IR的程序吧,就4个码;
2.会做NEC解码程序吧! ...

问题是他不只解NEC格式

liujinhan 发表于 2012-10-12 17:17:56

yihui184 发表于 2012-10-12 14:10 static/image/common/back.gif
恩,改程序,光解NEC的我是做出来了,我想问下发送RC6码的波形,不是38KHZ的载波么? ...

3.2.2 数据的逻辑定义
(1)RC6逻辑电平的定义(对于接受波形)。见图RC6-3。
逻辑‘ 0’ :先高后低,下降沿。
逻辑‘ 1’ :先低后高,上升沿。
(2)RC6每一位的时间
RC6用36K 载波, 半位时间(1T)占用16个载波周期。
半位时间(HALF BIT TIME‡1T):16*27778=444.444µs(1T)
一位时间(FULL BIT TIME‡2T):2*444.444=888.889µs(2T)
(3)RC6消息时间(MESSAGE TIME)和帧(FRAME TIME)
一个消息经历的消息时间为:52*0.444444=23.111MS(52T)。
一个帧经历的帧时间为:58*0.444444=25.778MS(58T)。
(4)RC6重复时间(REPEATING TIMING)
240*0.444444=106.667ms。



还有一点需要特别注意,遥控接收头的问题,并不是所有的接收头都可以接收所有的遥控信号。有些接收出来的时序和实际差别很大,导致无法正常解码。

BXAK 发表于 2012-10-12 18:02:48

yihui184 发表于 2012-10-12 14:49 static/image/common/back.gif
BXAK,还是不行,我再研究下,用单片机做的逻辑分析仪看下,我去找个网上有网友做的逻辑分析仪弄到我开发 ...

又一个错误的地方,16位定时器赋值错误
TH0=256-dat;                                                       //先发 1 ,给定时器赋初值,取反,                                          
TL0=256-dat;

BXAK 发表于 2012-10-12 22:25:00

BXAK 发表于 2012-10-12 18:02 static/image/common/back.gif
又一个错误的地方,16位定时器赋值错误
TH0=256-dat;                                                ...

程序已传到新帖,链接:基于STC89C52的简易学习型红外遥控器

yihui184 发表于 2012-10-12 22:55:23

BXAK 发表于 2012-10-12 22:25 static/image/common/back.gif
程序已传到新帖,链接:基于STC89C52的简易学习型红外遥控器

BXAK,你就弄出来啦,就验证啦,真厉害!

yihui184 发表于 2012-10-12 23:07:17

BXAK 发表于 2012-10-12 22:25 static/image/common/back.gif
程序已传到新帖,链接:基于STC89C52的简易学习型红外遥控器

BXAK,又让你花时间了,谢谢你,我现在就去看你的程序。好强大啊,真的好厉害呀!你总是那么的热心,我都不知道怎么感谢你!

BXAK 发表于 2012-10-12 23:13:11

yihui184 发表于 2012-10-12 23:07 static/image/common/back.gif
BXAK,又让你花时间了,谢谢你,我现在就去看你的程序。好强大啊,真的好厉害呀!你总是那么的热心,我都 ...

还好,主要模块都是以前模块化编程留下来的,现在只需组合小改就行

Xlt123gO 发表于 2012-10-15 13:12:03

标记一下

chenjian198722 发表于 2013-4-5 07:59:37

liujinhan 发表于 2012-10-12 11:14 static/image/common/back.gif
之前也是用51的方案做了一个遥控学习,载波不准是肯定的,而且延时也不会很准。后来改用M32了,效果好很多 ...

前辈 我是一个学生,我也在学习红外这部分 ,能不能给我份您写的捕获脉冲长度复制红外波形的例程 ,非常感谢

chenjian198722 发表于 2013-4-5 08:12:25

liujinhan 发表于 2012-10-12 11:14 static/image/common/back.gif
之前也是用51的方案做了一个遥控学习,载波不准是肯定的,而且延时也不会很准。后来改用M32了,效果好很多 ...

1130160836@qq.com

liujinhan 发表于 2013-4-5 08:23:00

chenjian198722 发表于 2013-4-5 08:12 static/image/common/back.gif


搜索下 输入捕获的相关主题吧。。

chenjian198722 发表于 2013-4-5 09:39:08

liujinhan 发表于 2013-4-5 08:23 static/image/common/back.gif
搜索下 输入捕获的相关主题吧。。

我已经弄了好长时间了 我用学习了原子例程里面的捕获高脉冲,可是我测遥控同一个按键 得到的两次数据不同 ,希望前辈给个思路,我不会把您的代码用作商用,仅学习

chenjian198722 发表于 2013-4-5 09:42:01

liujinhan 发表于 2013-4-5 08:23 static/image/common/back.gif
搜索下 输入捕获的相关主题吧。。

void TIM5_Cap_Init(u16 arr,u16 psc)
{               
        RCC->APB1ENR|=1<<3;           //TIM5 时钟使能
        RCC->APB2ENR|=1<<2;            //使能PORTA时钟
       
        GPIOA->CRL&=0XFFFFFFF0;        //PA0 清除之前设置
        GPIOA->CRL|=0X00000008;        //PA0 输入   
        GPIOA->ODR|=0<<0;                //PA0 下拉
          
        TIM5->ARR=arr;                //设定计数器自动重装值   
        TIM5->PSC=psc;                //预分频器

        TIM5->CCMR1|=1<<0;                //CC1S=01         选择输入端 IC1映射到TI1上
        TIM5->CCMR1|=0<<4;                 //IC1F=0000 配置输入滤波器 不滤波
        TIM5->CCMR1|=0<<10;         //IC2PS=00         配置输入分频,不分频

        TIM5->CCER|=0<<1;                 //CC1P=0        上升沿捕获
        TIM5->CCER|=1<<0;                 //CC1E=1         允许捕获计数器的值到捕获寄存器中

        TIM5->DIER|=1<<1;           //允许捕获中断                               
        TIM5->DIER|=1<<0;           //允许更新中断       
        TIM5->CR1|=0x01;            //使能定时器2
        MY_NVIC_Init(2,0,TIM5_IRQChannel,2);//抢占2,子优先级0,组2          
}

//捕获状态
//:0,没有成功的捕获;1,成功捕获到一次.
//:0,还没捕获到高电平;1,已经捕获到高电平了.
//:捕获高电平后溢出的次数
u8TIM5CH1_CAPTURE_STA=0;        //输入捕获状态                                                 
u16        TIM5CH1_CAPTURE_VAL;        //输入捕获值
//定时器5中断服务程序       
void TIM5_IRQHandler(void)
{                   
        u16 tsr;
        tsr=TIM5->SR;
        if((TIM5CH1_CAPTURE_STA&0X80)==0)//还未成功捕获       
        {
                if(tsr&0X01)//溢出
                {          
                        if(TIM5CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
                        {
                                if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
                                {
                                        TIM5CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
                                        TIM5CH1_CAPTURE_VAL=0XFFFF;
                                }else TIM5CH1_CAPTURE_STA++;
                        }       
                }
                if(tsr&0x02)//捕获1发生捕获事件
                {       
                        if(TIM5CH1_CAPTURE_STA&0X40)                //捕获到一个下降沿                
                        {                                 
                                TIM5CH1_CAPTURE_STA|=0X80;                //标记成功捕获到一次高电平脉宽
                          TIM5CH1_CAPTURE_VAL=TIM5->CCR1;        //获取当前的捕获值.
                               TIM5->CCER&=~(1<<1);                        //CC1P=0 设置为上升沿捕获
                        }else                                                                //还未开始,第一次捕获上升沿
                        {
                                TIM5CH1_CAPTURE_STA=0;                        //清空
                                TIM5CH1_CAPTURE_VAL=0;
                                TIM5CH1_CAPTURE_STA|=0X40;                //标记捕获到了上升沿
                               TIM5->CNT=0;                                        //计数器清空
                               TIM5->CCER|=1<<1;                                 //CC1P=1 设置为下降沿捕获
                        }                  
                }                                                                                 
        }
        TIM5->SR=0;//清除中断标志位           
}





第一次

HIGH:7604 us
HIGH:2302 us
HIGH:2250 us
HIGH:7604 us
HIGH:1192 us
HIGH:21423 us
HIGH:1185 us
HIGH:1248 us
HIGH:7611 us
HIGH:2304 us
HIGH:2304 us
第二次

HIGH:7658 us
HIGH:1257 us
HIGH:1202 us
HIGH:7625 us
HIGH:1208 us
HIGH:7605 us
HIGH:1156 us
HIGH:1183 us
HIGH:7605 us
HIGH:2192 us
HIGH:2209 us

liujinhan 发表于 2013-4-5 09:58:12

下面是定时器和中断的配置,你看看吧。具体的程序我找不到了。不是不给你。

红外的捕获时,遥控头会收外界干扰,所以当你捕获一串数据时,可能前面几个数据是错误的。后面的连续的数据才是真实的遥控码,可以从遥控首码判断。



void TIM_Config(void)
{
        TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
        TIM_ICInitTypeDefTIM_ICInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        SET_GPIO_DIR(GPIOB,10,MODE_IN_FLOAT);

        GPIO_PinRemapConfig(GPIO_PartialRemap2_TIM2, ENABLE); //端口重映射

        /* 基础设置*/
        TIM_TimeBaseStructure.TIM_Period = 0xf000;                        //计数值   
        TIM_TimeBaseStructure.TIM_Prescaler = 72-1;            //预分频,此值+1为分频的除数,72M、72,定时1us
        TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;        //
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;         //向上计数              
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
//       
       /* TIM2 Input Capture Configuration */
        TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
        TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;        //捕获上升沿
        TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;        //直接连接到TIM2CH3
        TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
        TIM_ICInitStructure.TIM_ICFilter = 0;                  
        TIM_ICInit(TIM2, &TIM_ICInitStructure);


        TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
        TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;        //捕获下降沿
        TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI;        //间接连接到TIM2CH3
        TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
        TIM_ICInitStructure.TIM_ICFilter = 0;                  
        TIM_ICInit(TIM2, &TIM_ICInitStructure);
              
        /*使能预装载*/
        TIM_ARRPreloadConfig(TIM2, ENABLE);
        /*预先清除所有中断位*/
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC3 | TIM_IT_CC4);        
        /* 4个通道和溢出都配置中断*/
        TIM_ITConfig(TIM2, TIM_IT_CC3 |TIM_IT_CC4, ENABLE);       

        /* Timer2中断*/
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
       
        /* 允许TIM2开始计数 */
        TIM_Cmd(TIM2, ENABLE);
}
void TIM2_IRQHandler(void)
{
        if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET)
        {               
                TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
               
                IR_TimeOut=0;//超时复位
               
                if(IR_CaptureEnable)
                {
                        if(0==IR_CaptureStart)        //遇到第一个电平变化即开始捕获,初始化一些变量
                        {
                                IR_CaptureStart=1;
                                IR_CCR3=TIM2->CCR3;
                                IR_CCR4=TIM2->CCR4;
                                IR_Count=0;
                        }
                        else
                        {
                                IR_CCR3=TIM2->CCR3;
                                if(IR_CCR3>IR_CCR4) IR_Data=IR_CCR3-IR_CCR4;
                                else IR_Data=IR_CCR3+0xf000-IR_CCR4;
                                IR_Count++;
                        }
                }
        }
        else if (TIM_GetITStatus(TIM2, TIM_IT_CC4) != RESET)
        {
                  TIM_ClearITPendingBit(TIM2, TIM_IT_CC4);
          
                IR_TimeOut=0;//超时复位
               
                if(IR_CaptureEnable)//遇到第一个电平变化即开始捕获,初始化一些变量
                {
                        if(0==IR_CaptureStart)
                        {
                                IR_CaptureStart=1;
                                IR_CCR3=TIM2->CCR3;
                                IR_CCR4=TIM2->CCR4;
                                IR_Count=0;
                        }
                        else
                        {
                                IR_CCR4=TIM2->CCR4;
                                if(IR_CCR4>IR_CCR3) IR_Data=IR_CCR4-IR_CCR3;
                                else IR_Data=IR_CCR4+0xf000-IR_CCR3;
                                IR_Count++;
                        }                       
                }
        }
}

hzqlz 发表于 2013-11-10 13:57:20

不仅要学习红外波形还要学习红外载波频率才能控制电视机。一个逻辑bit误差一般20几个us算是正常的。实时性要求高,一般用汇编写。这类成熟的方案mcu也就一块多钱,不知道楼主做的是什么产品

water0313 发表于 2013-12-12 16:04:41

想问楼主红外接收模块式怎么实现的,是利用专用的一体化接收头还是利用红外发射二极管实现的?

newywx 发表于 2013-12-16 16:45:08

专用的一体化接收头省事吧

星晨海源 发表于 2014-11-22 13:31:10

BXAK 发表于 2012-10-12 14:21
有个错误,uchar dat;   最大学习才40个电平,这不够,就拿常用的NEC编码来说:
引导码(高9ms,低4. ...

mark此处,这个数据很有用

weixfile 发表于 2014-11-22 15:57:46

到底有多少种编码标准啊。我们家海尔电视是RC-5码,机顶盒是NEC码。每次看电视都要两个遥控器,烦死了。后来我在电视里装了一块小板,可以接收机顶盒遥控器的两个无用的按键(NEC码),然后再用RC-5码发射给电视,可以实现机顶盒遥控器控制电视图象亮度和图象静止功能。另外我讨厌原来电视的声音通过A/D ,D/A变换出来不好听,在同一块板上装了一个4通道音量控制芯片,甩开了数字板的声音处理,接收遥控器的音量控制按键后,用51单片机控制音量。NEC码和RC-5码的接收和RC-5码的发射都是用一块51单片机实现的,也没接什么调制电路。我也没有逻辑分析仪和数字示波器,都是通过实验自己编的程序,修改了很多次错误。

a615 发表于 2014-12-10 13:23:30

我最近也在做红外波形学习,采用的是PIC18,都是us级别的电平变化采集。发射也是以10us为最小发射单位时间。调了好多最小发射单位时间,都不行,郁闷ing
页: [1]
查看完整版本: 请教学习型遥控器,波形拷贝式,发射和接收的问题。