基于stm32的红外发射实验HAL库编程(美的)

基于stm32的红外发射实验HAL库编程(美的)

本文目标:基于stm32的红外发射实验HAL库编程(美的)

按照本文的描述,应该可以跑通实验并举一反三。

先决条件:装有编译和集成的开发环境,比如:Keil uVision5、STM32CubeMX

使用外设:USART1、GPIO、TIM2

前言

遥控器随处可见,是我们日常生活中常用的一种电子设备。它可以通过红外信号来控制电视、空调等家用电器的开关、模式、音量等功能。本文将介绍如何使用 STM32 单片机和 HAL 库来实现一个红外遥控器的发射实验,让你了解红外遥控的原理和编程方法。

实验目的

基于stm32的红外发射实验HAL库编程(美的),通过使用stm32的定时器功能,模拟学习到的码值进行发射。

关于美的空调红外遥控器协议R05D

美的空调红外遥控器采用R05D格式,载波频率为38KHZ。
数据格式:引导码+48位数据+分隔码+48位数据(LAA’BB’CC’ S LAA’BB’CC’)

L为引导码;
ABC为实际数据,A’为A的反码,B’为B的反码,C’为C的反码;
S为分隔码;
第二帧数据和第一帧一样;

L引导码:4.5ms低电平+4.5ms高电平(以解析方分析,编码方刚好相反,下面不再概述)

在这里插入图片描述

数据0格式

550us低+550us高就识别成数据0

在这里插入图片描述

数据1格式

550us低+1600us高就识别成数据0

在这里插入图片描述

分隔码

在这里插入图片描述

完整时序图

在这里插入图片描述

关于实验原理图

在这里插入图片描述

本次工程的目标是使用我现有的硬件实现一个红外发射达到控制空调的目的,目标了解,开工。

搭建工程

使用STM32CubeMX配置stm32的基本配置。基本的配置如下:开启swd调试,开启外部时钟。

在这里插入图片描述

在这里插入图片描述

  • 配置USART1,用于printf调试

在这里插入图片描述

  • 配置time1

    在这里插入图片描述

    在这里插入图片描述

  • 时钟界面选项卡:

在这里插入图片描述

  • 工程选项卡:

在这里插入图片描述

编写代码实现需求

我们的目标是使用定时器整出38khz的编码

开始编写代码,首先要把串口的打印映射好,使用下面的代码片段可用正常使用printf打印

int fputc( int ch, FILE *f )
{
	USART_TypeDef* USARTx = USART1;
	while ((USARTx->SR & (1<<7)) == 0);
	USARTx->DR = ch;
	return ch;
}

接下来编写一些代码片段如下:

/*
*********************************************************************************************************
*	函 数 名: Lead_Code
*	功能说明: 红外引导码发送  4.5ms高 + 4.5ms低
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/

void Lead_Code()
{
	bsp_SetTIMOutPWM(GPIOA, GPIO_PIN_8,  TIM1,  1, 38000, 5000);  // 高
	bsp_DelayUS(4500);
	bsp_SetTIMOutPWM(GPIOA, GPIO_PIN_8,  TIM1,  1, 0, 0); // 低
	bsp_DelayUS(4500);
}

/*
*********************************************************************************************************
*	函 数 名: Stop_Code
*	功能说明: 红外分割码发送  540us高 + 5250us低
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
void Stop_Code()
{
	bsp_SetTIMOutPWM(GPIOA, GPIO_PIN_8,  TIM1,  1, 38000, 5000); // 高
	bsp_DelayUS(540);
	bsp_SetTIMOutPWM(GPIOA, GPIO_PIN_8,  TIM1,  1, 0, 0);     // 低
	bsp_DelayUS(5250);
}

/*
*********************************************************************************************************
*	函 数 名: Send_0_Code
*	功能说明: 红外码值0发送  540us高 + 540us低
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
void Send_0_Code()
{
	bsp_SetTIMOutPWM(GPIOA, GPIO_PIN_8,  TIM1,  1, 38000, 5000); // 高
	bsp_DelayUS(540);
	bsp_SetTIMOutPWM(GPIOA, GPIO_PIN_8,  TIM1,  1, 0, 0);     // 低
	bsp_DelayUS(540);
}

/*
*********************************************************************************************************
*	函 数 名: Send_0_Code
*	功能说明: 红外码值0发送  540us高 + 1600us低
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
void Send_1_Code()
{
	bsp_SetTIMOutPWM(GPIOA, GPIO_PIN_8,  TIM1,  1, 38000, 5000); // 高
	bsp_DelayUS(490);
	bsp_SetTIMOutPWM(GPIOA, GPIO_PIN_8,  TIM1,  1, 0, 0);     // 低
	bsp_DelayUS(1600);
}

/*
*********************************************************************************************************
*	函 数 名: Send_Byte
*	功能说明: 发送一个字节
*	形    参: data 发送的字节数
*	返 回 值: 无
*********************************************************************************************************
*/
void Send_Byte(uint8_t data)
{
	int i;
	for(i=7;i>=0;i--)
	{
		if(data & (1<<i))
		{
			Send_1_Code();
		}
		else
		{
			Send_0_Code();
		}
	}
}

