目录
- 基于stm32的红外发射实验HAL库编程(美的)
- 前言
- 实验目的
- 关于美的空调红外遥控器协议R05D
- 数据0格式
- 数据1格式
- 分隔码
- 完整时序图
- 关于实验原理图
- 搭建工程
- 编写代码实现需求
- 实验现象
- 本文中使用的测试工程
基于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’),我这里抓取了开机的对应的码值进行模拟,依据抓取到的码值进行模拟发射,借助逻辑分析仪工具一步调试,所以本次实验成功。