STM32入门开发 制作红外线遥控器(智能居家-万能遥控器)

举报
DS小龙哥 发表于 2022/08/04 10:06:15 2022/08/04
【摘要】 红外线协议有很多,本章节主要是针对NEC协议讲解,只要把NEC协议原理搞懂了,其他协议都是一样的使用;如果想要模拟空调遥控器,去控制美的空调、格力空调这些设备,就需要按照美的、格力空调的协议发送;如果不知道协议长什么样,可以将逻辑分析仪插在红外线接收头的引脚上,拿个正常的空调遥控器对着接收头按一下,然后采集数据分析,即可得到协议规律,然后网络上也有空调按键值功能的说明文档,调试一下即可。

一、环境介绍

MCU: STM32F103ZET6

编程软件环境: keil5

红外线传输协议: NEC协议—38KHZ载波:。NEC协议是红外遥控协议中常见的一种。

编码发送思路: 延时函数模拟38KHZ + PWM产生38KHZ两种方式

代码风格: 模块化编程,寄存器直接操作方式

二、NEC协议与相关硬件介绍

2.1 NEC协议介绍

红外线协议有很多,本章节主要是针对NEC协议讲解,只要把NEC协议原理搞懂了,其他协议都是一样的使用;如果想要模拟空调遥控器,去控制美的空调、格力空调这些设备,就需要按照美的、格力空调的协议发送;如果不知道协议长什么样,可以将逻辑分析仪插在红外线接收头的引脚上,拿个正常的空调遥控器对着接收头按一下,然后采集数据分析,即可得到协议规律,然后网络上也有空调按键值功能的说明文档,调试一下即可。

2. 2 使用的相关硬件

因为要模拟红外线遥控器,就需要一个红外线发射管;在学习阶段,如果不想自己搭建电路,可以买现成的模块。 买模块连接也是比较稳定,接线也比较简单,VCC和GND接好之后,把DAT引脚接到STM32任意一个IO口上即可,如果想用硬件PWM控制发送,那么引脚接到STM32的PWM输出脚即可。

img

2.3 完成NEC协议编码发送

先看一段红外线接收头引脚上采集的NEC协议的电平: 这是接收端采集的。

img

红外线接收头的硬件特性: (注意: 这里是针对NEC遥控器协议来说明),下图就是当前使用的红外线接收头。

img

收到38KHZ的红外光,IN引脚就输出低电平;没有收到IN引脚就输出高电平。

NEC红外线协议说明:(这是站在接收端解码的角度分析的)

一段独立的NEC协议数据包由引导码+32位数据组成。

引导码: 9ms的高电平 + 4.5ms 低电平组成。

32位数据就是: 8位用户码+ 8位用户反码+ 8位按键码+8位按键反码

每个数据位之间的间隔时间是0.56ms(低电平)

NEC协议是依靠收到的高电平持续时间来判断数据0和数据1;高电平持续时间是0.56ms表示数据0,高电平持续时间是1.68ms表示数据1。

只要明白上面说的两个特点,就可以写程序,按照NEC协议驱动红外线发射管,发送数据了。

编写发送程序之前,得先明白这个38KHZ的红外光如何产生?

STM32支持硬件PWM功能,可以配置38KHZ方波输出;如果没有硬件PWM功能的单片机,也可以使用延时的方式产生38KHZ方波,差那么一点点问题也不到,解码端适当调整一下时间范围即可。

采用延时函数实现方法如下:

/*
函数功能: 发送38KHZ的载波
函数参数:
u32 time_us 持续的时间
u8 flag 1表示发送38KHZ载波,0表示不发送
*/
void InfraredSend38KHZ(u32 time_us,u8 flag)
{
    u32 i;
    if(flag)
    {
        //发送38KHZ载波
        for(i=0;i<time_us/13;i++)
        {
            INFRARED_OUTPUT=!INFRARED_OUTPUT;
            DelayUs(13);
        }
    }
    else
    {
        INFRARED_OUTPUT=1;//关闭红外线发射管
        DelayUs(time_us);
    }
}

为了方便发送指定的用户码和按键码,可以封装成一个函数调用。

/*
函数功能: NEC协议编码发送
函数参数: 
				u8 user 用户码
				u8 key  按键码
先发低位
按键反码+按键码+用户反码+用户码
*/
void InfraredNECSend(u8 user,u8 key)
{
	u32 i;
	 /*1. 组合发送的数据*/
	u32 data=((~key&0xFF)<<24)|((key&0xFF)<<16)|((~user&0xFF)<<8)|((user&0xFF)<<0);
		
	 /*2. 发送引导码*/
	InfraredSend38KHZ(9000,1);//发送38KHZ载波
	InfraredSend38KHZ(4500,0);//不发送
	
	/*3. 发送32位数据*/
	 for(i=0;i<32;i++)
	 {
			InfraredSend38KHZ(560,1); //间隔时间
			if(data&0x01)InfraredSend38KHZ(1685,0); //发送1
			else InfraredSend38KHZ(560,0); //发送0
		  data>>=1;
	 }
	 InfraredSend38KHZ(560,1); //间隔时间
}