/*
*********************************************************************************************************
*	函 数 名: Normal_Code
*	功能说明: 发送对应的码值
*	形    参: A、B、C对应的码值
*	返 回 值: 无
*********************************************************************************************************
*/
void Normal_Code(uint8_t A, uint8_t B, uint8_t C)
{
	Lead_Code();
	Send_Byte(A);
	Send_Byte(~A);
	Send_Byte(B);
	Send_Byte(~B);
	Send_Byte(C);
	Send_Byte(~C);
	Stop_Code();
	Lead_Code();
	Send_Byte(A);
	Send_Byte(~A);
	Send_Byte(B);
	Send_Byte(~B);
	Send_Byte(C);
	Send_Byte(~C);
	Stop_Code();
}


在main函数中简单进行测试一下

/* 按键滤波和检测由后台systick中断服务程序实现,我们只需要调用bsp_GetKey读取键值即可。 */
ucKeyCode = bsp_GetKey();	/* 读取键值, 无键按下时返回 KEY_NONE = 0 */
if (ucKeyCode != KEY_NONE)
{
    switch (ucKeyCode)
    {
        case KEY_DOWN_K1:			/* K1键按下,PA8输出38KHz方波,占空比50% */
            Normal_Code(0xB2,0xBF,0xD0);
            Lead_Code();
            Send_Byte(0Xd5);
            Send_Byte(0x66);
            Send_Byte(0x00);
            Send_Byte(0x00);
            Send_Byte(0x00);
            Send_Byte(0x3b);
            Stop_Code();
            //					bsp_SetTIMOutPWM(GPIOA, GPIO_PIN_8,  TIM1,  1, 38000, 5000);
            break;

        case KEY_DOWN_K2:			/* K2键按下,PB9输出10KHz方波,占空比50% */
            //					bsp_SetTIMOutPWM(GPIOB, GPIO_PIN_9,  TIM4,  4, 10000, 5000);
            break;

        case KEY_DOWN_K3:			/* K3键按下,PB9输出100KHz方波,占空比50% */
            bsp_SetTIMOutPWM(GPIOB, GPIO_PIN_9,  TIM4,  4, 100000, 5000);		
            break;

        default:
            /* 其它的键值不处理 */
            break;
    }
}

main.c中的编写的代码片段

在这里插入图片描述

接下来简单的对工程配置一下

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

烧入代码,观察实验现象。

实验现象

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

这里当按下对应的遥控器按键时,使用手机的中的照相功能,可以观察到对应的有红外的波形,同时我这里的空调也有正常的相应,根据对应的数据格式:引导码+48位数据+分隔码+48位数据(LAA’BB’CC’ S LAA’BB’CC’),我这里抓取了开机的对应的码值进行模拟,依据抓取到的码值进行模拟发射,借助逻辑分析仪工具一步调试,所以本次实验成功。

参考资料: https://www.bilibili.com/video/B … 67518978e88addf1f65

本文中使用的测试工程

https://download.csdn.net/download/weixin_44317448/88351106

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
以下是STM32 HAL库UART中断形式发送的示例代码: ``` #include "stm32f4xx_hal.h" /* UART_HandleTypeDef结构体定义 */ UART_HandleTypeDef huart2; /* 用于存储UART接收数据的缓冲区 */ uint8_t rxBuffer[10]; /* 定义要发送的数据 */ uint8_t txData[] = "Hello, world!\r\n"; int main(void) { /* 初始化HAL库 */ HAL_Init(); /* 初始化UART2 */ __HAL_RCC_USART2_CLK_ENABLE(); huart2.Instance = USART2; huart2.Init.BaudRate = 9600; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart2); /* 开启UART2接收中断 */ HAL_UART_Receive_IT(&huart2, rxBuffer, 10); while (1) { /* 发送数据 */ HAL_UART_Transmit_IT(&huart2, txData, sizeof(txData)); /* 等待发送完成 */ while (huart2.gState != HAL_UART_STATE_READY) {} /* 延时 */ HAL_Delay(1000); } } /* UART接收中断处理函数 */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { /* 处理接收到的数据 */ /* ... */ /* 继续开启接收中断 */ HAL_UART_Receive_IT(&huart2, rxBuffer, 10); } /* UART发送中断处理函数 */ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { /* 发送完成 */ } ``` 在上述代码中,使用`HAL_UART_Init`函数初始化UART2,然后使用`HAL_UART_Receive_IT`函数开启UART2接收中断,并指定接收缓冲区和缓冲区长度。 在主循环中,使用`HAL_UART_Transmit_IT`函数发送数据,并在发送完成后等待,直到UART处于就绪状态。 当接收到数据时,将调用`HAL_UART_RxCpltCallback`函数,以处理接收到的数据,并使用`HAL_UART_Receive_IT`函数继续开启接收中断。 当发送完成时,将调用`HAL_UART_TxCpltCallback`函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独处东汉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值