有读者私信我,要获得更详细的内情。很抱歉,因为时间实在有限,而且对于实际场景不了解,所以,简单地更新,添加了点儿内容。至于更加详细的电路图和源码需要额外时间继续补充。
前言
最近使用STM8L152做产品,需要基于红外线通讯的Bootloader。发现STM8L05X/15X是红外通讯的绝配。
红外线大致有CIR和SIR两种。前者主要用于5~10米距离的红外遥控器,采用38kHz载波,有大量的廉价接收解码器可用。后者是IrDa标准之一,曾经是功能手机和笔记本电脑的标准配置,其堆栈和配置实体设计与蓝牙比较像,物理层采用3/16载波方式,需要单独的收发模块。
消费电子的红外遥控器
电子、DVD、机顶盒、空调等传统消费电子中常见的遥控器,我们称之为CIR, Consumer Infra Red。CIR通常使用980nm红外线,还需要采用38KHz~40KHz载波以避免可见光干扰。CIR需要编码和解码电路。
我们可以找到若干编码电路。如果由MCU来实现,则需要产生38~40KHz 载波,另外根据特定的红外遥控协议,如SONY/Philips RC5等产生二进制码流。并利用逻辑门或者三极管来实现二进制码流对于载波的调制。理论上,二进制码流和载波还有一定的时序关系,但是实践下来,这种时序关系的容错率很高。
至于CIR的红外接收部分,因为产量比较大,有低成本模块供应,内置38~40KHz载波发生器,并直接输出解调后的二进制码流。所以解码接收部分任意MCU都可以实现。
综上所述,STM8L的CIR方案中,主要考虑的是编码发射端。
IRC + GPIO + 二极管
MCU产生38KHz载波最常见的方法是使用定时器。包括设定38KHz的中断,并在中断中去切换GPIO引脚。或者设定一个占空比为50%的PWM中断。其道理是类似的。同时,由软件或者另外一种定时器来产生定时中断,产生二进制码流。两者在外部使用CIR二极管相连,当两个GPIO压差为VCC时,IR二极管点亮,压差为零时,IR二极管关闭。这样就形成了最简单的CIR遥控器。
对于STM8L来说,其内部的低频RC振荡器频率正好在38KHz,当然有些误差,但是对于CIR来说要求没有那么严格。由于是内部IRC,所以并不需要使用定时器来产生中断。
Bootloader与中断
通常38kHz载波采用定时器产生PWM。但是Bootloader状态下必须关闭所有中断。这就限制了许多MCU在这种状态的使用。有部分设计只用了单向传输,但是这种方式试错成本太高了。
STM8L05X内部低速RC就是38kHz。而且可以从引脚引出来为载波,实测37.2kHz。配合USART可以直接构成双向红外通讯和遥控器。比STM推荐的IRTM还好用。
基于消费红外线的串口通讯
消费者红外线技术是单向的:遥控器负责编码和发射红外线,设备负责接收和解码。在某些环境中,比如说水电煤表的自动抄表系统中,则需要建立起双向红外线通道。
红外线和无线电通讯类似,采用半双工通讯方式。所以软件角度必须要确保时序,不要造成双方的通讯冲突。同时硬件上也可以采取一些方法,保证己方在发射时不进行接收,避免自发自收。
由于38KHz载波的存在,其波特率收到限制,我测试过9.6kbps,但是工作在2.4kbps,误码率要少许多。
在Bootloader模式下,USART RXD可以采用polling方式实现,在低速率情况下不会掉数据。
消费红外编码与解码
这个其实和STM8无关了,可以参考Arduino的红外编码和红外解码库。总的思路是将红外切割成一个个小的时间片,而无需太多考虑RC5/SONY/Toshiba/RCA等不同的红外遥控协议,直接使用一串二进制数据来编码。这也是大多数通用学习型红外遥控器的原理。
具体实现请参考 How to make IR decoder 以及 How to setup an IR remote and receiver on an Arduino.
IrDa SIR串口通讯
STM8的片内USART外设是支持IRDA SIR收发标准的。这是一种国际标准,早期移动电话和其他数据终端中多采用此类标准,通讯速率较高,可达到115.2kbps。但相对应的,它的红外收发模组成本在20多元人民币,比消费红外模块贵许多。
STM8的架构限制
STM8的原始MCU架构来自意法半导体的ST7,是意法自主开发的内核。这里额外提一下,意法的STR7和ST7不同,是基于ARM7TDMI内核的产品线。STM8在ST7上做了很多改变,与STM32保持了引脚一致性。所以,STM8是一个性价比较高的MCU。
警告
但是STM8的ITC(中断控制)部分却存在着较大的问题。通过仿真器,我觉得和STM8的虚拟存储器以及压栈的先后顺序有关联。在某些极端嵌套中断情况下会导致堆栈溢出,或者一些莫名其妙的问题。具体请留意STM8 Error Sheet。
所以STM8在中断设计方面不能够采用过于复杂的嵌套设计,同时需要做些黑盒压力测试。
本文中的某些做法,如利用IRC直接产生38~40KHz载波的方式,可以作为一种思路,在其他MCU中继续使用。比如STM32F030F4 IRC40KHz/LPC812 SCT等。