原创 RC6格式遥控码的另外一种解码方法

2009-10-19 16:14 3782 4 8 分类: MCU/ 嵌入式

考虑了另外一种解码方法,解码程序在定时中断中执行,定时中断设置成200us中断,在中断程序中扫描I/O,测量遥控信号低电平和高电平的时间。有几个关键变量:ir_ltime-低电平时间,ir_htime-高电平时间,bit_over-位变量,指示一位数据是否处理完。


RC6格式的01波形如下:


1位数据“<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />0”“1”的周期是888us,高低电平分别是444us,奇偶位的周期是2*888us,高低电平分别是2*444us


5bfd05c7-7126-4199-9cbc-6ba993c1264a.jpg


分析RC6格式,可以得到下面的规律,就是解码原理:


1、  如果低电平是窄的,且bit_over=1,那么bit_over=0,当前位为1ir_bit++


2、  如果低电平是窄的,且bit_over=0,那么bit_over=1,其它不做处理。


3、  如果低电平是宽的,且bit_over=1,是错误码。


4、  如果低电平是宽的,且bit_over=0,那么bit_over=0,当前位为1ir_bit++


5、  如果高电平是窄的,且bit_over=1,那么bit_over=0,当前位为0ir_bit++


6、  如果高电平是窄的,且bit_over=0,那么bit_over=1,其它不做处理。


7、  如果高电平是宽的,且bit_over=1,是错误码。


8、  如果高电平是宽的,且bit_over=0,那么bit_over=0,当前位为0ir_bit++


9、  奇偶校验位的电平宽度是其他位电平宽度的2倍,在程序中单独处理。


解码程序如下:


/*


定时器0中断函数


中断间隔:200us


*/


<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 


void Isr_Timer0()


{


shift_ir:


       if(ir_shift_flag)


       {


              ir_shift_flag = 0;   


           _rlc(&ir_data0);


           _rlc(&ir_data1);


           _rlc(&ir_data2);


         if(ir_bit >= 21)


         { 


             if((ir_usercode == ir_data1) && (ir_value == ir_data0))


                    {


                           ir_ok = 1;


                    }


                    else


                    {    


                    ir_usercode = ir_data1;


                    ir_value = ir_data0;


                }


err_ir:


           ir_head = 0;


           ir_bit = 0;


           ir_data0 = 0;


           ir_data1 = 0;


           ir_data2 = 0;


           bit_over = 0;


           ir_shift_flag = 0; 


         } 


           return;


        }  


             


       ir_ltime++;


       ir_htime++;


       if(IR_IN)


       {


              if(!ir_pin_level)


              {


                     ir_pin_level = 1;   //ir电平从低变高


                     ir_ltime_temp = ir_ltime;


                     ir_htime = 0;


                     if(ir_head)


                     {


                            if(ir_ltime > 3)


                            {


                                   if(bit_over)


                                          goto err_ir;


                                   else


                                   {


                                          if(ir_bit == 5)


                                          {


                                                 if(ir_ltime > 5)     //判断奇偶位为0时的低电平


                                                 {


                                                                     


                                             _c = 1;


                                             ir_bit++;


                                             ir_shift_flag = 1;


                                             goto shift_ir;


                                       }


                                       else


                                       {


                                              bit_over = 1;


                                       }


                                      }


                                      else


                                      {


                                        _c = 1;


                                             ir_bit++;


                                             ir_shift_flag = 1;


                                             goto shift_ir;


                                           }   


                                                    


                                   }


                            }


                            else


                            {


                                   if(bit_over)


                                   {


                                          bit_over = 0;


                                          _c = 1;


                                          ir_bit++;


                                          ir_shift_flag = 1;


                                          goto shift_ir;


                                   }


                                   else


                                          bit_over = 1;


                            }                                                                   


                     }


             


              }


             


       }


       else


       {


              if(ir_pin_level)


              {


                     ir_pin_level = 0; //ir电平从高变低


                     ir_htime_temp = ir_htime;


                     ir_ltime = 0;   


                     if(ir_head)


                     {


                            if(ir_htime > 3)


                            {


                                   if(bit_over)


                                   {


                                          if(ir_bit == 4)


                                          {


                                                 bit_over = 0;         //判断奇偶位是0时的高电平


                                                        _c = 0;


                                              ir_bit++;


                                              ir_shift_flag = 1;


                                              goto shift_ir;


                                            }


                                           else


                                                goto err_ir;


                                          }


                                         


                                   else


                                   {


                                          if(ir_bit == 5)


                                          {


                                                 if(ir_htime < 5)       //判断奇偶校验位是1时的高电平


                                                 {


                                                        bit_over = 1;


                                                 }


                                                 else


                                           {


                                                       _c = 0;


                                              ir_bit++;


                                              ir_shift_flag = 1;


                                              goto shift_ir;


                                            }


                                          }


                                          else


                                          {


                                                 _c = 0;


                                              ir_bit++;


                                              ir_shift_flag = 1;


                                              goto shift_ir;


                                            }


                                                         


                                   }


                            }


                            else


                            {


                                   if(bit_over)


                                   {


                                          bit_over = 0;


                                          _c = 0;


                                          ir_bit++;


                                          ir_shift_flag = 1;


                                          goto shift_ir;


                                         


                                   }


                                   else


                                          bit_over = 1;                                     


                            }           


                                         


                     }


                     else


                     {


                            if((ir_ltime_temp > 11) && (ir_ltime_temp < 16))             


                            {


                                   ir_head = 1;   //检测到头码


                                   bit_over = 1;


                                  


                            }


                            else


                                   goto err_ir;


                     }                         


                                  


             }    


      }           


}


