简介
本文介绍STM8L系列如何使用红外发射管发射38K信号。
其中,红外协议采用为最常见的NEC协议,38K信号由定时器产生。
实验平台
编译软件:IAR for STM8 1.42.2
硬件平台:stm8l101f3p6开发板
仿真器:ST-LINK
库函数版本:STM8L_STMTouch_Lib_V1.1.0
硬件原理
1、发射管元器件
附淘宝链接:
https://detail.tmall.com/item.htm?spm=a1z10.3-b.w4011-3079905380.29.6Sd192&id=16965424268&rn=40b8f46057241ffac5e0d72df2c9b8d7&abbucket=14
2、原理图
上图的蓝色部分为红外发射部分,R2为红外距离调节的电阻,阻值越小、距离越远。
基础知识
1、什么是红外?
答:红外是红外线的简称。红外是一种波长范围为760nm~ 1mm的电磁波,可以实现数据的无线传输,距离大概十几米以内,且需要对准接收端进行发射。
红外的成本比其它无线设备要低的多,所以家电遥控器大多采用红外控制。常见的红外设备:电视遥控器、空调遥控器等。
遥控器的基带通信协议有很多,大概有几十种。常见的红外协议: ITT 协议、NEC 协议(最常见)、Sharp 协议、Philips RC-5 协议、Sony SIRC 协议等。
2、什么是NEC协议?
答:NEC协议的数据格式:引导码、用户码、用户反码、键码、键码反码、停止位。
注意几点:
1)上图黑色部分为一定频率(如38K)的载波,并不是长时间的高电平。该载波可通过定时器定时翻转IO口或PWM来产生。
2)上图为发射端的信号波形,由于接收端空闲时为高电平、接收到载波时为低电平,因此接收端的信号波形与发射端信号波形完全相反,接收端信号波形如下图
3)时序如下:
①引导码:9ms 的载波+4.5ms 的空闲。
②比特值“0”:560us 的载波+560us 的空闲。
③比特值“1”:560us 的载波+1.68ms 的空闲。
4)举例(上图的接收信号波形来读数据):
①引导码:9ms 的载波+4.5ms 的空闲。
②用户码:0x00。
③用户码反码:0xFF。
④键码:0x30。
⑤键码反码:0xCF。
⑥停止位。
所以解析出来的红外键值为:0x00FF30CF(4个字节)。
3、本文中编码红外发射的流程是如何的?
答:
1)使用定时器2产生一个13us的定时中断(当13us翻转一次IO,产生的就是38K的频率)。
2)当需要发送红外键值时,按上图的NEC时序依次发送:引导码、用户码、用户反码、键码、键码反码、停止位。
实验前提
在进行本文步骤前,请先阅读并实现以下博文:
1、《STM8L之timer2》:
http://blog.csdn.net/feilusia/article/details/53167211实验步骤
1、修改定时器产生中断的时间(替换GUA_Timer2.c中的GUA_Timer2_Init)
//******************************************************************************
//name: GUA_Timer2_Init
//introduce: 定时器2初始化
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.11.15
//******************************************************************************
void GUA_Timer2_Init(void)
{
//时钟配置
CLK_PeripheralClockConfig(CLK_Peripheral_TIM2,ENABLE);
//1分频,向上计数,每13us定时中断一次(实测设置9为17us)
TIM2_DeInit();
TIM2_TimeBaseInit(TIM2_Prescaler_1, TIM2_CounterMode_Up, 16*9);
TIM2_ARRPreloadConfig(ENABLE);
TIM2_ITConfig(TIM2_IT_Update , ENABLE);
TIM2_Cmd(ENABLE);
}
由于香瓜使用的是内部晶振导致定时器不准,并且定时器产生13us时会影响代码正常运行,因此香瓜实测代码中设置为9us时能产生17us的红外载波。
2、工程中添加自己写的红外发射的驱动
1)写一个驱动GUA_Infrared_Send.c(存放在工程的USER文件夹中)
//******************************************************************************
//name: GUA_Infrared_Send.c
//introduce: 红外传感器发送驱动
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.11.16
//******************************************************************************
#include "stm8l10x.h"
#include "GUA_Infrared_Send.h"
/*********************宏定义************************/
#ifndef U8
typedef unsigned char U8;
#endif
#ifndef U16
typedef unsigned short U16;
#endif
#ifndef U32
typedef unsigned long U32;
#endif
/*********************外部变量************************/
//红外开关的标志位
U8 gGUA_Infrared_Flag = GUA_INFRARED_FLAG_OFF;
//红外38K脉冲翻转次数
U16 gGUA_Infrared_Count = 0;
//******************************************************************************
//name: GUA_Infrared_Send
//introduce: 红外发送
//parameter: nGUA_Data:要发送的数据
//return: none
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.11.16
//******************************************************************************
void GUA_Infrared_Send(U32 nGUA_Data)
{
U8 i = 0;
//初始化红外,默认为关
gGUA_Infrared_Flag = GUA_INFRARED_FLAG_OFF;
//9ms起始信号低电平,683*13us=8.879ms(后面的*3/4为实际的校准值)
gGUA_Infrared_Count = 683*3/4;
gGUA_Infrared_Flag = GUA_INFRARED_FLAG_ON;
while(gGUA_Infrared_Count);
//4.5ms起始信号高电平,341*13=4.433ms(后面的*3/4为实际的校准值)
gGUA_Infrared_Count = 341*3/4;
gGUA_Infrared_Flag = GUA_INFRARED_FLAG_OFF;
while(gGUA_Infrared_Count);
//循环发送32bit的数据
for(i = 0; i < 32; i++)
{
//通用的0.56ms低电平,42*13us=0.546ms(后面的*3/4为实际的校准值)
gGUA_Infrared_Count = 42*3/4;
gGUA_Infrared_Flag = GUA_INFRARED_FLAG_ON;
while(gGUA_Infrared_Count);
//数值0
if((nGUA_Data & 0x80000000) == 0)
{
//0.565ms高电平,43*13us=0.559ms(后面的*3/4为实际的校准值)
gGUA_Infrared_Count = 43*3/4;
}
//数值1
else
{
//1.69ms高电平,128*13us=1.664ms(后面的*3/4为实际的校准值)
gGUA_Infrared_Count = 128*3/4;
}
//执行高电平
gGUA_Infrared_Flag = GUA_INFRARED_FLAG_OFF;
while(gGUA_Infrared_Count);
//数据移位
nGUA_Data <<= 1;
}
//0.263ms低电平作为结束位,20*13=0.26ms(后面的*3/4为实际的校准值)
gGUA_Infrared_Count = 20*3/4;
gGUA_Infrared_Flag = GUA_INFRARED_FLAG_ON;
while(gGUA_Infrared_Count);
//关闭红外
gGUA_Infrared_Flag = GUA_INFRARED_FLAG_OFF;
}
//******************************************************************************
//name: GUA_Infrared_Send_Init
//introduce: 红外发送初始化
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』