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 debug
LED_turn();
#endif
rx_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实时更新接收数据包


更多推荐


所有评论(0)