这种解码方式占用单片机资源少,而且灵敏度高,不会因为遥控波形的高低电平时间的少量偏差检测到误码。


 
PARTNER CONTENT

文章评论4条评论)

登录后参与讨论

用户1035191 2010-1-6 09:12

51里的带进位左移要定义一个宏 #define _rlcar_(RX)CY=RX&0x80 //RX带进位左移1位,数据放入ACC ,此处是CY=RX&0x80,RX处没有双引号 你在网上搜一下就知道了

用户1323229 2010-1-5 23:36

谢谢指点,也是这么理解的,但51好像不行,是不是要息写一个函数?

用户1035191 2010-1-4 10:05

hongly, _rlc(&ir_data0); _rlc(&ir_data1); _rlc(&ir_data2);是带进位左移

用户1323229 2010-1-1 02:38

首先非常感谢你的无私献出这么好的代码,想请教一下,我用的是51核MCU,看不懂你下面这几句的意思,能否指点一二,非常感谢! _rlc(&ir_data0); _rlc(&ir_data1); _rlc(&ir_data2);
相关推荐阅读
用户1035191 2012-05-18 16:36
根据年月日计算星期
在门禁系统中要用到星期,但是在设置时间的时候,一般只设置年月日时分秒,不会去设置星期,那么如何根据年月日来得到星期?有一个公式: (年+年/4+年/400-年/100-年基数+月基数+日)%7...
用户1035191 2012-05-09 12:40
串口扩展芯片VK3214使用总结
最近一个项目需要用到3个串口,但是用的MCU只有2个串口,选择多串口的单片机成本太高,最后打算用串口扩展芯片VK3214扩展2个串口。 VK3214可以用单片机的一个串口扩展出4个子串口,每个...
用户1035191 2011-10-12 17:54
STM32串口发送时序图分析
下面是STM32使用手册上的串口发送时序图:1、 使能串口发送TE,此时USART_DR为空,此时应查询TXE是否置1,TXE置1,TX脚先发送一个空闲帧,把F1帧写入USART_DR,TXE被清零。...
用户1035191 2011-09-30 14:52
STM32的RTC实现日历功能程序
STM32的RTC只有一个32位的计数器用来计时,没有寄存器来存年月日时分秒等。通过设置可以让这个计数器1秒加1,从0-0XFFFFFFFF大概可以计时136年。程序要设置一个时间起点表示0,一般设...
用户1035191 2011-09-14 17:30
C语言计算时间差
以前曾写过一篇文章C51计算时间差,采用的算法是网上查到的,虽然测试没有问题,但是感觉那种算法不便于理解。最近重新考虑了一种算法。 用2个BCD码数组存储进场时间和出场时间: unsigned ch...
用户1035191 2011-08-24 17:06
C51扩展外部RAM释放P2口
51单片机经常要使用一些外部器件,有些器件内部有寄存器,一般都把这些寄存器当做外部RAM读写。以IC卡读卡芯片RC500为例,这个芯片有D0-D7共8个数据线,接在51的P0口,D0-D7既做>...
EE直播间
更多
我要评论
4
4
关闭 站长推荐上一条 /3 下一条