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

STM32CubeMX红外收发模块(串口)

两块开发板,一块接发送模块;一块接接收模块,实现一个开发板红外发送数据包控制另一个开发板LED的亮灭(数据包匹配)

一、红外发送模块

红外发送模块负责将电信号转换为红外光信号并发射出去。

红外发射管:940nm波长,辐射角度30°-60°,需串联限流电阻(常用100-200Ω)。

驱动电路:使用NPN三极管(如8050)或MOSFET(如2N7002)放大电流,由MCU的PWM引脚控制。

载波生成:通过STM32定时器输出38kHz PWM信号(占空比50%)。

二、红外接收模块

红外接收模块用于接收和解调红外信号,将其转换为电信号。

一体化接收头:如VS1838B(3引脚:VCC, GND, OUT),内置38kHz带通滤波和解调。

信号调理电路:OUT引脚接10kΩ上拉电阻,输出TTL电平信号至MCU串口接收RX引脚。

三、CubeMX配置

我使用的是stm32f030K6
RCC与SYS

波特率根据购买的来自己定 

PWM调制看有没有相应的引脚配置,没有可以不加

计算:48MHz/[(32-1)*(40-1)]=37.5KHz≈38KHz 

四、代码

UART.c
/** @Author: random* @Date: 2025-07-14 16:17:01* @Last Modified by: random* @Last Modified time: Do not Edit*/
// 串口封装函数
#include "UART.h"
#include "usart.h"
//#define debug
// 重定向函数,用于printf1
int fputc(int ch, FILE *f)
{HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);return ch;
}//=======================================================================接收===================================//
char rxdat[255+1]; // +1 用于字符串终止符
volatile uint8_t rx_count = 0;
uint8_t rxbuff;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if (huart->Instance == USART1){if (rx_count < 5){rxdat[rx_count++] = rxbuff;// 检查是否收到结束符if (rx_count == 4 && rxdat[0]== 0xAA && rxdat[3]== 0x55)//接收包头包尾,可自行修改{rxdat[rx_count] = '\0'; // 添加终止符
#ifdef debugLED_turn();
#endifrx_count = 0;}}else{// 缓冲区溢出处理rx_count = 0;memset(rxdat, 0, sizeof(rxdat));}HAL_UART_Receive_IT(&huart1, &rxbuff, 1);}
}//==========================================================================发送====================================//
#include "string.h"
#include "tim.h"// UART定义
#define IR_TX_UART         huart1  // 使用UART1的PA9引脚发送// 发送状态
volatile uint8_t ir_sending = 0;
static uint8_t uart_buffer[64];     // UART发送缓冲区/*** @brief 启动PWM输出*/
static void IR_PWM_On(void)
{HAL_TIMEx_PWMN_Start(&htim17, TIM_CHANNEL_1);
}/*** @brief 停止PWM输出*/
static void IR_PWM_Off(void)
{HAL_TIMEx_PWMN_Stop(&htim17, TIM_CHANNEL_1);
}/*** @brief 微秒级延时* @param us 延时微秒数*/
static void IR_Delay_us(uint32_t us) {uint32_t delay = us * 48 ; // 假设每次循环3周期while (delay--) {__NOP(); // 1周期}
}/*** @brief 通过UART1(PA9)发送红外数据* @param data 要发送的数据* @param length 数据长度*/
void IR_SendData_UART(uint8_t *data, uint16_t length)
{if (data == NULL || length == 0 || length > sizeof(uart_buffer))return;if (!ir_sending){ir_sending = 1;//        // 启动PWM载波IR_PWM_On();// 复制数据到缓冲区memcpy(uart_buffer, data, length);// 通过UART发送数据HAL_UART_Transmit_IT(&IR_TX_UART, uart_buffer, length);}
}/*** @brief 通过UART1发送NEC协议数据* @param address 设备地址* @param command 命令码*/
void IR_SendNEC_UART(uint8_t address, uint8_t command)//可自行修改匹配
{uint8_t data[4];// NEC协议: 地址  + 命令 + 命令反码 + 地址反码data[0] = address;data[1] = command;data[2] = ~command;data[3] = ~address;IR_SendData_UART(data, 4);
}/*** @brief UART发送完成回调函数* @param huart UART句柄*/
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{if (huart->Instance == USART1){// 关闭PWM载波IR_PWM_Off();ir_sending = 0;}
}
UART.h
/** @Author: random* @Date: 2025-07-14 16:17:15* @Last Modified by: random* @Last Modified time: Do not Edit*/
#ifndef _UART_H
#define _UART_H#include "main.h"
int fputc(int ch, FILE *f);//==============================
static void IR_PWM_On(void);
static void IR_PWM_Off(void);//==============================
void IR_SendData_UART(uint8_t *data, uint16_t length);
void IR_SendNEC_UART(uint8_t address, uint8_t command);
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);#endif
发送模块main.c
     //初始化HAL_UART_Receive_IT(&huart1, &rxbuff, 1);HAL_TIMEx_PWMN_Start(&htim17, TIM_CHANNEL_1);char t[4]={0x01,0x02,0x03,0x04}; uint8_t t_count = 0;while (1){IR_SendNEC_UART(0xAA,t[t_count++]);if(t_count == 4)t_count = 0;Delay_ms(1000);}
接收模块main.c
 while (1){if(rxdat[1] ==0x01)//灯灭{LED_OFF(LED_CHARG); //LED_OFF(LED_FREE); //LED_OFF(LED_LOAD); //}else if(rxdat[1] ==0x02)//蓝{LED_ON(LED_CHARG); //LED_OFF(LED_FREE); //LED_OFF(LED_LOAD); //}else if(rxdat[1] ==0x03)//红{LED_OFF(LED_CHARG); //LED_ON(LED_FREE); //LED_OFF(LED_LOAD); //}else if(rxdat[1] ==0x04)//绿{LED_OFF(LED_CHARG); //LED_OFF(LED_FREE); //LED_ON(LED_LOAD); //}else{LED_OFF(LED_CHARG); //LED_OFF(LED_FREE); //LED_OFF(LED_LOAD); //}

debug实时更新接收数据包 

 

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

相关文章:

  • H3CNE综合实验之五角星
  • 了解linux用户和权限
  • Linux开发利器:探秘开源,构建高效——基础开发工具指南(上)【包管理器/Vim】
  • springboot项目部署到K8S
  • Golang 并发快速上手
  • SingLoRA:单矩阵架构减半参数量,让大模型微调更稳定高效
  • ​HAProxy负载均衡集群概述
  • 逆向入门(39、40)程序逆向篇-DaNiEl-RJ.1、genocide1
  • 基于SSE传输的MCP服务器实现
  • LVS集群实践
  • 使用CodeQL挖掘Spring中的大量赋值漏洞
  • 行为模式-策略模式
  • 华大北斗TAU1201-1216A00高精度双频GNSS定位模块 自动驾驶专用
  • AWS IAM 最佳安全实践通用指南
  • 从 “洗澡难” 到 “洗得爽”:便携智能洗浴机如何重塑生活?
  • 微服务架构升级:从Dubbo到SpringCloud的技术演进
  • 浏览器自动化方案
  • 创客匠人解析:系统化工具如何重构知识变现效率
  • 在 kubernetes 上安装 jenkins
  • 闲庭信步使用图像验证平台加速FPGA的开发:第十九课——图像拉普拉斯金字塔的FPGA实现
  • Image 和 IMU 时间戳同步
  • 事务~~~
  • JavaScript进阶篇——第五章 对象成员管理与数组遍历优化
  • 密码喷洒复现
  • Thymeleaf 基础语法与标准表达式详解
  • 如何区分Bug是前端问题还是后端问题?
  • LeetCode经典题解:141、判断链表是否有环
  • 【LeetCode】链表相关算法题
  • Node.js Process Events 深入全面讲解
  • 1.3 vue响应式对象