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

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

一、环境介绍

MCU: STM32F103ZET6


编程软件环境: keil5


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


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


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


完整keil工程源码下载(解压即可编译运行测试):  


https://download.csdn.net/download/xiaolong1126626497/19863305


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

2.1 NEC协议介绍

NEC协议在上篇<STM32入门开发: NEC红外线协议解码(超低成本无线传输方案)>文章里已经详细介绍过了。这篇文章和上篇文章内容是连贯的,上篇文章完成NEC红外线协议解码,这篇文章就当做遥控器发送端,发送自定义数据给接收端,完成自定义的数据传输;也可以模拟家电遥控器,对电视机、投影仪、空调等设备进行遥控操作。


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


2. 2 使用的相关硬件

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

image.png

2.3 完成NEC协议编码发送

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

image.png

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

image.png

收到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); //间隔时间
}

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

image.png

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

image.png

三、核心代码

3.1 main.c

#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位:温度


制冷模式下:

image.png

制热模式:

image.png

吸湿模式:

image.png

送风模式:

image.png

13-20位:睡眠定时

image.pngimage.png

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位的命令和一位停止位。

image.png

image.png

五、美的空调协议介绍

L为引导码,


S为分隔码,


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


A'为A的反码,


B'为B的反码,


C'为C的反码


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


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


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


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

image.png

image.png


目录
相关文章
|
27天前
|
传感器 监控
基于STM32的智能公交站牌系统设计与实现
基于STM32的智能公交站牌系统设计与实现
13 0
|
3月前
|
传感器 物联网 芯片
毕业设计 基于STM32单片机无线ZIGBEE智能大棚土壤湿度光照检测
毕业设计 基于STM32单片机无线ZIGBEE智能大棚土壤湿度光照检测
|
27天前
|
传感器 监控 API
基于STM32的智能灌溉系统设计与实现
基于STM32的智能灌溉系统设计与实现
92 1
|
4月前
|
传感器
基于stm32的智能婴儿床(毕业设计)
基于stm32的智能婴儿床(毕业设计)
|
7月前
|
存储 编译器 C语言
STM32开发 -- Keil基本使用
STM32开发 -- Keil基本使用
307 0
|
4月前
|
人工智能 安全 搜索推荐
单片机毕业设计|基于stm32智能快递箱设计
随在当今的社会,网上购物以及线下获取快递己经成为日常生活中很重要的一个组成部分,电子商务的发展也带来了快递业的繁荣。这对快递业而言,是一个巨大的发展机遇,同时也是一个不可忽视的挑战。当前,快件运输的安全性越来越受到大家的重视,对快件的服务要求也越来越高。但就目前的快递行业来说,也面临着这样那样的问题,比较经常遇到送快递的到了,业务不在家,取快递时间对不上等。在此基础上,提出了一种以STM32为核心的智能化快递柜。本快递柜的主要功能有,指纹解锁功能,按键功能,警报功能,继电器柜门开锁功能,验证码功能,主要设计加入了指纹解锁功能。本系统以STM32F103为主控芯片,配置了指纹传感、4*4矩阵键盘
132 0
|
3月前
|
人工智能 安全 搜索推荐
单片机毕业设计|基于stm32智能快递箱设计
单片机毕业设计|基于stm32智能快递箱设计
|
3月前
|
缓存 编译器 程序员
嵌入式开发环境Vscode开发STM32单片机程序
嵌入式开发环境Vscode开发STM32单片机程序
55 0
|
3月前
|
传感器 内存技术
毕业设计 江科大STM32的智能温室控制蓝牙声光报警APP系统设计
毕业设计 江科大STM32的智能温室控制蓝牙声光报警APP系统设计
|
3月前
|
机器学习/深度学习 传感器 语音技术
毕业设计|基于STM32单片机的语音识别控制智能停车场设计
毕业设计|基于STM32单片机的语音识别控制智能停车场设计