当前位置: 首页 > news >正文

GD32入门到实战22--红外NEC通信协议

ir_drv.c

红外传输协议地位在前,所以我们可以这样保存数据到数组

假使接收到1就>>1再|0x80,如果接收到0就>>1

新建红外驱动层代码ir_drv.c

#include <stdio.h>  
#include "gd32f30x.h"
#include <stdbool.h>  static void GpioInit(void) 
{rcu_periph_clock_enable(RCU_GPIOC);gpio_init(GPIOC,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_10MHZ,GPIO_PIN_6);
}static void TimerInit()
{timer_parameter_struct timerInitPara;timer_struct_para_init(&timerInitPara);//给定时器结构体赋初值/*使能定时器时钟*/rcu_periph_clock_enable(RCU_TIMER7);/*复位定时器*/timer_deinit(TIMER7);/*设置预分频值*/timerInitPara.prescaler = 120 - 1;//时钟频率为1Mhz,周期为1us/*设置自动重装载值*/timerInitPara.period = 65535;/*初始化定时器*/timer_init(TIMER7,&timerInitPara);//给定时器结构体赋初值timer_ic_parameter_struct icInitPara;timer_channel_input_struct_para_init(&icInitPara);/*设置上升沿/下降沿捕获*/icInitPara.icpolarity = TIMER_IC_POLARITY_FALLING;/*设置输入通道*/icInitPara.icselection = TIMER_IC_SELECTION_DIRECTTI;timer_input_capture_config(TIMER7,TIMER_CH_0,&icInitPara);/*使能定时器的捕获中断*/timer_interrupt_flag_clear(TIMER7 ,TIMER_INT_FLAG_CH0);//清除中断标志位timer_interrupt_enable(TIMER7,TIMER_INT_CH0);/*使能定时器中断优先级*/nvic_irq_enable(TIMER7_Channel_IRQn, 0, 0);/*使能定时器*/timer_enable(TIMER7);
}#define TICK_HEAD_MAX   20000//引导码的最长时间
#define TICK_HEAD_MIN   10000//引导码的最短时间
#define TICK_0_MAX      1800//0的最长时间
#define TICK_0_MIN      500 //0的最短时间
#define TICK_1_MAX      3000//1的最长时间
#define TICK_1_MIN      1800//1的最短时间
static uint8_t g_irCode[4]; //存放数组
static bool g_irCodeFlag = false; //解析到完整的数据
static void ParseIrFrame(uint32_t tickNum)
{static bool s_headFlag = false;//表示是否收到static uint8_t s_index = 0;//数组索引值if(tickNum > TICK_HEAD_MIN && tickNum < TICK_HEAD_MAX)//引导码时间是否正常{//正常s_headFlag = true;return;}if(!s_headFlag)//如果引导码不正常{//说明没有解析到引导码return;}if(tickNum > TICK_1_MIN && tickNum < TICK_1_MAX)//1{//s_index / 8:s_index为8位数据,整个数据长为32位,//s_index0-7存到g_irCode[0];s_index8-15存到g_irCode[1]....g_irCode[s_index / 8] >>= 1;g_irCode[s_index / 8] |= 0x80;s_index++;}if(tickNum > TICK_0_MIN && tickNum < TICK_0_MAX)//0{g_irCode[s_index / 8] >>= 1;s_index++;}if(s_index == 32){   //if(g_irCode[2] == (uint8_t)~g_irCode[3])//校验数据反码,两种方法一样if((g_irCode[2] & g_irCode[3]) == 0)//按位与{//如果相等g_irCodeFlag = true;}else{g_irCodeFlag = false;}            s_headFlag = false;//清除接收到标志s_index = 0;//数组索引清零}
}/**
***********************************************************
* @brief 获取红外码值
* @param  code,输出,按键码值
* @return 返回是否成功获取按键码值
***********************************************************
*///*code:
bool GetIrCode(uint8_t *code)
{if(!g_irCodeFlag)//如果没有解析到完整数据{return false;}*code = g_irCode[2];//把数据取到指向的地址g_irCodeFlag = false;//把解析完成标志位清零return true;
}void TIMER7_Channel_IRQHandler()
{   static uint32_t icValue;//1 = 1usif(timer_interrupt_flag_get(TIMER7 , TIMER_INT_FLAG_CH0) == SET)//判断是否产生中断{timer_interrupt_flag_clear(TIMER7 , TIMER_INT_FLAG_CH0);//清除中断标志位icValue = timer_channel_capture_value_register_read(TIMER7, TIMER_CH_0) + 1;//读取计数值timer_counter_value_config(TIMER7 , 0);//计数器清零ParseIrFrame(icValue);}
}/**
***********************************************************
* @brief 红外接收硬件初始化函数
* @param 
* @return 
***********************************************************
*/
void IrDrvInit()
{GpioInit();TimerInit();
}

ir_drv.h

#ifndef _IR_DRV_H_
#define _IR_DRV_H_#include <stdint.h>
#include <stdbool.h>#define KEY1_CODE   0X45
#define KEY2_CODE   0X46/**
***********************************************************
* @brief 红外接收硬件初始化函数
* @param 
* @return 
***********************************************************
*/
void IrDrvInit(void);/**
***********************************************************
* @brief 获取遥控按键码值
* @param code,输出,按键码值
* @return 返回是否成功获取到按键码值
***********************************************************
*/
bool GetIrCode(uint8_t *code);#endif

