【1】NEC紅外線協(xié)議介紹
NEC紅外線協(xié)議是一種常用的紅外線通信協(xié)議,廣泛應(yīng)用于消費(fèi)電子產(chǎn)品中,如電視、DVD播放器、空調(diào)遙控器等。該協(xié)議定義了紅外線通信的物理層和數(shù)據(jù)鏈路層規(guī)范,以實(shí)現(xiàn)可靠的紅外線數(shù)據(jù)傳輸。
下面是NEC紅外線協(xié)議的詳細(xì)介紹:
(1)載波頻率:NEC紅外線協(xié)議使用的載波頻率為38kHz。發(fā)送方通過以38kHz頻率調(diào)制紅外線光信號(hào),接收方則通過解調(diào)來(lái)接收數(shù)據(jù)。
(2)數(shù)據(jù)編碼:NEC紅外線協(xié)議使用脈沖寬度編碼(Pulse Width Encoding)來(lái)表示二進(jìn)制數(shù)據(jù)。每個(gè)數(shù)據(jù)位由一系列的脈沖組成,邏輯0和邏輯1分別由不同的脈沖寬度表示。
- 邏輯0:發(fā)送方發(fā)射一個(gè)530μs的載波后,延遲時(shí)間為530μs。
- 邏輯1:發(fā)送方發(fā)射一個(gè)530μs的載波后,延遲時(shí)間為1.69ms。
(3)幀結(jié)構(gòu):NEC紅外線協(xié)議的一個(gè)完整幀由多個(gè)數(shù)據(jù)位組成,包括引導(dǎo)碼、自定義碼、數(shù)據(jù)碼和反碼。幀結(jié)構(gòu)如下:
- 引導(dǎo)碼(Leader Code):由一系列的載波脈沖組成,用于同步接收方和發(fā)送方的時(shí)鐘。
- 自定義碼(Custom Code):8位數(shù)據(jù),用于識(shí)別設(shè)備類型。
- 數(shù)據(jù)碼(Data Code):8位數(shù)據(jù),用于傳輸具體命令或數(shù)據(jù)。
- 反碼(Inverted Data Code):數(shù)據(jù)碼的反碼,用于校驗(yàn)數(shù)據(jù)的正確性。
(4)重復(fù)碼:為了提高通信可靠性,NEC紅外線協(xié)議還定義了重復(fù)碼。當(dāng)按鍵保持不松開時(shí),發(fā)送方會(huì)周期性地發(fā)送重復(fù)碼,以確保接收方正確接收到連續(xù)的按鍵數(shù)據(jù)。
(5)接收端工作原理:接收端使用紅外線接收模塊接收紅外線信號(hào),并通過解調(diào)將其轉(zhuǎn)換為數(shù)字?jǐn)?shù)據(jù)。接收端在接收到引導(dǎo)碼后,開始解析自定義碼和數(shù)據(jù)碼,并進(jìn)行校驗(yàn)。
NEC紅外線協(xié)議的優(yōu)點(diǎn)是簡(jiǎn)單、廣泛應(yīng)用,并且在消費(fèi)電子產(chǎn)品中得到了廣泛支持。提供了可靠的紅外線數(shù)據(jù)傳輸方式,適用于遠(yuǎn)程控制和通信需求。
【2】硬件連接
38KHZ紅外線接收頭硬件連接圖:
【3】源代碼
Main.c示例代碼
#include "stm32f4xx.h" // Device header
#include "led.h"
#include "delay.h"
#include "key.h"
#include "usart.h"
#include "sys.h"
#include "exti.h"
#include "timer.h"
#include "pwm.h"
#include "ds18b20.h"
#include "infrared.h"
extern u8 InfraredRxBuff[5];
int main(void)
{
LED_Init();
KEY_Init();
USART1_Init(84,115200);
KEY_EXTI_Init();
DS18B20_Init();
InfraredRxInit(); //紅外線解碼初始化
while(1)
{
if(InfraredRxBuff[4])
{
InfraredRxBuff[4]=0; //清除接收成功標(biāo)志
printf("USER=0x%x
",InfraredRxBuff[0]);
printf("KEY=0x%x
",InfraredRxBuff[2]);
LED0=0;
DelayMs(100);
LED0=1;
}
}
}
?
?
Infread.c文件示例
#include "infrared.h"
/*
函數(shù)功能:紅外線解碼初始化
硬件連接:PA8
定 時(shí) 器:使用TIM2
*/
void InfraredRxInit(void)
{
/*1. 開時(shí)鐘*/
RCC- >AHB1ENR|=1< < 0;//使能PORTA時(shí)鐘
/*2. 配置GPIO口模式*/
GPIOA- >MODER&=~(0x3< < 8*2); //清除模式
GPIOA- >MODER|=0x0< < 8*2; //配置輸入模式
/*3. 開啟SYSCFG時(shí)鐘 */
RCC- >APB2ENR|=1< < 14;
/*4. 開放來(lái)自線x上的中斷請(qǐng)求*/
EXTI- >IMR|=1< < 8; //中斷線8
/*3. 配置中斷線觸發(fā)邊沿*/
EXTI- >FTSR|=1< < 8; //下降沿
/*4. 配置產(chǎn)生中斷的對(duì)應(yīng)IO口*/
SYSCFG- >EXTICR[2]&=~(0xf< < 0*4);
SYSCFG- >EXTICR[2]|=0x0< < 0*4;
/*5. 配置中斷優(yōu)先級(jí)*/
SetNVICPriorityGrouping(EXTI9_5_IRQn,1,1);
/*6. 初始化定時(shí)器*/
RCC- >APB1ENR|=1< < 0; //開啟定時(shí)器2的時(shí)鐘
RCC- >APB1RSTR|=1< < 0; //開啟復(fù)位時(shí)鐘
RCC- >APB1RSTR&=~(1< < 0); //關(guān)閉
TIM2- >PSC=84; //預(yù)分頻
TIM2- >ARR=65535; //重裝載寄存器
TIM2- >CR1&=~(1< < 0); //開啟計(jì)數(shù)器
}
?
/*
函數(shù)功能:獲取高電平持續(xù)的時(shí)間
返 回 值:高電平持續(xù)的時(shí)間
*/
u32 GetInfraredRxH(void)
{
TIM2- >CR1|=1< < 0;
TIM2- >CNT=0;
while(INFRARED_RX){}
TIM2- >CR1&=~(1< < 0);
return TIM2- >CNT;
}
?
/*
函數(shù)功能:獲取低電平持續(xù)的時(shí)間
返 回 值:低電平持續(xù)的時(shí)間
*/
u32 GetInfraredRxL(void)
{
TIM2- >CR1|=1< < 0;
TIM2- >CNT=0;
while(!INFRARED_RX){}
TIM2- >CR1&=~(1< < 0);
return TIM2- >CNT;
}
?
?
/*
函數(shù)功能:外部中斷線0中斷服務(wù)函數(shù)
NEC協(xié)議解碼原理:
1. 先接收引導(dǎo)碼:9ms低電平+4.5ms高電平
2. 引導(dǎo)碼之后,是連續(xù)的32位數(shù)據(jù)。用戶碼+用戶反碼+按鍵碼+按鍵反碼
3. 數(shù)據(jù)‘0’ :560us低電平+560us高電平
4. 數(shù)據(jù)‘1’ :560us低電平+1680us高電平
*/
u8 InfraredRxBuff[5]={0}; //存放紅外線接收的數(shù)據(jù)值,其中[4]表示標(biāo)志位。=0失敗,=1成功
void EXTI9_5_IRQHandler(void)
{
u32 time,j,i;
u8 data=0;
EXTI- >PR|=1< < 0; //清除中斷標(biāo)志位
/*1. 判斷引導(dǎo)碼*/
time=GetInfraredRxL(); //獲取低電平的時(shí)間
if(time< 5000||time >11000)return;
time=GetInfraredRxH();
if(time< 2500||time >5500)return;
/*2. 接收用戶碼和按鍵碼*/
for(i=0;i< 4;i++)
{
for(j=0;j< 8;j++)
{
time=GetInfraredRxL(); //獲取低電平的時(shí)間
if(time< 360||time >660)return;
time=GetInfraredRxH(); //獲取高電平的時(shí)間
//560us高電平 0 、 1680us高電平 1
if(time >360&&time< 660