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

2020-01-21 21:36发布

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

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

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





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

学习型遥控器.rar (40.29 KB, 下载次数: 88) 2012-10-11 23:10 上传 点击文件名下载附件

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

学习型遥控器设计.pdf (121.82 KB, 下载次数: 125) 2012-10-11 23:12 上传 点击文件名下载附件


我写的程序如下:

  1. /*
  2.    时间:2012.10.10
  3.    功能:学习型遥控器
  4. */

  5. #include <reg52.h>

  6. #define uchar unsigned char   
  7. #define uint  unsigned int
  8. #define ulong unsigned long

  9. sbit  study_key=P1^0;                      //学习按键
  10. sbit  studylamp=P2^1;                             //学习状态指示灯
  11. sbit  send_key=P1^1;                      //发射键
  12. sbit  remotein=P2^0;                      //遥控信号输入口
  13. sbit  remoteout= P3^4;                  // 遥控信号输出口
  14. sbit  txkey=P1^1;                         //待定
  15. bit   flag=0;

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


  17. void Delay1ms(uint t)
  18. {
  19.                 uint x,y;
  20.         for(x=0;x<t;x++)
  21.            for(y=0;y<120;y++);
  22. }

  23. void delete_dat()
  24. {
  25.                uchar t;
  26.         for(t=0;t<80;t++)
  27.         {
  28.             dat[t]=0;
  29.         }
  30. }

  31. void init_io()
  32. {
  33.                TMOD=0x21;
  34.         TH1=0xF3;                              
  35.         TL1=0xF3;
  36.         remotein=1;
  37.         remoteout=1;
  38.         studylamp=0;       
  39.         EA=1;
  40. }


  41. void main()
  42. {
  43.    uchar i=0;
  44.    init_io();
  45.    delete_dat();
  46.    while(1)
  47.    {

  48.            if(!study_key)                                                                            //学习键按下,开始接收红外码.用于记录整个码的高低电平.
  49.            {
  50.                           Delay1ms(10);
  51.                   if(!study_key)
  52.                   {
  53.                                  while(!study_key);
  54.                                     while( remotein );                   //当红外接收端为 1 时一直等待,为 0 跳入循环.开始接收程序.
  55.                                       while(1)
  56.                                 {                       
  57.                                   TH0=0;                                
  58.                                   TL0=0;
  59.                                   TR0=1;
  60.                                   while(!remotein);                         //当为 1 时 跳出循环.
  61.                                   TR0=0;
  62.                                   dat[i++]=TH0;                           //保存 0  的记时时间.
  63.                                   dat[i++]=TL0;
  64.                                   TH0=0;                                    //重新赋初值.
  65.                                   TL0=0;                 
  66.                                   TR0=1;
  67.                                   while(remotein)                      //当接收的时候,1 的值是否有溢出,有的话,跳出当前循环,给一个标志位,用于跳出大循环,不再接收.
  68.                                   if(TF0)
  69.                                   {
  70.                                             TF0=0;
  71.                                             TR0=0;
  72.                                               flag=1;
  73.                                               dat[i++]=0;
  74.                                             studylamp=1;
  75.                                             break;
  76.                                  }
  77.                                  if(flag)
  78.                                       break;
  79.                                  TR0=0;
  80.                                  dat[i++]=TH0;
  81.                                          dat[i++]=TL0;                  
  82.                         }
  83.                   }
  84.            }
  85.        
  86.            if(!send_key)                                                  //发射键按下,用于发射接收到的码的高低电平.
  87.            {
  88.                           Delay1ms(10);
  89.                   if(!send_key)
  90.                   {
  91.                           while(!send_key);
  92.                           if(flag)
  93.                           {          
  94.                                           i=0;                                                                                               
  95.                                           ET1=1;                                                                                   //把发送载波的中断开启.
  96.                                           while(1)
  97.                                   {                         
  98.                                                TH0=256-dat[i++];                                                       //先发 1 ,给定时器赋初值,取反,                                          
  99.                                                TL0=256-dat[i++];
  100.                                                TR0=1;
  101.                                                TR1=1;                                                                     //启动载波
  102.                                           while(!TF0);                                                               //溢出后,发下一组.
  103.                                                TF0=0;
  104.                                                TR0=0;
  105.                                                TR1=0;
  106.                                         remoteout=0;                                                        //发送 低 电平
  107.                                         TH0=256-dat[i++];                                                 //发 0  
  108.                                         TL0=256-dat[i++];
  109.                                          if( dat[i] == 0 )                                                     //当发的数据中没有植,为0时,停止发送.
  110.                                          {
  111.                                                       delete_dat();
  112.                                               flag=0;
  113.                                                       studylamp=0;
  114.                                                ET1=0;
  115.                                                break;
  116.                                         }
  117.                                         TR0=1;
  118.                                         while(!TF0);
  119.                                         TF0=0;       
  120.                                         TR0=0;                                                                                 
  121.                                 }
  122.                           }
  123.                   }
  124.            }

  125.    }
  126.         
  127. }

  128. //40KHz发生器      
  129. void time_intt1(void) interrupt 3
  130. {
  131.      remoteout=~remoteout;
  132. }
复制代码请问一下:

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

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

帮我看下我上面写的那个接收码和发射码,哪里是不是有问题呢?还是思路有问题呢?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
61条回答
liujinhan
1楼-- · 2020-01-27 20:48
下面是定时器和中断的配置,你看看吧。具体的程序我找不到了。不是不给你。

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



void TIM_Config(void)
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_ICInitTypeDef  TIM_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_Count]=IR_CCR3-IR_CCR4;
                                else IR_Data[IR_Count]=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_Count]=IR_CCR4-IR_CCR3;
                                else IR_Data[IR_Count]=IR_CCR4+0xf000-IR_CCR3;
                                IR_Count++;
                        }                       
                }
        }
}
hzqlz
2楼-- · 2020-01-28 02:42
不仅要学习红外波形还要学习红外载波频率才能控制电视机。一个逻辑bit误差一般20几个us算是正常的。实时性要求高,一般用汇编写。这类成熟的方案mcu也就一块多钱,不知道楼主做的是什么产品
water0313
3楼-- · 2020-01-28 03:14
 精彩回答 2  元偷偷看……
newywx
4楼-- · 2020-01-28 07:03
专用的一体化接收头省事吧
星晨海源
5楼-- · 2020-01-28 07:17
BXAK 发表于 2012-10-12 14:21
有个错误,uchar dat[80];   最大学习才40个电平,这不够,就拿常用的NEC编码来说:
引导码(高9ms,低4. ...

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

一周热门 更多>