STM32開發(fā)指南--第三十二章 紅外遙控實(shí)驗(yàn)
第三十二章紅外遙控實(shí)驗(yàn)
本章,我們將向大家介紹如何通過STM32來解碼紅外遙控器的信號。ALIENTK戰(zhàn)艦STM32開發(fā)板標(biāo)配了紅外接收頭和一個很小巧的紅外遙控器。在本章中,我們將利用STM32的輸入捕獲功能,解碼開發(fā)板標(biāo)配的這個紅外遙控器的編碼信號,并將解碼后的鍵值TFTLCD模塊上顯示出來。本章分為如下幾個部分:
32.1 紅外遙控簡介
32.2 硬件設(shè)計(jì)
32.3 軟件設(shè)計(jì)
32.4 下載驗(yàn)證
32.1紅外遙控簡介
紅外遙控是一種無線、非接觸控制技術(shù),具有抗干擾能力強(qiáng),信息傳輸可靠,功耗低,成本低,易實(shí)現(xiàn)等顯著優(yōu)點(diǎn),被諸多電子設(shè)備特別是家用電器廣泛采用,并越來越多的應(yīng)用到計(jì)算機(jī)系統(tǒng)中。
由于紅外線遙控不具有像無線電遙控那樣穿過障礙物去控制被控對象的能力,所以,在設(shè)計(jì)紅外線遙控器時,不必要像無線電遙控器那樣,每套(發(fā)射器和接收器)要有不同的遙控頻率或編碼(否則,就會隔墻控制或干擾鄰居的家用電器),所以同類產(chǎn)品的紅外線遙控器,可以有相同的遙控頻率或編碼,而不會出現(xiàn)遙控信號“串門”的情況。這對于大批量生產(chǎn)以及在家用電器上普及紅外線遙控提供了極大的方面。由于紅外線為不可見光,因此對環(huán)境影響很小,再由紅外光波動波長遠(yuǎn)小于無線電波的波長,所以紅外線遙控不會影響其他家用電器,也不會影響臨近的無線電設(shè)備。
紅外遙控的編碼目前廣泛使用的是:NEC Protocol 的PWM(脈沖寬度調(diào)制)和Philips
RC-5 Protocol 的PPM(脈沖位置調(diào)制)。ALIENTEK戰(zhàn)艦STM32開發(fā)板配套的遙控器使用的是NEC協(xié)議,其特征如下:
1、8位地址和8位指令長度;
2、地址和命令2次傳輸(確??煽啃裕?/p>
3、PWM脈沖位置調(diào)制,以發(fā)射紅外載波的占空比代表“0”和“1”;
4、載波頻率為38Khz;
5、位時間為1.125ms或2.25ms;
NEC碼的位定義:一個脈沖對應(yīng)560us的連續(xù)載波,一個邏輯1傳輸需要2.25ms(560us脈沖+1680us低電平),一個邏輯0的傳輸需要1.125ms(560us脈沖+560us低電平)。而遙控接收頭在收到脈沖的時候?yàn)榈碗娖?,在沒有脈沖的時候?yàn)楦唠娖?,這樣,我們在接收頭端收到的信號為:邏輯1應(yīng)該是560us低+1680us高,邏輯0應(yīng)該是560us低+560us高。
NEC遙控指令的數(shù)據(jù)格式為:同步碼頭、地址碼、地址反碼、控制碼、控制反碼。同步碼由一個9ms的低電平和一個4.5ms的高電平組成,地址碼、地址反碼、控制碼、控制反碼均是8位數(shù)據(jù)格式。按照低位在前,高位在后的順序發(fā)送。采用反碼是為了增加傳輸?shù)目煽啃裕捎糜谛r?yàn))。
我們遙控器的按鍵2按下時,從紅外接收頭端收到的波形如圖32.1.1所示:
圖32.1.1 按鍵2所對應(yīng)的紅外波形
從圖32.1.1中可以看到,其地址碼為0,控制碼為168??梢钥吹皆?00ms之后,我們還收到了幾個脈沖,這是NEC碼規(guī)定的連發(fā)碼(由9ms低電平+2.5m高電平+0.56ms低電平+97.94ms高電平組成),如果在一幀數(shù)據(jù)發(fā)送完畢之后,按鍵仍然沒有放開,則發(fā)射重復(fù)碼,即連發(fā)碼,可以通過統(tǒng)計(jì)連發(fā)碼的次數(shù)來標(biāo)記按鍵按下的長短/次數(shù)。
第十五章我們曾經(jīng)介紹過利用輸入捕獲來測量高電平的脈寬,本章解碼紅外遙控信號,剛好可以利用輸入捕獲的這個功能來實(shí)現(xiàn)遙控解碼。關(guān)于輸入捕獲的介紹,請參考第十五章的內(nèi)容。
32.2硬件設(shè)計(jì)
本實(shí)驗(yàn)采用定時器的輸入捕獲功能實(shí)現(xiàn)紅外解碼,本章實(shí)驗(yàn)功能簡介:開機(jī)在LCD上顯示一些信息之后,即進(jìn)入等待紅外觸發(fā),如過接收到正確的紅外信號,則解碼,并在LCD上顯示鍵值和所代表的意義,以及按鍵次數(shù)等信息。同樣我們也是用LED0來指示程序正在運(yùn)行。
所要用到的硬件資源如下:
1)指示燈DS0
2) TFTLCD模塊(帶觸摸屏)
3)紅外接收頭
4)紅外遙控器
前兩個,在之前的實(shí)例已經(jīng)介紹過了,遙控器屬于外部器件,遙控接收頭在板子上,與MCU的連接原理圖如32.2.1所示:
圖32.2.1 紅外遙控接收頭與STM32的連接電路圖
紅外遙控接收頭連接在STM32的PB9(TIM4_CH4)上。硬件上不需要變動,只要程序?qū)IM4_CH4設(shè)計(jì)為輸入捕獲,然后將收到的脈沖信號解碼就可以了。 開發(fā)板配套的紅外遙控器外觀如圖32.2.2所示:
圖32.2.2 紅外遙控器
32.3軟件設(shè)計(jì)
打開上一章的工程,首先在HARDWARE文件夾下新建一個REMOTE的文件夾。然后新建一個remote.c和remote.h的文件保存在REMOTE文件夾下,并將這個文件夾加入頭文件包含路徑。
打開remote.c文件,輸入如下代碼:
#include "remote.h"
#include "delay.h"
#include "usart.h"
//紅外遙控初始化
//設(shè)置IO以及定時器4的輸入捕獲
void Remote_Init(void)
{
RCC->APB1ENR|=1<<2; //TIM4時鐘使能
RCC->APB2ENR|=1<<3; //使能PORTB時鐘
GPIOB->CRH&=0XFFFFFF0F; //PB9輸入
GPIOB->CRH|=0X00000080; //上拉輸入
GPIOB->ODR|=1<<9; //PB9上拉
TIM4->ARR=10000; //設(shè)定計(jì)數(shù)器自動重裝值最大10ms溢出
TIM4->PSC=71; //預(yù)分頻器,1M的計(jì)數(shù)頻率,1us加1.
TIM4->CCMR2|=1<<8; //CC4S=01 選擇輸入端IC4映射到TI4上
TIM4->CCMR2|=3<<12; //IC4F=0011配置輸入濾波器8個定時器時鐘周期濾波
TIM4->CCMR2|=0<<10; //IC4PS=00 配置輸入分頻,不分頻
TIM4->CCER|=0<<13; //CC4P=0 上升沿捕獲
TIM4->CCER|=1<<12; //CC4E=1 允許捕獲計(jì)數(shù)器的值到捕獲寄存器中
TIM4->DIER|=1<<4; //允許CC4IE捕獲中斷
TIM4->DIER|=1<<0; //允許更新中斷
TIM4->CR1|=0x01; //使能定時器4
MY_NVIC_Init(1,3,TIM4_IRQChannel,2);//搶占1,子優(yōu)先級3,組2
}
//遙控器接收狀態(tài)
//[7]:收到了引導(dǎo)碼標(biāo)志
//[6]:得到了一個按鍵的所有信息
//[5]:保留
//[4]:標(biāo)記上升沿是否已經(jīng)被捕獲
//[3:0]:溢出計(jì)時器
u8 RmtSta=0;
u16 Dval; //下降沿時計(jì)數(shù)器的值
u32 RmtRec=0; //紅外接收到的數(shù)據(jù)
u8RmtCnt=0; //按鍵按下的次數(shù)
//定時器2中斷服務(wù)程序
void TIM4_IRQHandler(void)
{
//省略代碼
}
//處理紅外鍵盤
//返回值:
// 0,沒有任何按鍵按下
//其他,按下的按鍵鍵值.
u8 Remote_Scan(void)
{
u8 sta=0;
u8 t1,t2;
if(RmtSta&(1<<6))//得到一個按鍵的所有信息了
{
t1=RmtRec>>24; //得到地址碼
t2=(RmtRec>>16)&0xff; //得到地址反碼
if((t1==(u8)~t2)&&t1==REMOTE_ID)//檢驗(yàn)遙控識別碼(ID)及地址
{
t1=RmtRec>>8;
t2=RmtRec;
if(t1==(u8)~t2)sta=t1;//鍵值正確
}
if((sta==0)||((RmtSta&0X80)==0))//按鍵數(shù)據(jù)錯誤/遙控已經(jīng)沒有按下了
{
RmtSta&=~(1<<6);//清除接收到有效按鍵標(biāo)識
RmtCnt=0; //清除按鍵次數(shù)計(jì)數(shù)器
}
}
return sta;
}
該部分代碼包含3個函數(shù),首先是Remote_Init函數(shù),該函數(shù)用于初始化IO口,并配置TIM4_CH4為輸入捕獲,并設(shè)置其相關(guān)參數(shù)。TIM4_IRQHandler函數(shù)是TIM4的中斷服務(wù)函數(shù),在該函數(shù)里面,實(shí)現(xiàn)對紅外信號的高電平脈沖的捕獲,同時根據(jù)我們之前簡介的協(xié)議內(nèi)容來解碼 ,該函數(shù)用到幾個全局變量,用于輔助解碼,并存儲解碼結(jié)果。最后是Remote_Scan函數(shù),該函用來掃描解碼結(jié)果,相當(dāng)于我們的按鍵掃描,輸入捕獲解碼的紅外數(shù)據(jù),通過該函數(shù)傳送給其他程序。
保存remote.c,然后把該文件加入HARDWARE組下。接下來打開remote.h在該文件里面加入如下代碼:
//省略代碼
這里的REMOTE_ID就是我們開發(fā)板配套的遙控器的識別碼,對于其他遙控器可能不一樣,只要修改這個為你所使用的遙控器的一致就可以了。其他是一些函數(shù)的聲明,我們保存此部分代碼,然后在test.c里面修改主函數(shù)如下:
int main(void)
{
//省略部分代碼
}
至此,我們的軟件設(shè)計(jì)部分就結(jié)束了。
32.4下載驗(yàn)證
在代碼編譯成功之后,我們通過下載代碼到ALIENTEK戰(zhàn)艦STM32開發(fā)板上,可以看到LCD顯示如圖32.4.1所示的內(nèi)容:
圖32.4.1 程序運(yùn)行效果圖
此時我們通過遙控器按下不同的按鍵,則可以看到LCD上顯示了不同按鍵的鍵值以及按鍵次數(shù)和對應(yīng)的遙控器上的符號。如圖32.4.2所示:
圖32.4.2 解碼成功