#include "mw_ir_controller.h" #include "bsp_usart.h" #include "string.h" #include "public_diy.h" #define IR_CONTROLLER_FRAME_HEAD_1 (0x00) #define IR_CONTROLLER_FRAME_HEAD_2 (0xFF) #define IR_CONTROLLER_FRAME_UP (0x18) // ↑ #define IR_CONTROLLER_FRAME_DOWN (0x52) // ↓ #define IR_CONTROLLER_FRAME_LEFT (0x08) // ← #define IR_CONTROLLER_FRAME_RIGHT (0x5A) // → #define IR_CONTROLLER_FRAME_OK (0x1C) // OK #define IR_DECODE_QUEUE_LEN (20u) typedef struct { uint8_t read; uint8_t write; uint8_t count; IR_DECODE_ENUM ir_decode_queue[IR_DECODE_QUEUE_LEN]; }IR_DECODE_STR; static IR_DECODE_STR str_ir_decode; /************************************************************************************* * @brief 解码 * @param[in/out] val 【参数注释】 * @return IR_DECODE_ENUM【返回值注释】 * * @warning 【不可重入,阻塞等警告】 * @note 【重大修改】 *************************************************************************************/ IR_DECODE_ENUM mw_IrController_decode(uint8_t val) { IR_DECODE_ENUM e_retVal; switch(val) { case IR_CONTROLLER_FRAME_UP: e_retVal = ir_decode_up; break; case IR_CONTROLLER_FRAME_DOWN: e_retVal = ir_decode_down; break; case IR_CONTROLLER_FRAME_LEFT: e_retVal = ir_decode_left; break; case IR_CONTROLLER_FRAME_RIGHT: e_retVal = ir_decode_right; break; case IR_CONTROLLER_FRAME_OK: e_retVal = ir_decode_ok; break; default: e_retVal = ir_decode_NUM; break; } return e_retVal; } /************************************************************************************* * @brief 红外模块 中间件 初始化 * * @warning 【不可重入,阻塞等警告】 * @note 【重大修改】 *************************************************************************************/ void mw_InitIrController(void) { memset((uint8_t *)&str_ir_decode, 0x00, sizeof(str_ir_decode)); } uint8_t mw_GetIrControllerChar(IR_DECODE_ENUM * eptr_val) { if(str_ir_decode.count > 0) { // 取值 * eptr_val = str_ir_decode.ir_decode_queue[str_ir_decode.read]; // 更新 if(++str_ir_decode.read >= IR_DECODE_QUEUE_LEN) { str_ir_decode.read = 0; } str_ir_decode.count--; return RET_OK; } else { return RET_ERROR; } } /************************************************************************************* * @brief 红外模块接收函数 * * @warning 【不可重入,阻塞等警告】 * @note 【重大修改】 *************************************************************************************/ void mw_IrReceiveProcess(void) { static uint8_t tmp_recv_state = 0; uint8_t recv_val; IR_DECODE_ENUM e_recv_ir_decode; switch(tmp_recv_state) { // Idle case 0: if(bsp_usart_IsComRecvChar(COM_IR_CONTROLLER) > 0) { tmp_recv_state = 1; } break; // 接收第一个字符 若帧头1 对了则进入下一阶段,否则回到最初的阶段 case 1: if(bsp_usart_GetComChar(COM_IR_CONTROLLER, &recv_val) == RET_OK) { if(recv_val == IR_CONTROLLER_FRAME_HEAD_1) { tmp_recv_state = 2; } else { tmp_recv_state = 0; } } break; case 2: // 接收第二个字符 若帧头2 对了则进入下一阶段,否则回到最初的阶段 if(bsp_usart_GetComChar(COM_IR_CONTROLLER, &recv_val) == RET_OK) { if(recv_val == IR_CONTROLLER_FRAME_HEAD_2) { tmp_recv_state = 3; } else { tmp_recv_state = 0; } } break; case 3: // 判断用户码,修改遥控器状态 if(bsp_usart_GetComChar(COM_IR_CONTROLLER, &recv_val) == RET_OK) { // 转化为解码后的数据 e_recv_ir_decode = mw_IrController_decode(recv_val); // 存进队列并更新 str_ir_decode.ir_decode_queue[str_ir_decode.write] = e_recv_ir_decode; ++str_ir_decode.count; if(++str_ir_decode.write >= IR_DECODE_QUEUE_LEN) { str_ir_decode.write = 0; } // 回到最初的阶段 tmp_recv_state = 0; } break; default: break; } }