这是使用逻辑分析仪采集的发送端波形: 和协议对应了一下,没有问题。

img

对比一下解码端采集的波形图:

img

三、核心代码

3.1 main.c


因为文章篇幅限制,不能贴出全部代码,字数超限。
需要其他部分的代码可以去这里下载:https://download.csdn.net/download/xiaolong1126626497/19863305


#include "stm32f10x.h"
#include "beep.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include <string.h>
#include <stdio.h>
#include "exti.h"
#include "timer.h"
#include "rtc.h"
#include "adc.h"
#include "ds18b20.h"
#include "ble.h"
#include "esp8266.h"
#include "wdg.h"
#include "oled.h"
#include "rfid_rc522.h"
#include "infrared.h"

int main()
{   
  LED_Init();
  KEY_Init();
  BEEP_Init();
  TIM1_Init(72,20000); //辅助串口1接收,超时时间为20ms
	USART_X_Init(USART1,72,115200);
	//InfraredDecodeInit(); //红外线解码初始化
	InfraredCodingInit();   //红外线编码初始化
  printf("UART1 OK.....\n");
	
  while(1)
  {
		InfraredNECSend(13,14); //发送红外线数据
		DelayMs(500);
		LED0=!LED0;
  }
}

3.2 红外线.c

#include "infrared.h"

/*
函数功能: 红外线编码初始化
硬件连接: PG11
编码思路: 采用延时函数实现38KHZ
*/
void InfraredCodingInit(void)
{
	  RCC->APB2ENR|=1<<8; //PG
	  GPIOG->CRH&=0xFFFF0FFF;
	  GPIOG->CRH|=0x00003000;
	  GPIOG->ODR|=1<<11;
}

/*
函数功能: 发送38KHZ的载波
函数参数:
u32 time_us 持续的时间
u8 flag 1表示发送38KHZ载波,0表示不发送
*/
void InfraredSend38KHZ(u32 time_us,u8 flag)
{
    u32 i;
    if(flag)
    {
        //发送38KHZ载波
        for(i=0;i<time_us/13;i++)
        {
            INFRARED_OUTPUT=!INFRARED_OUTPUT;
            DelayUs(13);
        }
    }
    else
    {
        INFRARED_OUTPUT=1;//关闭红外线发射管
        DelayUs(time_us);
    }
}

/*
函数功能: NEC协议编码发送
函数参数: 
				u8 user 用户码
				u8 key  按键码
先发低位
按键反码+按键码+用户反码+用户码
*/
void InfraredNECSend(u8 user,u8 key)
{
	u32 i;
	 /*1. 组合发送的数据*/
	u32 data=((~key&0xFF)<<24)|((key&0xFF)<<16)|((~user&0xFF)<<8)|((user&0xFF)<<0);
		
	 /*2. 发送引导码*/
	InfraredSend38KHZ(9000,1);//发送38KHZ载波
	InfraredSend38KHZ(4500,0);//不发送
	
	/*3. 发送32位数据*/
	 for(i=0;i<32;i++)
	 {
			InfraredSend38KHZ(560,1); //间隔时间
			if(data&0x01)InfraredSend38KHZ(1685,0); //发送1
			else InfraredSend38KHZ(560,0); //发送0
		  data>>=1;
	 }
	 InfraredSend38KHZ(560,1); //间隔时间
}

四、格力空调遥控协议介绍

4.1 协议解析

报头脉冲:9ms

报头间距:4.5ms

载波频率:37.9KHz(38KHz)

码段1与码段2间距:20ms

“1”:脉宽,656us。间距,1640us。

“0”:脉宽,656us。间距,544us。

4.2 编码定义

1-3位:模式

送风:图标:风扇。代码:110。

自动:图标:循环箭头。代码:000。

除湿:图标:水滴。代码:010。

制冷:图标:雪花。代码:100。

制热:图标:太阳。代码:001。

4位(加68位):开机关机

开机:1。

关机:0。第68位取反。

5-6位:风速

一级:10

二级:01

三级:11

自动:00

7、37、41位(加65位):扫风

上下扫风:110。第65位取反

左右扫风:101。

上下左右:111

无扫风:000

8位:睡眠

睡眠:1

不睡眠:0

