跟着项目组长一起做了几个空鼠项目,一直觉得自己长劲不大,因为自己只负责简单的键盘定义部分,最终的整个软件架构其实自己都不太了解。从去年11月份开始,一直都很忙,一个接着一个做,我的任务也只是键盘部分。重复的做一样东西,感觉挺没劲的!
由于产品设计需要,我们要做学习型的遥控器。于是,这项任务就落在了我的手里。
一说起学习型遥控器,其实,思路很简单:就是把要学习的遥控器发送的电平给记录下来,然后存入flash中。待到需要发送时,从flash中将记录的电平给发送出来。而设计的难点在于:用于记录电平的数组应该设为多大,什么时候才算学完一个波形。以及在学习时,怎么才能区分出码字信息和重发信息。
不同的红外编码格式,按键在短按和长按的情况下,发送的红外信息格式也不一样。分析了大部分的红外编码,我发现它们大致可以分为两类:一类是发送完码字信息之后,后面跟有Stop Bit ,然后是Repeat Code;一类是发送完码字信息之后,后面只跟有Stop Bit。而且这两种方式,在按键短按和长按的情况下也不一样。第一类:按键短按情况下,发送完码字信息,发送一次Repeat Code 就结束;长按情况下,发送完码字信息,则一直发送Repeat Code。第二类:按键短按情况下,会有两种情况,一是发送完码字信息之后,紧跟一次Stop Bit 就结束,另一种是发送完码字信息之后,发送Stop Bit ,然后再发一次码字信息才结束。出现这两种不同情况,我判断是跟按键按下的时间长短有关,但具体原因和原理,还不是很清楚。希望看到这点的博友,能给解释下。按键长按的情况下,会再次重发码字信息和Stop Bit 。但是长按时,不同的红外格式,重发的也不一样。以我现在的了解,我知道,该类方式大部分编码按键在长按时,会再次发送第一次发送的信息(包含所谓的Lead Code)和Stop Bit。但也有特殊的,像红外编码Victor C8D8 这种格式,在长按时,重发部分不含有Lead Code。
对于第一个难点,我发现几乎所有的编码格式,在按键长按时,不管有无Repeat Code,电平中最大时长不超过100ms,最大的在96、97ms左右。所以在我的设计中,把94ms定为学习结束的一个标志,当发现学习的电平中,出现大于94ms的电平,记录下此时的电平并且退出中断,宣告学习结束。在这种情况下,对于发送信息中没有超过94ms的红外编码格式,这个结束条件就永远不会成立,这时,我就采用能学习的电平个数作为结束条件。分析大部分编码格式,特别是不含有Repeat Code的编码,到达第一个Stop Bit 位,其中Panasonic 红外编码格式,电平数达到100,所以,我设定自己用于学习电平的数组大小为202。至于为什么会翻倍呢,就跟第二个难点有关。第二个难点,学习电平时要能区分出红外信息中的码字信息和重发信息,所以大前提是,学习时要长按按键。分析大部分编码在按键长按时,并不是发送完第一个Stop Bit之后再发送的信息就是重发信息。这其中还是有特例,像Sharp红外编码格式,它的码字信息要包含两个Stop Bit位,即它要学习到至少出现两次Stop Bit 位,才能区分出码字信息和重发信息。所以我把数组大小定为出现第一个Stop Bit位时,最大电平个数的两倍多。
下面就是怎么区分Stop Bit 和Repeat Code 或者 Stop Bit 和 第二个 Stop Bit
分析各种红外编码,发现大部分红外编码的Stop Bit 位时长都会大于15ms,当然也会有极个别特例,我的设计没有对其进行考虑。而且在含有Repeat Code 的红外编码格式中,Repeat Code 中的最大电平时长和其Stop Bit 的电平时长都会相差很大,通常前者会大于后者至少20ms以上。所以,我在对学到的电平进行分析时,就可以依次检测每个电平,第一次出现大于15ms的电平,它就是Stop Bit ,并记下其在数组中的位置。再去检测其它电平,若出现某个电平大于Stop Bit 电平20ms以上,则视其为Repeat Code,记下其在数组中的位置;若没有出现Repeat Code ,而是再次出现大于15ms 的电平,则说明是编码中的第二个Stop Bit 位,并记录其在数组中的位置。这样才算分析完成。
分析完之后,就是红外发送部分。发送时,根据有无Repeat Code 进行区分。对于有Repeat Code 的编码,短按时,只发送到Stop Bit 位之前的信息;长按时,只发送Stop Bit 和 Repeat Code 之间的信息。对于无Repeat Code 的编码,短按时,发送第二个Stop Bit 位之前的信息;长按时,由于Victor C8D8这种特殊的红外编码,不能简单的再次发送第二个Stop Bit 位之前的信息。而是根据Stop Bit 和 第二个Stop Bit之间的电平个数差和Stop Bit 位所在的电平位数是否相等,来判断长按时的重发信息。若相等,则重发第二个Stop Bit 位之前的信息;若不等,则重发Stop Bit 和 第二个Stop Bit之间的信息。
以上是我个人对学习型红外采取的方法,其中仍然有一些局限,像对于Stop Bit 位电平时长小于10ms 的红外编码,我的方法会失效。因为NEC红外编码的Lead Code 就有9ms 多,这也是我把Stop Bit 位定位15ms 的原因。虽然方法有一定的局限,但大部分红外编码还是可以进行学习的。特拿出来与博友分享,这也是自己的第一篇技术型原创博文,愿大家多多指点和鼓励!!