模块来源
规格参数
移植过程
我们的目标是将例程移植至开发板上【能够实现红外信号接收的功能】。首先要获取资料,查看数据手册应如何实现读取数据,再移植至我们的工程。
查看资料
在光谱中波长自760nm至400um的电磁波称为红外线,它是一种不可见光。红外线通信的例子我们每个人应该都很熟悉,目前常用的家电设备几乎都可以通过红外遥控的方式进行遥控,比如电视机、空调、投影仪等,都可以见到红外遥控的影子。这种技术应用广泛,相应的应用器件都十分廉价,因此红外遥控是我们日常设备控制的理想方式。
红外线的通讯原理
红外光是以特定的频率脉冲形式发射,接收端收到到信号后,按照约定的协议进行解码,完成数据传输。在消费类电子产品里,脉冲频率普遍采用 30KHz 到 60KHz 这个频段,NEC协议的频率就是38KHZ。 这个以特定的频率发射其实就可以理解为点灯,不要被复杂的词汇难住了,就是控制灯的闪烁频率(亮灭),和刚学单片机完成闪烁灯一样的意思,只不过是灯换了一种类型,都是灯。
接收端的原理: 接收端的芯片对这个红外光比较敏感,可以根据有没有光输出高低电平,如果发送端的闪烁频率是有规律的,接收端收到后输出的高电平和低电平也是有规律对应的,这样发送端和接收端只要约定好,那就可以做数据传输了。
红外线传输协议可以说是所有无线传输协议里成本最低,最方便的传输协议了,但是也有缺点,距离不够长,速度不够快;当然,每个传输协议应用的环境不一样,定位不一样,好坏没法比较,具体要看自己的实际场景选择合适的通信方式。
NEC协议介绍
NEC协议是众多红外线协议中的一种(这里说的协议就是他们数据帧格式定义不一样,数据传输原理都是一样的),我们购买的外能遥控器、淘宝买的mini遥控器、电视机、投影仪几乎都是NEC协议。 像格力空调、美的空调这些设备使用的就是其他协议格式,不是NEC协议,但是只要学会一种协议解析方式,明白了红外线传输原理,其他遥控器协议都可以解出来。
NEC协议一次完整的传输包含: 引导码、8位地址码、8位地址反码、8位命令码、8位命令反码。这里我们主要讲解如何接收红外发送端发送的NEC协议内容。
引导码:由9ms的低电平+4.5ms的高电平组成。
4个字节的数据: 地址码+地址反码+命令码+命令反码。 这里的反码可以用来校验数据是否传输正确,有没有丢包。
重点: NEC协议传输数据位的时候,0和1的区分是依靠收到的高、低电平的持续时间来进行区分的。这是解码关键。
数据发送0码:0.56ms低电平+ 0.56ms的高电平。
数据发送1码:0.56ms低电平+1.68ms的高电平
所以,收到一个数据位的完整时间表示方法是这样的:
收到数据位0: 0.56ms低电平+ 0.56ms的高电平
收到数据位1: 0.56ms低电平+1.68ms的高电平
还有一个重复码,它是由一个 9ms 的低电平和一个 2.5ms 的高电平组成。当一个红外信号连续发送时,可以通过发送重复码的方式快速发送。
引脚选择
这里选择的引脚见引脚接线表
代码移植
下载为大家准备的驱动代码文件夹,复制到自己工程中\luban-lite\application\rt-thread\helloworld\user-bsp
文件夹下
提示
如果未找到 user-bsp
这个文件夹,说明你未进行模块移植的前置操作。请转移到手册使用必要操作(点击跳转)中进行必要的配置操作!!!
接下来打开自己的工程,开始修改Kconfig文件。
1、在 VSCode 中打开 application\rt-thread\helloworld\Kconfig 文件
2、在该文件的 #endif
前面添加该模块的 Kconfig路径语句
# 红外接收模块
source "application/rt-thread/helloworld/user-bsp/infrared-receiving-module/Kconfig"
2
menuconfig操作
1、我们 双击 luban-lite
文件夹下的 win_env.bat
脚本打开env工具:
2、输入以下命令列出所有可用的默认配置:
scons --list-def
3、选择 d13x_JLC_rt-thread_helloworld
这个配置!这个是我们衡山派开发板的默认配置!输入以下命令即可:
scons --apply-def=7
或者
scons --apply-def=d13x_JLC_rt-thread_helloworld_defconfig
这两个命令作用是一样的,一个是 文件名 ,一个是 编号 !!!
4、输入以下命令进入menuconfig菜单
scons --menuconfig
进入以下界面:
5、选中 Porting code using the LCKFB module
按
Y
选中按
N
取消选中方向键
左右
调整 最下面菜单的选项方向键
上下
调整 列表的选项
回车
执行最下面菜单的选项
6、回车进入 Porting code using the LCKFB module
菜单
7、按方向键 上下
选中 Using infrared receiving module
后按 Y
键,看到前面括号中出现一个 *
号,就可以下一步了。
8、按方向键 左右
选中 <Save>
然后一路回车
,然后 退出
即可
编译
我们 保存并退出menuconfig菜单 之后,输入以下命令进行编译:
scons
或
scons -j16
-j 用来选择参与编译的核心数: 我这里是选择16
大家可以根据自己的电脑来选择
核心越多编译越快
如果写的数量高于电脑本身,那么就自动按照最高可用的来运行!
镜像烧录
编译完成之后会在 \luban-lite\output\d13x_JLC_rt-thread_helloworld\images
文件夹下生成一个 d13x_JLC_v1.0.0.img
镜像文件!
然后我们烧录镜像,具体的教程请查看:镜像烧录(点击跳转🚀)
到这里完成了,请移步到 最后一节 进行移植验证。
工程代码解析
bsp_hx1838b.c
/*
* 立创开发板软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 文档网站:wiki.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 嘉立创社区问答:https://www.jlc-bbs.com/lckfb
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
*/
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <sys/time.h>
#include <rtthread.h>
#include "hal_adcim.h"
#include "rtdevice.h"
#include "aic_core.h"
#include "aic_log.h"
#include "hal_gpai.h"
#include <stdio.h>
#include "aic_hal_gpio.h"
#include "bsp_hx1838b.h"
typedef struct INFRARED_DATA {
char AddressCode; //地址码
char AddressInverseCode; //地址反码
char CommandCode; //命令码
char CommandInverseCode; //命令反码
} _INFRARED_DATA_STRUCT_ ;
/* 数据存储 */
static _INFRARED_DATA_STRUCT_ InfraredData;
// 引脚
#define HX1838B_PIN rt_pin_get("PE.14")
#define HX1838B_Pin_Get() rt_pin_read(HX1838B_PIN)
static void delay_us(uint32_t us){ aicos_udelay(us); }
/**********************************************************
* 函 数 名 称:HX1838B_Get_LowTime
* 函 数 功 能:获取红外低电平时间
* 传 入 参 数:无
* 函 数 返 回:无
* 作 者:LCKFB
* 备 注:以微秒us作为时间参考
**********************************************************/
static void HX1838B_Get_LowTime(uint32_t *low_time)
{
uint32_t time_val = 0;
while( HX1838B_Pin_Get() == 0 )
{
if( time_val>= 500 )
{
*low_time = time_val;
return;
}
delay_us(20);
time_val++;
}
*low_time = time_val;
}
/**********************************************************
* 函 数 名 称:HX1838B_Get_HighTime
* 函 数 功 能:获取红外高电平时间
* 传 入 参 数:无
* 函 数 返 回:无
* 作 者:LCKFB
* 备 注:以微秒us作为时间参考
**********************************************************/
static void HX1838B_Get_HighTime(uint32_t *high_time)
{
uint32_t time_val = 0;
while( HX1838B_Pin_Get() == 1 )
{
if( time_val >= 250 )
{
*high_time = time_val;
return;
}
delay_us(20);
time_val++;
}
*high_time = time_val;
}
/******************************************************************
* 函 数 名 称:HX1838B_Guide_Repeat_Judgment
* 函 数 说 明:引导 和 重复 码 判断
* 函 数 形 参:1:不是引导码 2:重复码 0:引导码
* 函 数 返 回:RT_EOK成功 -RT_ERROR错误
* 作 者:LCKFB
* 备 注:以20微秒us作为时间参考
引导码:由一个 9ms 的低电平和一个 4.5ms 的高电平组成
重复码:由一个 9ms 的低电平和一个 2.5ms 的高电平组成
******************************************************************/
static int HX1838B_Guide_Repeat_Judgment(uint8_t *returnValue)
{
uint32_t out_time = 0;
HX1838B_Get_LowTime(&out_time);
//time>10ms time <8ms
if((out_time > 500) || (out_time < 400))
{
return 1;
}
HX1838B_Get_HighTime(&out_time);
// x>5ms 或者 x<2ms
if((out_time > 250) || (out_time < 100))
{
return 1;
}
//如果是重复码 2ms < time < 3ms
if((out_time > 100) && (out_time < 150))
{
return 2;
}
return 0;
}
/******************************************************************
* 函 数 名 称:HX1838B_Validate_Infrared_Data
* 函 数 说 明:红外数据是否正确判断
* 函 数 形 参:value数据缓存地址
* 函 数 返 回:RT_EOK成功 -RT_ERROR错误
* 作 者:LCKFB
* 备 注:
******************************************************************/
static int HX1838B_Validate_Infrared_Data(uint8_t *value)
{
//判断地址码是否正确
if( value[0] != (uint8_t)(~value[1]) ) return -RT_ERROR;
//判断命令码是否正确
if( value[2] != (uint8_t)(~value[3]) ) return -RT_ERROR;
rt_kprintf("\n\n=======================\n");
rt_kprintf("\n%x %x %x %x\n",value[0],value[1],value[2],value[3]);
rt_kprintf("\n=======================\n");
//保存正确数据
InfraredData.AddressCode = value[0];
InfraredData.AddressInverseCode = value[1];
InfraredData.CommandCode = value[2];
InfraredData.CommandInverseCode = value[3];
return RT_EOK;
}
/******************************************************************
* 函 数 名 称:HX1838B_Receiving_Infrared_Data
* 函 数 说 明:接收红外数据
* 函 数 形 参:无
* 函 数 返 回:RT_EOK成功 -RT_ERROR错误
* 作 者:LCKFB
* 备 注:
******************************************************************/
static int HX1838B_Receiving_Infrared_Data(void)
{
uint16_t group_num = 0,data_num = 0;
uint32_t time=0;
uint8_t bit_data = 0;
uint8_t ir_value[5] = {0};
uint8_t guide_and_repeat_code = 0;
//等待引导码
HX1838B_Guide_Repeat_Judgment(&guide_and_repeat_code);
//如果不是引导码则结束解析
if( guide_and_repeat_code == 1 )
{
LOG_E("[Function:%s] [Line:%d] failed !!", __FUNCTION__, __LINE__);
return -RT_ERROR;
}
//共有4组数据
//地址码+地址反码+命令码+命令反码
for(group_num = 0; group_num < 4; group_num++ )
{
//接收一组8位的数据
for( data_num = 0; data_num < 8; data_num++ )
{
//接收低电平
HX1838B_Get_LowTime(&time);
//如果不在0.56ms内的低电平,数据错误
if((time > 60) || (time < 20))
{
return -RT_ERROR;
}
time = 0;
//接收高电平
HX1838B_Get_HighTime(&time);
//如果是在1200us < t < 2000us范围内则判断为1
if((time >=60) && (time < 100))
{
bit_data = 1;
}
//如果是在200us<t<1000us范围内则判断为0
else if((time >= 10) && (time < 50))
{
bit_data = 0;
}
//groupNum表示第几组数据
ir_value[ group_num ] <<= 1;
//接收的第1个数为高电平;在第二个for循环中,数据会向右移8次
ir_value[ group_num ] |= bit_data;
//用完时间要重新赋值
time = 0;
}
}
//判断数据是否正确,正确则保存数据
if(RT_EOK != HX1838B_Validate_Infrared_Data(ir_value))
{
LOG_E("[Function:%s] [Line:%d] failed !!", __FUNCTION__, __LINE__);
return -RT_ERROR;
}
return RT_EOK;
}
/* 引脚中断回调函数 */
static void HX1838B_Interrupt_Callback_Function(void)
{
//接收一次红外数据
HX1838B_Receiving_Infrared_Data();
}
/**********************************************************
* 函 数 名 称:HX1838B_Get_Command
* 函 数 功 能:返回接收到的命令码
* 传 入 参 数:无
* 函 数 返 回:RT_EOK成功 -RT_ERROR失败
* 作 者:LCKFB
* 备 注:
**********************************************************/
int HX1838B_Get_Command(uint8_t *Commands)
{
if(InfraredData.CommandCode == -1)
{
return -RT_ERROR;
}
/* 转存数据 */
*Commands = InfraredData.CommandCode;
/* 清除数据 */
HX1838B_Clean_Save();
return RT_EOK;
}
/**********************************************************
* 函 数 名 称:HX1838B_Clean_Save
* 函 数 功 能:清除接收到的地址码
* 传 入 参 数:无
* 函 数 返 回:无
* 作 者:LCKFB
* 备 注:
**********************************************************/
void HX1838B_Clean_Save(void)
{
InfraredData.AddressCode = -1;
InfraredData.AddressInverseCode = -1;
InfraredData.CommandCode = -1;
InfraredData.CommandInverseCode = -1;
return RT_EOK;
}
/**********************************************************
* 函 数 名 称:HX1838B_Init
* 函 数 功 能:初始化红外接收模块
* 传 入 参 数:无
* 函 数 返 回:RT_EOK成功 -RT_ERROR失败
* 作 者:LCKFB
* 备 注:
**********************************************************/
int HX1838B_Init(void)
{
int ret = 0;
/* 引脚为输入模式 */
rt_pin_mode(HX1838B_PIN, PIN_MODE_INPUT_PULLUP);
/* 绑定中断,下降沿模式,回调函数名为 HX1838B_Interrupt_Callback_Function */
ret = rt_pin_attach_irq(HX1838B_PIN, PIN_IRQ_MODE_FALLING, HX1838B_Interrupt_Callback_Function, RT_NULL);
if(ret != RT_EOK)
{
LOG_E("[Function:%s] [Line:%d] failed !!", __FUNCTION__, __LINE__);
return -RT_ERROR;
}
/* 使能中断 */
ret = rt_pin_irq_enable(HX1838B_PIN, PIN_IRQ_ENABLE);
if(ret != RT_EOK)
{
LOG_E("[Function:%s] [Line:%d] failed !!", __FUNCTION__, __LINE__);
return -RT_ERROR;
}
return RT_EOK;
}
/**********************************************************
* 函 数 名 称:HX1838B_DeInit
* 函 数 功 能:清除初始化红外接收模块
* 传 入 参 数:无
* 函 数 返 回:RT_EOK成功 -RT_ERROR失败
* 作 者:LCKFB
* 备 注:
**********************************************************/
int HX1838B_DeInit(void)
{
int ret = 0;
/* 失能中断 */
ret = rt_pin_irq_enable(HX1838B_PIN, PIN_IRQ_DISABLE);
if(ret != RT_EOK)
{
LOG_E("[Function:%s] [Line:%d] failed !!", __FUNCTION__, __LINE__);
return -RT_ERROR;
}
/* 解绑中断 */
ret = rt_pin_detach_irq(HX1838B_PIN);
if(ret != RT_EOK)
{
LOG_E("[Function:%s] [Line:%d] failed !!", __FUNCTION__, __LINE__);
return -RT_ERROR;
}
return RT_EOK;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
bsp_hx1838b.h
/*
* 立创开发板软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 文档网站:wiki.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 嘉立创社区问答:https://www.jlc-bbs.com/lckfb
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
*/
#ifndef __BSP_HX1838B_H__
#define __BSP_HX1838B_H__
#include "stdio.h"
int HX1838B_Init(void);
int HX1838B_DeInit(void);
int HX1838B_Get_Command(uint8_t *Commands);
void HX1838B_Clean_Save(void);
#endif
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Kconfig
这个是一个menuconfig中的选项,如果在菜单中选中该选项,就会在rtconfig.h
中定义一个语句,用来if判断条件编译之类的。
config LCKFB_HX1928B_IR_RECEIVE_MODULE
bool "Using infrared receiving module"
default n
help
More information is available at: https://wiki.lckfb.com/
2
3
4
5
SConscript
自动化构建文件,如果定义了 LCKFB_HX1928B_IR_RECEIVE_MODULE
和 USING_LCKFB_TRANSPLANT_CODE
就自动编译当前目录下的文件!!
Import('RTT_ROOT')
Import('rtconfig')
import rtconfig
from building import *
cwd = GetCurrentDir()
CPPPATH = [cwd]
src = []
if GetDepend('LCKFB_HX1928B_IR_RECEIVE_MODULE') and GetDepend('USING_LCKFB_TRANSPLANT_CODE'):
src = Glob(os.path.join(cwd, '*.c'))
group = DefineGroup('lckfb-infrared-receiving-module', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
test_infrared-receiving-module.c
这个文件定义了一个处理HX1838B红外接收模块的线程,初始化了红外接收模块的板级支持包(BSP),并设置了线程的优先级、栈大小和时间片。
线程的主要任务是循环检测HX1838B红外接收模块是否接收到特定的命令,并在控制台上打印相应的信息。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <getopt.h>
#include <sys/time.h>
#include <rtthread.h>
#include "rtdevice.h"
#include "aic_core.h"
#include "aic_hal_gpio.h"
#include "bsp_hx1838b.h"
#define THREAD_PRIORITY 25 // 线程优先级
#define THREAD_STACK_SIZE 1024 // 线程大小
#define THREAD_TIMESLICE 25 // 时间片
static rt_thread_t hx1838b_thread = RT_NULL; // 线程控制块
// 线程入口函数
static void hx1838b_thread_entry(void *param)
{
int while_count = 1;
while(while_count++)
{
uint8_t Commands = 0;
if(RT_EOK == HX1838B_Get_Command(&Commands))
{
if(Commands == 0xA2)
{
rt_kprintf("按下【1】按键 !!\n");
}
}
/* 循环提示 */
if(while_count >= 500)
{
while_count = 1;
rt_kprintf("\nType [test_exit_infrared_receiving_module] command to exit \n");
rt_kprintf("Note: Pressing [TAB] as you type will autocomplete the command\n");
rt_thread_mdelay(2000);
}
rt_thread_mdelay(100);
}
}
static void test_infrared_receiving_module(int argc, char **argv)
{
int ret = HX1838B_Init();
if(ret != RT_EOK)
{
LOG_E("Failed to [HX1838B_Init] !!!");
return;
}
/* 创建线程,名称是 hx1838b_thread,入口是 hx1838b_thread_entry */
hx1838b_thread = rt_thread_create("hx1838b_thread",
hx1838b_thread_entry, RT_NULL,
THREAD_STACK_SIZE,
THREAD_PRIORITY, THREAD_TIMESLICE);
/* 如果获得线程控制块,启动这个线程 */
if (hx1838b_thread != RT_NULL)
rt_thread_startup(hx1838b_thread);
}
// 导出函数为命令
MSH_CMD_EXPORT(test_infrared_receiving_module, Infrared receiving module);
/* 退出函数 */
void test_exit_infrared_receiving_module(void)
{
int ret = rt_thread_delete(hx1838b_thread);
if(ret != RT_EOK)
{
LOG_E("failed to test_exit_infrared_receiving_module !!");
return;
}
ret = HX1838B_DeInit();
if(ret != RT_EOK)
{
LOG_E("Failed to [HX1838B_DeInit] !!!");
return;
}
else
{
rt_kprintf("\nHX1838B_DeInit successful!!!\n");
}
rt_kprintf("\n========hx1838b sensor exit successful !!========\n");
}
// 导出函数为命令
MSH_CMD_EXPORT(test_exit_infrared_receiving_module, exit Infrared receiving module);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
线程入口函数逻辑
- 定义一个整型变量
while_count
用于记录循环次数,并初始化为1。 - 在一个无限循环中,首先尝试从HX1838B红外接收模块获取命令。
- 如果成功获取命令,并且命令是
0xA2
,则打印“按下【1】按键 !!”。 - 当循环次数达到500次时,提示用户可以通过输入命令来退出传感器读取循环,并重置循环次数。
- 在每次循环结束时,线程会挂起一段时间,这里是100毫秒。
此外,该文件还定义了两个命令,test_infrared_receiving_module
和test_exit_infrared_receiving_module
,它们分别用于启动和退出红外接收模块线程。
test_infrared_receiving_module
命令首先调用HX1838B_Init
函数来初始化HX1838B红外接收模块。如果初始化成功,则创建并启动一个名为hx1838b_thread
的线程,该线程将执行hx1838b_thread_entry
函数。test_exit_infrared_receiving_module
命令用于删除hx1838b_thread
线程,从而退出红外接收模块的数据处理循环,并打印退出成功的消息。在退出之前,它会调用HX1838B_DeInit
函数来反初始化红外接收模块。如果删除线程或反初始化红外接收模块失败,将打印错误信息。
通过在命令行中输入test_infrared_receiving_module
,用户可以启动HX1838B红外接收模块的数据处理线程,并且每当接收到特定命令时,都会在控制台上看到相应的输出信息。输入test_exit_infrared_receiving_module
命令可以退出数据处理线程。
以下是代码中的关键点:
HX1838B_Get_Command
函数用于从HX1838B红外接收模块获取接收到的命令。LOG_E
宏用于打印错误信息。MSH_CMD_EXPORT
宏用于将函数导出为命令行接口,使得用户可以在命令行中直接调用这些函数。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <getopt.h>
#include <sys/time.h>
#include <rtthread.h>
#include "rtdevice.h"
#include "aic_core.h"
#include "aic_hal_gpio.h"
#include "bsp_hx1838b.h"
#define THREAD_PRIORITY 25 // 线程优先级
#define THREAD_STACK_SIZE 1024 // 线程大小
#define THREAD_TIMESLICE 25 // 时间片
static rt_thread_t hx1838b_thread = RT_NULL; // 线程控制块
// 线程入口函数
static void hx1838b_thread_entry(void *param)
{
int while_count = 1;
while(while_count++)
{
uint8_t Commands = 0;
if(RT_EOK == HX1838B_Get_Command(&Commands))
{
if(Commands == 0xA2)
{
rt_kprintf("按下【1】按键 !!\n");
}
}
/* 循环提示 */
if(while_count >= 500)
{
while_count = 1;
rt_kprintf("\nType [test_exit_infrared_receiving_module] command to exit \n");
rt_kprintf("Note: Pressing [TAB] as you type will autocomplete the command\n");
aicos_mdelay(2000);
}
aicos_mdelay(100);
}
}
static void test_infrared_receiving_module(int argc, char **argv)
{
int ret = HX1838B_Init();
if(ret != RT_EOK)
{
LOG_E("Failed to [HX1838B_Init] !!!");
return;
}
/* 创建线程,名称是 hx1838b_thread,入口是 hx1838b_thread_entry */
hx1838b_thread = rt_thread_create("hx1838b_thread",
hx1838b_thread_entry, RT_NULL,
THREAD_STACK_SIZE,
THREAD_PRIORITY, THREAD_TIMESLICE);
/* 如果获得线程控制块,启动这个线程 */
if (hx1838b_thread != RT_NULL)
rt_thread_startup(hx1838b_thread);
}
// 导出函数为命令
MSH_CMD_EXPORT(test_infrared_receiving_module, Infrared receiving module);
/* 退出函数 */
void test_exit_infrared_receiving_module(void)
{
int ret = rt_thread_delete(hx1838b_thread);
if(ret != RT_EOK)
{
LOG_E("failed to test_exit_infrared_receiving_module !!");
return;
}
ret = HX1838B_DeInit();
if(ret != RT_EOK)
{
LOG_E("Failed to [HX1838B_DeInit] !!!");
return;
}
else
{
rt_kprintf("\nHX1838B_DeInit successful!!!\n");
}
rt_kprintf("\n========hx1838b sensor exit successful !!========\n");
}
// 导出函数为命令
MSH_CMD_EXPORT(test_exit_infrared_receiving_module, exit Infrared receiving module);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
移植验证
我们使用串口调试,将 USB转TTL模块 连接到衡山派开发板上面!!
具体的教程查看:串口调试(点击跳转🚀)
串口波特率默认为
115200
我们在输入下面的命令运行该模块的线程:
输入的时候按下
TAB键
会进行命令补全!!
test_infrared_receiving_module
模块上电效果:
我们使用红外遥控板进行控制,向红外编解码模块发送数据!
按下按键【1】之后会有提示!!