两块开发板,一块接发送模块;一块接接收模块,实现一个开发板红外发送数据包控制另一个开发板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实时更新接收数据包 

 

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