1 SIRC红外控制解决方案
1.1 协议基础
SIRC代码是一个12位的字;它使用40 kHz红外载波频率的调制。SIRC协议使用位的脉冲距离编码。每个脉冲是一个长600微秒的40 kHz载波爆发。逻辑"1"的传输需要1.8毫秒,而逻辑"0"的传输需要1.2毫秒。(参见图11)
图1. 逻辑位的长度
SIRC(Sony Infrared Remote Control,索尼红外遥控)协议的基本原理。以下是对这些信息的详细解释:
-
SIRC代码结构:SIRC协议的数据由一个12位的字组成,这意味着每次传输包含12位信息。
-
载波频率:SIRC协议使用40 kHz的红外载波频率进行调制,这是红外信号的基本频率。
-
脉冲距离编码:SIRC协议采用脉冲距离编码(Pulse Distance Encoding, PDE)方式来表示数据位。在PDE中,数据位的值由脉冲之间的距离(时间间隔)来确定。
-
脉冲长度:每个数据脉冲都是一个固定长度的40 kHz载波爆发,持续时间为600微秒。
-
逻辑"1"和逻辑"0"的传输时间:
逻辑"1":由一个600微秒的载波脉冲后跟一个1.2毫秒的间隔组成,总共需要1.8毫秒来传输。
逻辑"0":由一个600微秒的载波脉冲后跟一个600微秒的间隔组成,总共需要1.2毫秒来传输。
SIRC帧包含以下字段:
- 开始位:起始脉冲总是2.4毫秒宽,后面跟着一个0.6毫秒的标准间隔。SIRC帧的开始位由一个固定的脉冲宽度组成,这里是2.4毫秒宽的红外载波脉冲。这个起始脉冲后面紧跟着一个0.6毫秒的间隔,这个间隔是标准的空间(无脉冲的时间),用来标识一帧数据的开始。
命令字段:7位长度
- 此字段包含7位,用作命令字段。命令字段允许发送特定的指令,如打开或关闭设备,改变频道等。
地址字段:5位长度
- 此字段包含5位,用作地址字段,用于指定接收命令的特定设备地址。这使得多个设备可以使用相同的SIRC协议进行通信,而不会相互干扰。
图2. 开始位的长度
这种协议时,最低有效位(LSB)首先被传输。因此,它是从LSB到最高有效位(MSB)进行组装的。由使用于它作为7位的命令发送,后面跟随5位的设备地址,所以必须将接收到的12位编码分成两组,一组是7位,另一组是5位。
以下图表展示了一个SIRC帧的示例。 在这个例子中:地址为26h(二进制表示为0100110),命令为Ah(二进制表示为01010)。
图3. SIRC帧的示例
在两个连续的帧之间插入空闲时间,以避免发生冲突。每45毫秒传输一次重复码。
表4. SIRC时序
描述 | 典型值 | 最小值 | 最大值 |
---|---|---|---|
同步脉冲高电平 | 2.4 毫秒 | 2.3 毫秒 | 2.6 毫秒 |
同步脉冲低电平 | 0.6 毫秒 | 0.55 毫秒 | 0.7 毫秒 |
位0周期 | 1.2 毫秒 | 1.1 毫秒 | 1.3 毫秒 |
位1周期 | 1.8 毫秒 | 1.7 毫秒 | 1.9 毫秒 |
SIRC消息接收时间 | 45 毫秒 | - | - |
载波脉冲位时间 | 25 微秒 | - | - |
上表提供了SIRC(Sony Infrared Remote Control)协议中不同信号时序的典型值、最小值和最大值。以下是对这些时序参数的详细解释:
-
同步脉冲高电平:这是SIRC帧开始位的高电平部分,持续时间为2.4毫秒。
-
同步脉冲低电平:紧跟在开始位高电平之后,持续时间为0.6毫秒。
-
位0周期:表示逻辑"0"的脉冲和间隔的总持续时间,为1.2毫秒。
-
位1周期:表示逻辑"1"的脉冲和间隔的总持续时间,为1.8毫秒。
-
SIRC消息接收时间:这是接收整个SIRC消息所需的时间,为45毫秒。
-
载波脉冲位时间:这是载波脉冲本身的持续时间,为25微秒,这通常指的是调制红外载波的单个脉冲宽度。
这些时序参数对于实现SIRC协议的红外信号的生成和解码至关重要。它们确保了信号的可靠传输和接收,同时也允许不同设备能够正确地解析SIRC协议的数据帧。在设计红外遥控器或接收器时,这些参数需要被严格遵守以保证兼容性。
1.2 软件实现
图14. SIRC帧接收机制
定时器中断:
在PWM输入模式下 定时器被用来采样SIRC帧的不同位。我们在每个下降沿和上升沿捕获当前定时器的值,并且在两个沿上生成中断。这个特性使得测量SIRC脉冲的整体和低电平时间变得容易。
- 如果测量的周期等于T = 1200微秒,并且低脉冲持续时间等于T/2 = 600微秒,则该位是逻辑'0'。
- 如果测量的周期等于3T/2 = 1800微秒,并且低脉冲持续时间等于T = 1200微秒,则该位是逻辑'1'。
- 如果测量的整体周期等于3000微秒,并且低脉冲持续时间等于2400微秒,则该位是‘起始位’。
图5:SIRC解决方案流程图
1.2.1 SIRC软件处理示例
定义初始化函数IR_Init()
这个函数用于初始化用于SIRC协议的不同外设。
定义红外线解码函数IR_Decode(IRFrame_TypeDef *ir_frame)
这个函数设计用于在用户应用程序中调用。它解码接收到的SIRC消息。它有一个参数,该参数是一个结构体,包含了IR帧的不同值。
typedef struct {
__IO uint8_t Address; /* 地址字段 */
__IO uint8_t Command; /* 命令字段 */
} IRFrame_TypeDef;
当IRFrameReceived标志等于YES时,必须执行IR_Decode()。
这个函数将IR数据包重置为默认状态。这个函数在TIM3_IRQHandler例程中被调用。每次定时器溢出时,它都会发生以重置IR数据包。
IR_DeInit()
这个函数用于反初始化用于SIRC协议的不同外设。
TIM3_IRQHandler()
这个函数处理TIM捕获比较中断。
- 定时器下降边沿事件:这用于测量两个连续下降边沿之间的不同周期,以便识别帧位。
- 定时器上升边沿事件:这用于测量下降边沿和上升边沿之间的持续时间(低电平脉冲持续时间)。
- 更新事件(超时事件):这用于重置SIRC数据包。定时器溢出被设置为4毫秒。
从这两个持续时间中,我们确定位值。
4.4 如何使用SIRC解码器驱动
要使用SIRC解码器驱动,请按照以下步骤进行:
– 使用TIM3捕获比较和更新中断来解码IR帧。如果正确接收到一个帧,全局变量“IRFrameReceived”将被设置,以通知应用程序。
– 然后,应用程序应该调用IR_Decode()函数来检索接收到的IR帧。
– 你可以很容易地将这个驱动适配到任何其他红外协议,只需调整sirc_decode.h中的定义以适应红外协议规范(位持续时间、头部持续时间、边缘容差、位数...),以及ir_commands.c中的命令和设备表。
代码示例:
#include "ir_decode.h"
#include "mcu.h"
IR_Frame_TypeDef IR_FRAME;
/* Initialize the Color LCD mounted on mcu */
MCU_Init();
/* Clear the LCD */
LCD_Clear(LCD_COLOR_WHITE);
IR_Init();
/* SIRC */
IR_Decode(&IR_FRAME);
注意:1 TIM3_IRQHandler中断服务例程(ISR)在ir_decode.c驱动文件中已经编写完成。
● 如果你在你的应用程序中使用了一个或两个中断,你需要谨慎操作:
- 要么在这些ISR中添加你的应用程序代码
- 要么将这些ISR的内容复制到你的应用程序代码中
2 你可以通过修改"ir_decode.h"文件中的不同定义声明来轻松地将此应用程序适配到你自己的硬件上。
表5. 实现示例
定义名称 | 描述 | 允许的值 | 示例 |
---|---|---|---|
#define IR_TIM | 用于IR解码的定时器 | TIM1, TIM2, TIM3, TIM4, TIM5, TIM8, TIM9, TIM12, TIM15 | TIM3 |
#define TIM_PRESCALER | TIM预分频器 | 这个参数是计算出来的,以便以1微秒作为时间基准。TIM频率(MHz) / (预分频器 + 1) | 23 |
#define IR_TIM_CLK | 使用的定时器的APB时钟 | 参考RCC固件驱动 RCC_APB1Periph_TIM | 3 |
#define IR_TIM_IRQn | IR TIM中断请求编号 | 参考MCU_STARTUP文件,例如TIM3_IRQn | TIM3_IRQn |
#define IR_TIM_Channe | IR TIM通道 | TIM_Channel_1或者TIM_Channel_2 | TIM_Channel_1 |
#define IR_GPIO_PORT | 红外输出连接的端口 | 参考您的产品引脚配置(1) | GPIOC |
#define IR_GPIO_PORT_CLK | IR引脚GPIO时钟端口 | 参考RCC固件驱动,例如RCC_APB2Periph_GPIOx | RCC_APB2Periph_GPIOC |
#define IR_GPIO_PIN | 红外连接的引脚 | 参考您的产品引脚配置(1) | GPIO_Pin_6 |
2 接口层
为了方便使用红外协议驱动程序,采用了一个接口层(IR_decode)。
图6. 应用层架构
红外协议可以通过在IR_decode.h中定义的固件来选择。
#define IR_RC5_PROTOCOL
#define IR_SIRC_PROTOCOL
存在许多类似的红外协议,它们通过时序参数来区分,比如SIRC协议。这些协议由ir_decode.c中的函数来处理。您只需要更新时序值即可。
还有一些与其他协议完全不同的协议,它们由特定的函数来处理,比如RC5协议和与之关联的驱动程序rc5_decode.c。
每种协议都有一个特定的帧结构。IR_FRAME是指向所选红外协议结构的指针,它包含了通信所需的主要信息(设备地址和命令)。
2.1 应用层调用固件的方法
int32_t main(void)
{
#if defined IR_RC5_PROTOCOL
IR_RC5_Init();
#else
IR_Init();
#endif
while(1)
{
#if defined (IR_RC5_PROTOCOL)
/* RC5 */
IR_RC5_Decode(&IR_FRAME);
#else
IR_Decode(&IR_FRAME);
#endif
}
}