639 lines
18 KiB
C
639 lines
18 KiB
C
/**
|
||
* @file ir_device.c
|
||
* @author your name (you@domain.com)
|
||
* @brief
|
||
* @version 0.1
|
||
* @date 2024-10-15
|
||
*
|
||
* @copyright Copyright (c) 2024
|
||
*
|
||
*/
|
||
#include "stdio.h"
|
||
#include "stdlib.h"
|
||
#include "string.h"
|
||
#include "ir_device.h"
|
||
|
||
/* 芯片头文件使能 如果使用了其他的芯片 把屏蔽掉*/
|
||
#define MCU_AI_WB2
|
||
|
||
#ifdef MCU_AI_WB2
|
||
#include "FreeRTOS.h"
|
||
#include "task.h"
|
||
#include "timers.h"
|
||
#include "ir_uart.h"
|
||
#include "blog.h"
|
||
#include <bl_gpio.h>
|
||
#include "easy_flash.h"
|
||
#define DBG_TAG "IR-DEVICE"
|
||
TimerHandle_t hxd_busy_timer;
|
||
TimerHandle_t hxd_power_off_timer;
|
||
bool hxd_power_off_timer_start = 0;
|
||
#endif
|
||
|
||
#define BUFFER_SIZE 2
|
||
#define POWER_OFF 1
|
||
#define POWER_ON 0
|
||
typedef struct
|
||
{
|
||
char buffer[BUFFER_SIZE];
|
||
int head;
|
||
int tail;
|
||
int count;
|
||
} CircularBuffer;
|
||
static CircularBuffer hxd_recv_buff;
|
||
|
||
unsigned char ac_codeGrud[2] = {0x03, 0xF8}; // 默认空调码组
|
||
static unsigned char hxd039b2_code_lren[] = {0x30, 0x70, 0xa0}; // 固定学习码
|
||
|
||
static void initBuffer(CircularBuffer *cb);
|
||
static bool isEmpty(CircularBuffer *cb);
|
||
static bool isFull(CircularBuffer *cb);
|
||
static bool enqueue(CircularBuffer *cb, unsigned char data);
|
||
static bool dequeue(CircularBuffer *cb, unsigned char *data);
|
||
static void printBuffer(CircularBuffer *cb);
|
||
static void hxd_039b2_delay_ms(uint32_t ms);
|
||
/**
|
||
* @brief hxd039b2 串口接收回调,把这函数放到MCU的串口接收中断中运行
|
||
*
|
||
* @param uart_data 单字节接收数据
|
||
*/
|
||
void hxd_039b_uart_recv_cb(unsigned char uart_data)
|
||
{
|
||
enqueue(&hxd_recv_buff, uart_data);
|
||
|
||
if (isFull(&hxd_recv_buff))
|
||
{
|
||
// printBuffer(&hxd_recv_buff);
|
||
dequeue(&hxd_recv_buff, &ac_codeGrud[0]);
|
||
dequeue(&hxd_recv_buff, &ac_codeGrud[1]);
|
||
if (ac_codeGrud[0] != 0XFF)
|
||
{
|
||
/* 读取成功之后,保存到flash*/
|
||
#ifdef MCU_AI_WB2
|
||
blog_info_hexdump("ir_acCode", ac_codeGrud, 2);
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* @brief 保存空调码组至,可以保存至flash 或者其他地址,以实现掉电保存
|
||
*
|
||
* @param ac_codeGrud
|
||
* @param size_len
|
||
*/
|
||
void hxd_039b2_save_ac_codeGrud(unsigned char *ac_codeGrud, int size_len)
|
||
{
|
||
#ifdef MCU_AI_WB2
|
||
flash_save_new_ac_gcode(ac_codeGrud, size_len);
|
||
#endif
|
||
}
|
||
/**
|
||
* @brief 读取
|
||
*
|
||
* @param ac_codeGrud
|
||
*/
|
||
int hxd_039b2_get_ac_codeGrud(unsigned char *ac_codeGrud)
|
||
{
|
||
int g_code_len = 0;
|
||
#ifdef MCU_AI_WB2
|
||
memset(ac_codeGrud, 0, 2);
|
||
g_code_len = flash_get_ac_gcode(ac_codeGrud);
|
||
#endif
|
||
return g_code_len;
|
||
}
|
||
/**
|
||
* @brief 发送给hxb_039b 的代码,应该把串口发送函数再次运行
|
||
*
|
||
* @param data
|
||
* @param data_len
|
||
*/
|
||
static void hxd_039b_send_data(unsigned char *data, int data_len)
|
||
{
|
||
// Ai-WB2的串口发送函数
|
||
if (data == NULL)
|
||
{
|
||
printf("data is NULL \r\n");
|
||
return;
|
||
}
|
||
int __hxd039b_busy = 0;
|
||
// 如果芯片处于忙碌状态,则直接退出,不做任何操作
|
||
__hxd039b_busy = bl_gpio_input_get_value(HXD039B2_BUSY_GPIO);
|
||
if (!__hxd039b_busy)
|
||
{
|
||
#ifdef MCU_AI_WB2
|
||
blog_error("hxd is busy don't send data");
|
||
#endif
|
||
return;
|
||
}
|
||
#ifdef MCU_AI_WB2
|
||
// bl_uart_datas_send(IR_UART_NUM, data, data_len);
|
||
uint16_t cnt = 0;
|
||
while (cnt < data_len)
|
||
{
|
||
bl_uart_data_send(IR_UART_NUM, data[cnt]);
|
||
cnt++;
|
||
}
|
||
#endif
|
||
/* 其他主控的串口发送函数*/
|
||
}
|
||
/**
|
||
* @brief 延迟函数,需要MCU的延时函数在此处调用
|
||
*
|
||
* @param ms
|
||
*/
|
||
static void hxd_039b2_delay_ms(uint32_t ms)
|
||
{
|
||
#ifdef MCU_AI_WB2
|
||
vTaskDelay(pdMS_TO_TICKS(ms));
|
||
#endif
|
||
}
|
||
/**
|
||
* @brief hxd_039b 开始匹配红外码,需要按匹配键,之后使用目标遥控器开关进行匹配
|
||
*
|
||
* @param code_groud 缓存红外码组,成功则缓存
|
||
* @return int
|
||
* 成功输出 红外码组,失败输出 -1。输出的码组为16位整数,需要自行分离2个8位的数据
|
||
*/
|
||
static int hxd_039b_find_code_groud(void)
|
||
{
|
||
// hxd_039b_send_data(hxd039b2_code_lren, 3);
|
||
uint16_t cnt = 0;
|
||
while (cnt < 3)
|
||
{
|
||
bl_uart_data_send(IR_UART_NUM, hxd039b2_code_lren[cnt]);
|
||
cnt++;
|
||
}
|
||
return 0;
|
||
}
|
||
/**
|
||
* @brief 长时间无操作,关闭HXD芯片电源,
|
||
*
|
||
* @param xTimer
|
||
*/
|
||
static void hxd_power_timers_cb(TimerHandle_t xTimer)
|
||
{
|
||
uint32_t ulCount;
|
||
configASSERT(xTimer);
|
||
ulCount = (uint32_t)pvTimerGetTimerID(xTimer);
|
||
/* 识别是否已经超过2s 没有操作?*/
|
||
if (ulCount >= 20)
|
||
{
|
||
/* 关闭HXD 电源并停止此定时器 */
|
||
#ifdef MCU_AI_WB2
|
||
blog_info("hxd039 power off");
|
||
bl_gpio_output_set(HXD039B2_POWER_CTRL_GPIO, POWER_OFF);
|
||
#endif
|
||
xTimerStop(xTimer, 0);
|
||
vTimerSetTimerID(xTimer, 0);
|
||
hxd_power_off_timer_start = false;
|
||
return;
|
||
}
|
||
ulCount++;
|
||
vTimerSetTimerID(xTimer, (void *)ulCount);
|
||
}
|
||
|
||
/**
|
||
* @brief 红外设备初始化
|
||
*
|
||
*/
|
||
void ir_dvice_init(void)
|
||
{
|
||
// 串口初始化接口
|
||
#ifdef MCU_AI_WB2
|
||
ir_uart_dvice_init(hxd_039b_uart_recv_cb);
|
||
|
||
bl_gpio_enable_output(HXD039B2_POWER_CTRL_GPIO, true, false); // 使能HXD039B2 控制IO
|
||
bl_gpio_output_set(HXD039B2_POWER_CTRL_GPIO, POWER_OFF); // 关闭HXD039B2的电源
|
||
// 初始化判忙IO
|
||
bl_gpio_enable_input(HXD039B2_BUSY_GPIO, true, false);
|
||
/* 读取flash 内部的空调码组 */
|
||
if (hxd_039b2_get_ac_codeGrud(ac_codeGrud) == 0)
|
||
{
|
||
/* 如果读不到,则设置默认值 */
|
||
if (ac_codeGrud[0] == 0 && ac_codeGrud[1] == 0)
|
||
{
|
||
ac_codeGrud[0] = 0x03;
|
||
ac_codeGrud[1] = 0xf8;
|
||
}
|
||
}
|
||
/* 创建电源关闭定时器,默认100ms 定时*/
|
||
hxd_power_off_timer = xTimerCreate("power off", pdMS_TO_TICKS(100), pdTRUE, (void *)0, hxd_power_timers_cb);
|
||
#endif
|
||
/*初始化缓冲器*/
|
||
initBuffer(&hxd_recv_buff);
|
||
}
|
||
#ifdef MCU_AI_WB2
|
||
/**
|
||
* @brief 软件定时器定时判忙
|
||
*
|
||
* @param xTimer
|
||
*/
|
||
static void vTimerCallback(TimerHandle_t xTimer)
|
||
{
|
||
// uint32_t ulCount;
|
||
configASSERT(xTimer);
|
||
int __hxd039b_busy = 0;
|
||
__hxd039b_busy = bl_gpio_input_get_value(HXD039B2_BUSY_GPIO);
|
||
// ulCount = (uint32_t)pvTimerGetTimerID(xTimer);
|
||
// blog_info("__hxd039b_busy=%d ulCont=%d", __hxd039b_busy, ulCount);
|
||
// 如果超时或者退出忙碌
|
||
if (__hxd039b_busy)
|
||
{
|
||
// 学习成功,关闭HXD039B电源
|
||
blog_info("Learn success,ac code 0x%02X 0x%02X", ac_codeGrud[0], ac_codeGrud[1]);
|
||
if (ac_codeGrud[0] == 0xff && ac_codeGrud[1] == 0xff)
|
||
{
|
||
// 如果返回的是0xffff 则重新进入学习状态
|
||
hxd_039b_find_code_groud();
|
||
__hxd039b_busy = 0;
|
||
return;
|
||
}
|
||
if (ac_codeGrud[0] == 0x88 && ac_codeGrud[1] == 0x99)
|
||
{
|
||
blog_error("Learn timerout");
|
||
goto __exit;
|
||
}
|
||
hxd_039b2_save_ac_codeGrud(ac_codeGrud, 2);
|
||
ac_codeGrud[0] = ac_codeGrud[1] = 0xff;
|
||
__exit:
|
||
bl_gpio_output_set(HXD039B2_POWER_CTRL_GPIO, POWER_OFF);
|
||
__hxd039b_busy = 0;
|
||
xTimerStop(xTimer, 0);
|
||
xTimerDelete(xTimer, 0);
|
||
return;
|
||
}
|
||
}
|
||
#endif
|
||
/**
|
||
* @brief 启动学习,运行此函数之后,对着红外接收头,按遥控器的开关键即可匹配红外码
|
||
*
|
||
*/
|
||
void ir_codec_start_learn(void)
|
||
{
|
||
#ifdef MCU_AI_WB2
|
||
// 开启HXD039B电源
|
||
uint16_t time_out_cont = 0;
|
||
bl_gpio_output_set(HXD039B2_POWER_CTRL_GPIO, POWER_ON);
|
||
hxd_busy_timer = xTimerCreate("busy timer", pdMS_TO_TICKS(200), pdTRUE, (void *)time_out_cont, vTimerCallback);
|
||
#endif
|
||
/* 延时时间,让HXD039B 进入工作状态*/
|
||
hxd_039b2_delay_ms(HXD_039B2_START_TIME_MS);
|
||
// 发送数据
|
||
hxd_039b_find_code_groud();
|
||
|
||
hxd_039b2_delay_ms(HXD_039B2_START_TIME_MS * 10);
|
||
// 启动定时器判断HXD是否忙碌
|
||
#ifdef MCU_AI_WB2
|
||
xTimerStart(hxd_busy_timer, 0);
|
||
#endif
|
||
}
|
||
/**
|
||
* @brief 发送电源控制指令
|
||
*
|
||
* @param power_state 1为打开,0为关闭
|
||
*/
|
||
void ir_codec_set_power(int power_state)
|
||
{
|
||
#ifdef MCU_AI_WB2
|
||
// 开启HXD039B电源
|
||
bl_gpio_output_set(HXD039B2_POWER_CTRL_GPIO, POWER_ON);
|
||
flash_get_ac_gcode(ac_codeGrud);
|
||
#endif
|
||
hxd_039b2_delay_ms(HXD_039B2_START_TIME_MS);
|
||
// 组织数据 例如打开空调: 0x30 0x06 0x03 0x03e 81
|
||
uint8_t ir_code[5] = {IR_CODE_BYTE_HANDLE, IR_CODE_BYTE_AC_TYPE, ac_codeGrud[0], ac_codeGrud[1], power_state ? IR_CODE_BYTE_AC_ON : IR_CODE_BYTE_AC_OFF};
|
||
hxd_039b_send_data(ir_code, 5);
|
||
// 延时等待发送完成后关闭HXD039B的电源
|
||
// hxd_039b2_delay_ms(HXD_039B2_START_TIME_MS*20);
|
||
#ifdef MCU_AI_WB2
|
||
// 关闭HXD039B的电源
|
||
blog_info_hexdump("uart_data", ir_code, 5);
|
||
/* 判断电源定时器是否正在运行 */
|
||
if (hxd_power_off_timer_start)
|
||
{
|
||
/* 如果正在运行,则重新设置ID数,让定时器重新进行2S的定时*/
|
||
vTimerSetTimerID(hxd_power_off_timer, 0);
|
||
}
|
||
else
|
||
{
|
||
/* 如果没在运行,则启动定时器 */
|
||
hxd_power_off_timer_start = true;
|
||
xTimerStart(hxd_power_off_timer, 0);
|
||
}
|
||
|
||
// bl_gpio_output_set(HXD039B2_POWER_CTRL_GPIO, POWER_OFF);
|
||
#endif
|
||
}
|
||
/**
|
||
* @brief 设置模式,发送0~4
|
||
*
|
||
* @param mode 0: 自动模式 1:制冷模式 2:除湿模式 3:送风模式 4: 制热模式
|
||
*/
|
||
void ir_codec_set_mode(int mode)
|
||
{
|
||
uint32_t ulCount = 0;
|
||
#ifdef MCU_AI_WB2
|
||
// 开启HXD039B电源
|
||
bl_gpio_output_set(HXD039B2_POWER_CTRL_GPIO, POWER_ON);
|
||
flash_get_ac_gcode(ac_codeGrud);
|
||
#endif
|
||
hxd_039b2_delay_ms(HXD_039B2_START_TIME_MS);
|
||
// 组织数据 例如打开空调: 0x30 0x06 0x03 0x03e 81
|
||
|
||
uint8_t ir_code[5] = {IR_CODE_BYTE_HANDLE, IR_CODE_BYTE_AC_TYPE, ac_codeGrud[0], ac_codeGrud[1], IR_CODE_BYTE_AC_MODE_AUTO + mode};
|
||
hxd_039b_send_data(ir_code, 5);
|
||
// 延时等待发送完成后关闭HXD039B的电源
|
||
// hxd_039b2_delay_ms(HXD_039B2_START_TIME_MS*20);
|
||
#ifdef MCU_AI_WB2
|
||
// 关闭HXD039B的电源
|
||
blog_info_hexdump("uart_data", ir_code, 5);
|
||
if (hxd_power_off_timer_start)
|
||
{
|
||
/* 如果正在运行,则重新设置ID数,让定时器重新进行2S的定时*/
|
||
vTimerSetTimerID(hxd_power_off_timer, 0);
|
||
}
|
||
else
|
||
{
|
||
/* 如果没在运行,则启动定时器 */
|
||
hxd_power_off_timer_start = true;
|
||
xTimerStart(hxd_power_off_timer, 0);
|
||
}
|
||
|
||
#endif
|
||
}
|
||
/**
|
||
* @brief 设置温度,
|
||
*
|
||
* @param temperature
|
||
*/
|
||
void ir_codec_set_temperature(unsigned char temperature)
|
||
{
|
||
uint32_t ulCount = 0;
|
||
#ifdef MCU_AI_WB2
|
||
// 开启HXD039B电源
|
||
bl_gpio_output_set(HXD039B2_POWER_CTRL_GPIO, POWER_ON);
|
||
flash_get_ac_gcode(ac_codeGrud);
|
||
#endif
|
||
hxd_039b2_delay_ms(HXD_039B2_START_TIME_MS);
|
||
// 组织数据 例如打开空调: 0x30 0x06 0x03 0x03e 81
|
||
uint8_t ir_code[5] = {IR_CODE_BYTE_HANDLE, IR_CODE_BYTE_AC_TYPE, ac_codeGrud[0], ac_codeGrud[1], (temperature - 16) + IR_CODE_BYTE_AC_TEMPERATURE_16};
|
||
hxd_039b_send_data(ir_code, 5);
|
||
// 延时等待发送完成后关闭HXD039B的电源
|
||
// hxd_039b2_delay_ms(HXD_039B2_START_TIME_MS*20);
|
||
#ifdef MCU_AI_WB2
|
||
// 关闭HXD039B的电源
|
||
blog_info_hexdump("uart_data", ir_code, 5);
|
||
if (hxd_power_off_timer_start)
|
||
{
|
||
/* 如果正在运行,则重新设置ID数,让定时器重新进行2S的定时*/
|
||
vTimerSetTimerID(hxd_power_off_timer, 0);
|
||
}
|
||
else
|
||
{
|
||
/* 如果没在运行,则启动定时器 */
|
||
hxd_power_off_timer_start = true;
|
||
xTimerStart(hxd_power_off_timer, 0);
|
||
}
|
||
|
||
#endif
|
||
}
|
||
/**
|
||
* @brief 设置风力大小
|
||
*
|
||
* @param fan_mode 0:低速风 1:中等风力 2:强风
|
||
*/
|
||
void ir_codec_set_fan_mode(unsigned char fan_mode)
|
||
{
|
||
#ifdef MCU_AI_WB2
|
||
// 开启HXD039B电源
|
||
bl_gpio_output_set(HXD039B2_POWER_CTRL_GPIO, POWER_ON);
|
||
flash_get_ac_gcode(ac_codeGrud);
|
||
#endif
|
||
hxd_039b2_delay_ms(HXD_039B2_START_TIME_MS);
|
||
// 组织数据 例如打开空调: 0x30 0x06 0x03 0x03e 81
|
||
uint8_t ir_code[5] = {IR_CODE_BYTE_HANDLE, IR_CODE_BYTE_AC_TYPE, ac_codeGrud[0], ac_codeGrud[1], fan_mode + IR_CODE_BYTE_AC_FAN_MODE_AUTO};
|
||
hxd_039b_send_data(ir_code, 5);
|
||
// 延时等待发送完成后关闭HXD039B的电源
|
||
// hxd_039b2_delay_ms(HXD_039B2_START_TIME_MS*20);
|
||
#ifdef MCU_AI_WB2
|
||
// 关闭HXD039B的电源
|
||
blog_info_hexdump("uart_data", ir_code, 5);
|
||
if (hxd_power_off_timer_start)
|
||
{
|
||
/* 如果正在运行,则重新设置ID数,让定时器重新进行2S的定时*/
|
||
vTimerSetTimerID(hxd_power_off_timer, 0);
|
||
}
|
||
else
|
||
{
|
||
/* 如果没在运行,则启动定时器 */
|
||
hxd_power_off_timer_start = true;
|
||
xTimerStart(hxd_power_off_timer, 0);
|
||
}
|
||
|
||
#endif
|
||
}
|
||
/**
|
||
* @brief 设置风向
|
||
*
|
||
* @param trend 0:向上 1:中间 2:向下
|
||
*/
|
||
void ir_codec_set_trend(unsigned char trend)
|
||
{
|
||
#ifdef MCU_AI_WB2
|
||
// 开启HXD039B电源
|
||
bl_gpio_output_set(HXD039B2_POWER_CTRL_GPIO, POWER_ON);
|
||
flash_get_ac_gcode(ac_codeGrud);
|
||
#endif
|
||
hxd_039b2_delay_ms(HXD_039B2_START_TIME_MS);
|
||
// 组织数据 例如打开空调: 0x30 0x06 0x03 0x03e 81
|
||
uint8_t ir_code[5] = {IR_CODE_BYTE_HANDLE, IR_CODE_BYTE_AC_TYPE, ac_codeGrud[0], ac_codeGrud[1], trend + IR_CODE_BYTE_AC_TREND_UP};
|
||
hxd_039b_send_data(ir_code, 5);
|
||
// 延时等待发送完成后关闭HXD039B的电源
|
||
// hxd_039b2_delay_ms(HXD_039B2_START_TIME_MS*20);
|
||
#ifdef MCU_AI_WB2
|
||
// 关闭HXD039B的电源
|
||
blog_info_hexdump("uart_data", ir_code, 5);
|
||
if (hxd_power_off_timer_start)
|
||
{
|
||
/* 如果正在运行,则重新设置ID数,让定时器重新进行2S的定时*/
|
||
vTimerSetTimerID(hxd_power_off_timer, 0);
|
||
}
|
||
else
|
||
{
|
||
/* 如果没在运行,则启动定时器 */
|
||
hxd_power_off_timer_start = true;
|
||
xTimerStart(hxd_power_off_timer, 0);
|
||
}
|
||
|
||
#endif
|
||
}
|
||
/**
|
||
* @brief 自动风向开关
|
||
*
|
||
* @param trend_auto 0:关闭 1:开启
|
||
*/
|
||
void ir_codec_set_trend_auto(unsigned char trend_auto)
|
||
{
|
||
#ifdef MCU_AI_WB2
|
||
// 开启HXD039B电源
|
||
bl_gpio_output_set(HXD039B2_POWER_CTRL_GPIO, POWER_ON);
|
||
flash_get_ac_gcode(ac_codeGrud);
|
||
#endif
|
||
hxd_039b2_delay_ms(HXD_039B2_START_TIME_MS);
|
||
// 组织数据 例如打开空调: 0x30 0x06 0x03 0x03e 81
|
||
uint8_t ir_code[5] = {IR_CODE_BYTE_HANDLE, IR_CODE_BYTE_AC_TYPE, ac_codeGrud[0], ac_codeGrud[1], trend_auto ? IR_CODE_BYTE_AC_TREND_AUTO_ON : IR_CODE_BYTE_AC_TREND_AUTO_OFF};
|
||
hxd_039b_send_data(ir_code, 5);
|
||
// 延时等待发送完成后关闭HXD039B的电源
|
||
// hxd_039b2_delay_ms(HXD_039B2_START_TIME_MS*20);
|
||
#ifdef MCU_AI_WB2
|
||
// 关闭HXD039B的电源
|
||
blog_info_hexdump("uart_data", ir_code, 5);
|
||
if (hxd_power_off_timer_start)
|
||
{
|
||
/* 如果正在运行,则重新设置ID数,让定时器重新进行2S的定时*/
|
||
vTimerSetTimerID(hxd_power_off_timer, 0);
|
||
}
|
||
else
|
||
{
|
||
/* 如果没在运行,则启动定时器 */
|
||
hxd_power_off_timer_start = true;
|
||
xTimerStart(hxd_power_off_timer, 0);
|
||
}
|
||
|
||
#endif
|
||
}
|
||
/**
|
||
* @brief 灯光开关
|
||
*
|
||
* @param light_power 0:关闭灯光 1:打开灯光
|
||
*/
|
||
void ir_codec_set_light_power(unsigned char light_power)
|
||
{
|
||
#ifdef MCU_AI_WB2
|
||
// 开启HXD039B电源
|
||
bl_gpio_output_set(HXD039B2_POWER_CTRL_GPIO, POWER_ON);
|
||
flash_get_ac_gcode(ac_codeGrud);
|
||
#endif
|
||
hxd_039b2_delay_ms(HXD_039B2_START_TIME_MS);
|
||
// 组织数据 例如打开空调: 0x30 0x06 0x03 0x03e 81
|
||
uint8_t ir_code[5] = {IR_CODE_BYTE_HANDLE, IR_CODE_BYTE_AC_TYPE, ac_codeGrud[0], ac_codeGrud[1], light_power ? IR_CODE_BYTE_AC_LIGHT_ON : IR_CODE_BYTE_AC_LIGHT_OFF};
|
||
hxd_039b_send_data(ir_code, 5);
|
||
// 延时等待发送完成后关闭HXD039B的电源
|
||
// hxd_039b2_delay_ms(HXD_039B2_START_TIME_MS*20);
|
||
#ifdef MCU_AI_WB2
|
||
// 关闭HXD039B的电源
|
||
blog_info_hexdump("uart_data", ir_code, 5);
|
||
if (hxd_power_off_timer_start)
|
||
{
|
||
/* 如果正在运行,则重新设置ID数,让定时器重新进行2S的定时*/
|
||
vTimerSetTimerID(hxd_power_off_timer, 0);
|
||
}
|
||
else
|
||
{
|
||
/* 如果没在运行,则启动定时器 */
|
||
hxd_power_off_timer_start = true;
|
||
xTimerStart(hxd_power_off_timer, 0);
|
||
}
|
||
|
||
#endif
|
||
}
|
||
/**
|
||
* @brief 以下是缓冲器程序
|
||
*
|
||
*/
|
||
|
||
/**
|
||
* @brief 初始化回环缓冲
|
||
*
|
||
* @param cb
|
||
* @return * void
|
||
*/
|
||
static void initBuffer(CircularBuffer *cb)
|
||
{
|
||
cb->head = 0;
|
||
cb->tail = 0;
|
||
cb->count = 0;
|
||
memset(cb->buffer, 0, BUFFER_SIZE);
|
||
}
|
||
/**
|
||
* @brief 判断 检查缓冲区是否为空
|
||
*
|
||
* @param cb 缓冲器枚举
|
||
* @return true 为空
|
||
* @return false 不为空
|
||
*/
|
||
static bool isEmpty(CircularBuffer *cb)
|
||
{
|
||
return cb->count == 0;
|
||
}
|
||
/**
|
||
* @brief 判断缓冲器是否已满?
|
||
*
|
||
* @param cb 缓冲器枚举
|
||
* @return true 已满
|
||
* @return false 没满
|
||
*/
|
||
static bool isFull(CircularBuffer *cb)
|
||
{
|
||
return cb->count == BUFFER_SIZE;
|
||
}
|
||
/**
|
||
* @brief 向缓冲区添加数据
|
||
*
|
||
* @param cb 缓冲器枚举
|
||
* @param data 数据
|
||
* @return true 添加成功
|
||
* @return false 添加失败
|
||
*/
|
||
static bool enqueue(CircularBuffer *cb, unsigned char data)
|
||
{
|
||
if (isFull(cb))
|
||
{
|
||
return false; // 缓冲区已满,添加失败
|
||
}
|
||
cb->buffer[cb->head] = data;
|
||
cb->head = (cb->head + 1) % BUFFER_SIZE;
|
||
cb->count++;
|
||
return true;
|
||
}
|
||
/**
|
||
* @brief 从缓冲器取数据
|
||
*
|
||
* @param cb 缓冲器枚举
|
||
* @param data 数据
|
||
* @return true 取出成功
|
||
* @return false 取出失败
|
||
*/
|
||
static bool dequeue(CircularBuffer *cb, unsigned char *data)
|
||
{
|
||
if (isEmpty(cb))
|
||
{
|
||
return false; // 缓冲区为空,取出失败
|
||
}
|
||
*data = cb->buffer[cb->tail];
|
||
cb->tail = (cb->tail + 1) % BUFFER_SIZE;
|
||
cb->count--;
|
||
return true;
|
||
}
|
||
/**
|
||
* @brief 打印缓冲区内容(用于调试)
|
||
*
|
||
* @param cb
|
||
* @return * void
|
||
*/
|
||
static void printBuffer(CircularBuffer *cb)
|
||
{
|
||
printf("Buffer: ");
|
||
for (int i = 0; i < BUFFER_SIZE; i++)
|
||
{
|
||
int index = (cb->tail + i) % BUFFER_SIZE;
|
||
if (index == cb->head && i < cb->count)
|
||
{
|
||
printf("|"); // 指示缓冲区头和尾之间的分隔
|
||
}
|
||
printf("0x%02X ", cb->buffer[index]);
|
||
}
|
||
printf("\r\n");
|
||
}
|
||
|