一、環境介紹
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輸出腳即可。
2.3 完成NEC協定編碼發送
先看一段紅外線接收頭引腳上采集的NEC協定的電平: 這是接收端采集的。
紅外線接收頭的硬體特性: (注意: 這裡是針對NEC遙控器協定來說明),下圖就是目前使用的紅外線接收頭。收到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); //間隔時間
}
這是使用邏輯分析儀采集的發送端波形: 和協定對應了一下,沒有問題。
對比一下解碼端采集的波形圖:
三、核心代碼
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位:溫度
制冷模式下:
制熱模式:
吸濕模式:
送風模式:
13-20位:睡眠定時
21位:超強
超強:1
普通:0
22位:燈光
亮:1
滅:0
23位與25位:健康,換氣
健康:10
換氣:01
健康+換氣:11
普通:00
24位:制冷模式下-幹燥;制熱模式下-輔熱;
幹燥:1
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
該協定的紅外信号編碼格式為:引導碼+客戶碼+客戶反碼+資料碼+資料反碼+結束位,
其中引導碼和結束碼都是固定的,資料反碼由資料碼按位取反得來,真正變化的隻有使用者碼和資料碼。