9-12位与65-68位:温度

制冷模式下:

温度 9-12位 65-68位
30 0111 1000
29 1011 0000
28 0011 1111
27 1101 0111
26 0101 1011
25 1001 0011
24 0001 1101
23 1110 0101
22 0110 1001
21 1010 0001
20 0010 1110
19 1100 0110
18 0100 1010
17 1000 0010
16 0000 1100

制热模式:

温度 9-12位 65-68位
30 0111 0010
29 1011 1100
28 1101 0100
27 1101 1000
26 0101 0000
25 1001 1111
24 0001 0111
23 1110 1011
22 0110 0011
21 1010 1101
20 0010 0101
19 1100 1001
18 0100 0001
17 1000 1110
16 0000 0110

吸湿模式:

温度 9-12位 65-68位
30 0111 0100
29 1011 1000
28 0011 0000
27 1101 1111
26 0101 0111
25 1001 1011
24 0001 0011
23 1110 1101
22 0110 0101
21 1010 1001
20 0010 0001
19 1100 1110
18 0100 0110
17 1000 1010
16 0000 0010

送风模式:

温度 9-12位 65-68位
30 0111 1100
29 1011 0100
28 0011 1000
27 1101 0000
26 0101 1111
25 1001 0111
24 0001 1011
23 1110 0011
22 0110 1101
21 1010 0101
20 0010 1001
19 1100 0001
18 0100 1110
17 1000 0110
16 0000 1010

13-20位:睡眠定时

时间 13-20位
0.5 10010000
1 00011000
1.5 10011000
2 00010100
2.5 10010100
3 00011100
3.5 10011100
4 00010010
4.5 10010010
5 00011010
5.5 10011010
6 00010110
6.5 10010110
7 00011110
7.5 10011110
8 00010001
8.5 10010001
9 00011001
9.5 10011001
10 01010000
10.5 11010000
11 01011000
11.5 11011000
12 01010100
12.5 11010100
13 01011100
13.5 11011100
14 01010010
14.5 11010010
15 01011010
15.5 11011010
16 01010110
16.5 11010110
17 01011110
17.5 11011110
18 01010001
18.5 11010001
19 01011001
19.5 11011001
20 00110000
20.5 10110000
21 00111000
21.5 10111000
22 00110100
22.5 10110100
23 00111100
23.5 10111100
24 00110010
0 00000000

21位:超强

超强:1

普通:0

22位:灯光

亮:1

灭:0

23位与25位:健康,换气

健康:10

换气:01

健康+换气:11

普通:00

24位:制冷模式下-干燥;制热模式下-辅热;

干燥:1

普通:0

45-46位:显示温度

不显示:00

显示:10

显示室内温度:01

显示室外温度:11

其他位:

除了29、31、34位为“1”外,均为“0”。其他位功能不详(遥控器无对应项)。

第36位和69位分别是码段1和码段2的最后一位,无所谓“0”“1”。

4.3 其他说明

在自动模式下只可以设置的项目有:风速1、2、3级、自动;上上下左右扫风;显示温度;灯光;睡眠定时(非睡眠)。其他项均不可以设置。此时温度不可设置,温度段的代码为:10011101。

在关机状态下,可以设置定时开机,代码与睡眠定时关机一样。也可以设置灯光。

在制冷模式下,可以设置的项有:温度;扫风;健康换气,节能(仅在此状态下可以设置);风速;定时;超强;睡眠;灯光;温度显示。

在除湿模式下,可以设置的项有:温度;扫风;健康换气;干燥;温度显示;定时;睡眠;灯光。

在送风模式下,可以设置的项有:温度;风速;健康换气;扫风;温度显示;定时;灯光。

在制热模式下,可以设置的项有:温度;风速;扫风;辅热;温度显示;定时;超强;睡眠;灯光。

MGQ 2012-04-141、 格力YB0F2红外信号命令格式

红外信号主要包括CMD1和CMD2两部分,其中CMD1包括35 位的命令 和一位停止位,CMD2包括32位的命令和一位停止位。

五、美的空调协议介绍

L为引导码,

S为分隔码,

A为认别码(A=10110010=B2,预留方案时A=10110111=B7),

A’为A的反码,

B’为B的反码,

C’为C的反码

遥控器发射红外信号之时,通过“560微秒低电平+1680微秒高电平”代表“1”,通过“560微秒低电平+560微秒低电平”代表“0”。

美的的红外采用NEC格式的R05d

该协议的红外信号编码格式为:引导码+客户码+客户反码+数据码+数据反码+结束位

其中引导码和结束码都是固定的,数据反码由数据码按位取反得来,真正变化的只有用户码和数据码。

img

img

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。