一配置STM32CubeMx创建STM32工程首先勾选SYS里面的Debug选择Serial Wire否则下一次将无法烧录关闭SWD烧录接口。之后配置RCC时钟选择高速的外部晶振。首先在直接红框1内配置输入72点击回车之后选择OKSTM32CubeMx会自动帮你把时钟修改为72Mhz之后点击一个可以使用外部中断的引脚这里选择PA1作为外部中断触发引脚。按照下面图的形式去勾选PA1之后选择GPIO_EXIT之后进入GPIO里面配置PA1为外部中断下降沿触发。之后在旁边的NVIC中开启外部中断。按照下面配置生成信息Copy only the necessary library files 勾选该选项可以只生成需要的文件可以加快编译速度以及减少文件体积。勾选Generate peripheral initialization as a pair of.c/.h files per peripheral 可以去把每种文件都独立生成.C和.h文件点击Open Project可以直接打开Keil二实物连接红外遥控模装入纽扣电池接收头HX1838级连接3.3V电源、-级GND、信号线接入PA1外部中断。三编写HAL库代码代码以下是红外的NEC协议起始信号是一个下降沿所以我们可以通过外部中断下降沿捕获去获取起始信号通过延时函数去记录高电平时间完成信号的判断逻辑0和逻辑1前面560us低电平时间一致主要是高电平时间不同。起始信号的高电平时间也和他们不同。书写一个记录高电平时间的函数每次进入之后通过延时函数和t的数值判断高电平持续时间如果高电平时间远远大于正常时间说明错误。使用的us延时函数可以参考我的另一篇文章。STM32使用定时器完成精准的通用us延时函数-CSDN博客uint8_t Drv_Hw_RecordHightTime (void){uint8_t t 0;while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1)GPIO_PIN_SET) // 高电平{t ;delay_us(20);//以20us 为间隔记录高电平时间if(t 250){return t; // 超时溢出}}return t;}当下降沿来的时候会进入中断会进入中断回调函数在中断回调函数中卡住一直等到高电平时间出现开始判断高电平时间去区分起始信号逻辑和0逻辑1以及超时的意外信号。uint32_t hw_jsm; // 定义一个32位数据用于保存接收的红外键值extern uint8_t hw_jsbz;//用于记录红外的接收是否完成void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){uint8_t Tim 0,Ok 0,Data,Num 0;while(1){if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1)GPIO_PIN_SET){Tim Drv_Hw_RecordHightTime(); //获得此次高电平时间if(Tim250){break; // 不是有用的信号}if(Tim 200 Tim 250){Ok 1; // 收到起始信号}else if(Tim 60 Tim 90){Data 1; // 收到数据 1}else if(Tim 10 Tim 50){Data 0; // 收到数据 0}if(Ok 1){hw_jsm 1;hw_jsm Data;// 接收完成if(Num 32){hw_jsbz 1;break;}}Num ;}}}最后是去判断按键的键值可以通过串口打印或者通过Debug打断电去判断。每一个遥控器可能按键的键值不一样。uint8_t Med_Hw_ReadKeyValue (void){if(hw_jsm 0x00000081){return 1;}return 0;}在主函数While(1)里面调用判断按键的键值的函数此时我们以键值hw_jsm 0x00000081为例子这个返回1我们在主函数中调用。if (hw_jsbz 1)//已经成功接收到了正确的数据{gHwKeyValue Med_Hw_ReadKeyValue();//读取记录按键if (gHwKeyValue 1) // 按下按键“1”{// 点亮LEDHAL_Delay(1);//这里写个这个延时函数只是为了方便打断电看看是不是成功来了}hw_jsbz 0; // 清除接收完成标志位hw_jsm 0; // 清零接收码}四获取键值以及调试的办法首先连接好调试线点击Debug这俩位置打入断点将加入watch观察窗可以去看数值然后点击run开始调试可以根据这个数值修改前面函数Med_Hw_ReadKeyValue 里面的判断逻辑if(hw_jsm 0x00FFE21D)。参考的原文档如下基于STM32实现红外遥控的NEC协议解码程序设计-开发者社区-阿里云