紅外編碼分類:
紅外遙控器采用單總線通信方式,紅外常用的編碼:
NEC Protocol 的PWM(脈沖寬度調(diào)制)
Philips RC-5 Protocol 的PPM(脈沖位置調(diào)制)。
NEC協(xié)議特征:8位地址和8位指令長度
地址和命令2次傳輸(確保可靠性)
PWM脈沖寬度調(diào)制,以發(fā)射紅外載波的占空比代表“0”和“1”
載波頻率為38Khz
位時間為1.125ms或2.25ms
NEC碼位定義 :遙控器發(fā)送:
邏輯1:2.25ms(560us脈沖+1680us低電平)
邏輯0:1.125ms(560us脈沖+560us低電平)
接收頭接收:
遙控接收頭在收到脈沖的時候為低電平
邏輯1:560us低+1680us高
邏輯0:560us低+560us高
NEC遙控指令的數(shù)據(jù)格式為:同步碼頭、地址碼、地址反碼、控制碼、控制反碼。
同步碼:同步碼由一個9ms的低電平和一個4.5ms的高電平組成。地址碼、地址反碼、控制碼、控制反碼均是8位數(shù)據(jù)格式。按照低位在前,高位在后的順序發(fā)送。采用反碼是為了增加傳輸?shù)目煽啃裕捎糜谛r灒?/p>
其地址碼為0,控制碼為21??梢钥吹皆?00ms之后,我們還收到了幾個脈沖,這是NEC碼規(guī)定的連發(fā)碼(由9ms低電平+2.5m高電平+0.56ms低電平+97.94ms高電平組成),如果在一幀數(shù)據(jù)發(fā)送完畢之后,按鍵仍然沒有放開,則發(fā)射重復(fù)碼,即連發(fā)碼,可以通過統(tǒng)計連發(fā)碼的次數(shù)來標(biāo)記按鍵按下的長短/次數(shù)。
CODE:#include"remote.h"#include"delay.h"#include"usart.h"http://紅外遙控初始化//設(shè)置IO以及定時器4的輸入捕獲voidRemote_Init(void){GPIO_InitTypeDefGPIO_InitStructure;NVIC_InitTypeDefNVIC_InitStructure;TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;TIM_ICInitTypeDefTIM_ICInitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能PORTB時鐘RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//TIM4時鐘使能GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//PB9輸入GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;//上拉輸入GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStructure);GPIO_SetBits(GPIOB,GPIO_Pin_9);//初始化GPIOB.9TIM_TimeBaseStructure.TIM_Period=10000;//設(shè)定計數(shù)器自動重裝值最大10ms溢出TIM_TimeBaseStructure.TIM_Prescaler=(72-1);//預(yù)分頻器,1M的計數(shù)頻率,1us加1.TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//設(shè)置時鐘分割:TDTS=Tck_timTIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//TIM向上計數(shù)模式TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);//根據(jù)指定的參數(shù)初始化TIMxTIM_ICInitStructure.TIM_Channel=TIM_Channel_4;//選擇輸入端IC4映射到TI4上TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//上升沿捕獲TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;//配置輸入分頻,不分頻TIM_ICInitStructure.TIM_ICFilter=0x03;//IC4F=0011配置輸入濾波器8個定時器時鐘周期濾波TIM_ICInit(TIM4,&TIM_ICInitStructure);//初始化定時器輸入捕獲通道TIM_Cmd(TIM4,ENABLE);//使能定時器4NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn;//TIM3中斷NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//先占優(yōu)先級0級NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//從優(yōu)先級3級NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//IRQ通道被使能NVIC_Init(&NVIC_InitStructure);//根據(jù)NVIC_InitStruct中指定的參數(shù)初始化外設(shè)NVIC寄存器TIM_ITConfig(TIM4,TIM_IT_Update|TIM_IT_CC4,ENABLE);//允許更新中斷,允許CC4IE捕獲中斷}//遙控器接收狀態(tài)//[7]:收到了引導(dǎo)碼標(biāo)志//[6]:得到了一個按鍵的所有信息//[5]:保留//[4]:標(biāo)記上升沿是否已經(jīng)被捕獲//[3:0]:溢出計時器u8RmtSta=0;u16Dval;//下降沿時計數(shù)器的值u32RmtRec=0;//紅外接收到的數(shù)據(jù)u8RmtCnt=0;//按鍵按下的次數(shù)//定時器4中斷服務(wù)程序voidTIM4_IRQHandler(void){//更新中斷,計數(shù)器溢出if(TIM_GetITStatus(TIM4,TIM_IT_Update)!=RESET){if(RmtSta&0x80)//上次有數(shù)據(jù)被接收到了,如果已經(jīng)接受到了引導(dǎo)碼,為了區(qū)分同步嗎和連發(fā)碼{RmtSta&=~0X10;//取消上升沿已經(jīng)被捕獲標(biāo)記if((RmtSta&0X0F)==0X00)RmtSta|=1<<6;//標(biāo)記已經(jīng)完成一次按鍵的鍵值信息采集if((RmtSta&0X0F)<14)RmtSta++;else{//RmtSta&=~(1<<7);//清空引導(dǎo)標(biāo)識RmtSta&=0XF0;//清空計數(shù)器}}}//捕獲中斷if(TIM_GetITStatus(TIM4,TIM_IT_CC4)!=RESET){if(RDATA)//上升沿捕獲{TIM_OC4PolarityConfig(TIM4,TIM_ICPolarity_Falling);//CC4P=1設(shè)置為下降沿捕獲TIM_SetCounter(TIM4,0);//清空定時器值RmtSta|=0X10;//標(biāo)記上升沿已經(jīng)被捕獲}else//下降沿捕獲{Dval=TIM_GetCapture4(TIM4);//讀取CCR4也可以清CC4IF標(biāo)志位TIM_OC4PolarityConfig(TIM4,TIM_ICPolarity_Rising);//CC4P=0設(shè)置為上升沿捕獲if(RmtSta&0X10)//完成一次高電平捕獲{if(RmtSta&0X80)//接收到了引導(dǎo)碼{if(Dval>300&&Dval<800)//560為標(biāo)準(zhǔn)值,560us{RmtRec<<=1;//左移一位.RmtRec|=0;//接收到0}elseif(Dval>1400&&Dval<1800)//1680為標(biāo)準(zhǔn)值,1680us{RmtRec<<=1;//左移一位.RmtRec|=1;//接收到1}elseif(Dval>2200&&Dval<2600)//得到按鍵鍵值增加的信息2500為標(biāo)準(zhǔn)值2.5ms{RmtCnt++;//按鍵次數(shù)增加1次RmtSta&=0XF0;//清空計時器}}elseif(Dval>4200&&Dval<4700)//4500為標(biāo)準(zhǔn)值4.5ms{RmtSta|=1<<7;//標(biāo)記成功接收到了引導(dǎo)碼RmtCnt=0;//清除按鍵次數(shù)計數(shù)器}}RmtSta&=~(1<<4);//對第5位清零,也就是清楚上升沿被捕獲}}TIM_ClearITPendingBit(TIM4,TIM_IT_Update|TIM_IT_CC4);}//處理紅外鍵盤//返回值://0,沒有任何按鍵按下//其他,按下的按鍵鍵值.u8Remote_Scan(void){u8sta=0;u8t1,t2;if(RmtSta&(1<<6))//得到一個按鍵的所有信息了,有按鍵按下{t1=RmtRec>>24;//得到地址碼t2=(RmtRec>>16)&0xff;//得到地址反碼if((t1==(u8)~t2)&&t1==REMOTE_ID)//檢驗遙控識別碼(ID)及地址,地址飯嗎和地址嗎相反并且地址碼=0{t1=RmtRec>>8;//按鍵碼t2=RmtRec;//按鍵飯嗎if(t1==(u8)~t2)sta=t1;//鍵值正確}if((sta==0)||((RmtSta&0X80)==0))//按鍵數(shù)據(jù)錯誤/遙控已經(jīng)沒有按下了{(lán)RmtSta&=~(1<<6);//清除接收到有效按鍵標(biāo)識RmtCnt=0;//清除按鍵次數(shù)計數(shù)器}}returnsta;}