hmi_app.c

#include <stdint.h>
#include "led_drv.h"
#include "ir_drv.h"
#include <stdio.h>
/**
***********************************************************
* @brief 人机交互任务处理函数
* @param 
* @return 
***********************************************************
*/
void HmiTask(void)
{uint8_t keyVal;if(!GetIrCode(&keyVal))//如果没有获取到码值{return;}printf("ir keyVal is 0x%x.\n",keyVal);switch (keyVal){case KEY1_CODE:TurnOnLed(LED1);break;case KEY2_CODE:TurnOffLed(LED1);break;default:break;}
}

main.c

#include <stdint.h>
#include <stdio.h>
#include "led_drv.h"
#include "key_drv.h"
#include "systick.h"
#include "usart_drv.h"
#include "delay.h"
#include "usb2com_app.h"
#include "hmi_app.h"
#include "ir_drv.h"typedef struct
{uint8_t run;                // 调度标志,1:调度,0:挂起uint16_t timCount;          // 时间片计数值uint16_t timRload;          // 时间片重载值void (*pTaskFuncCb)(void);  // 函数指针变量,用来保存业务功能模块函数地址
} TaskComps_t;/*任务调度结构体*/static TaskComps_t g_taskComps[] =  /*任务调度结构体数组,存放各个业务功能模块调度参数*/
{/*填入各个业务功能模块*/{0, 5,   5,   HmiTask},{0, 200, 200, usartTask},/* 添加业务功能模块 */
};#define TASK_NUM_MAX   (sizeof(g_taskComps) / sizeof(g_taskComps[0]))
/*用宏定义计算结构体数组的个数*///sizeof(g_taskComps):计算整个数组 g_taskComps 的大小(以字节为单位)。
//sizeof(g_taskComps[0]):计算数组中单个元素的大小(以字节为单位)。
//通过整个数组的大小除以单个元素的大小,得到数组中元素的数量/*
******************************************
* @brief 任务调度函数(判断所有业务模块的标志位)
* @param 
* @return
********************************************
*/
static void TaskHandler(void)
{for (uint8_t i = 0; i < TASK_NUM_MAX; i++){if (g_taskComps[i].run)                  // 判断时间片标志{g_taskComps[i].run = 0;              // 标志清零g_taskComps[i].pTaskFuncCb();        // 执行调度业务功能模块}}
}/*
******************************************
* @brief 时间片递减函数 1ms-1时间片
* @param 
* @return
********************************************
*/
static void TaskScheduleCb(void)
{for (uint8_t i = 0; i < TASK_NUM_MAX; i++){if (g_taskComps[i].timCount){g_taskComps[i].timCount--;if (g_taskComps[i].timCount == 0){g_taskComps[i].run = 1;g_taskComps[i].timCount = g_taskComps[i].timRload;}}}
}static void DrvInit(void)
{SystickInit();LedDrvInit();DelayInit();UsartDrv_Init();IrDrvInit();
}
static void AppInit(void)
{TaskScheduleCbReg(TaskScheduleCb);
}int main(void)
{	DrvInit();AppInit();while (1){TaskHandler();}
}

http://www.dtcms.com/a/358526.html

相关文章:

  • node.js ---文件读写(FS模块)
  • shell脚本第五阶段---shell函数与正则表达式
  • 机器学习时间序列算法进行随机划分数据是不合适的!
  • 一键掌控三线资源:极简 Shell 脚本实现 CPU·磁盘·内存可视化巡检
  • 鸿蒙ArkTS 核心篇-14-条件表达式(三目运算符)
  • ans1语法的一个例子nt5inf.cat
  • openEuler2403安装部署PostgreSQL17
  • 开发中使用——鸿蒙CoreSpeechKit让文字发声
  • 118、【OS】【Nuttx】【周边】效果呈现方案解析:作用域?
  • python pyqt5开发DoIP上位机【源码】
  • Spring代理的特点
  • Photoshop - Ps Camera Raw 滤镜
  • 【Python+requests】解决Python requests中的ProxyError:SSL版本错误问题详解
  • C++中的临时对象与移动语义——深入理解与实践
  • 消费 $83,用Claude 实现临床护理系统记录单(所见即所得版)
  • 拦截器Intercepter
  • 基于单片机智能垃圾桶/垃圾分类/语音垃圾桶
  • Spring MVC 参数绑定的默认行为解析
  • MySQL错误1449: The user specified as a definer (‘root‘@‘%‘) does not exist
  • MIT 6.5840 (Spring, 2024) 通关指南——Lab 1: MapReduce
  • JC系列串口通信说明
  • day45-Ansible流程控制
  • 同步/异步日志库
  • 佳易王钟表维修养护管理系统:开启钟表维修高效管理新篇章​就#软件操作教程
  • Compare With Java And Python
  • springboot 实现不同接口指定上传文件大小
  • Linux 定时器:工作原理与实现机制深入分析
  • AI公司是怎样对权重和损失函数做处理的?
  • Oracle下载安装(学习版)
  • 向华为学习——解读73页业务迁移基本流程设计与华为迁移方案【附全文阅读】