生活随笔
收集整理的這篇文章主要介紹了
红外数据的基本原理和处理机制
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
紅外數據的處理主要分為對應的接收和發送處理。 數據要基于38K的載波進行數據的發送。
紅外常用的協議有NEC和RC-5。 NEC: 起始碼:9ms低電平 + 4.5ms高電平 邏輯0: 560us + 560us 邏輯1: 560us + 1680us 重復碼 : 9ms低電平 + 2.5ms高電平
RC-5: 邏輯0: 889us低電平+889高電平 邏輯1: 889us高電平+889低電平 起始位(Start Bit):1bit,固定為邏輯"1". 驗證位(Field Bit):1bit, (1)“1”: RC-5(原始RC5協議), (2) “0”: RC-5X(擴展RC5協議)。 控制位(TR Bit):1bit,當遙控器按鍵松開到再次按下時,這位會反轉(0→1, 1→0),通過這種方式,接收器可以辨別按鍵是否一直按下或者是重復按鍵。 地址位(Address):5bit,表示所要控制的設備類型,最高有效位首先發送。 命令位(Command)6bit,表示按鍵的值,最高有效位首先發送。 (1)若FieldBit = 1,CMD范圍:0x0~0x3F; (2)若FieldBit = 0,CMD范圍:0x40~0x7F。
不過現在市面的空調,電視等基本都是采用NEC的數據格式,再結合自己的數據分包形成協議發送。
美的的空調數據協議: 數據格式:引導碼+48位數據+分隔碼+48位數據 LAA’BB’CC’ S LAA’BB’CC’) L為引導碼; ABC為實際數據,A’為A的反碼,B’為B的反碼,C’為C的反碼; S為分隔碼; L引導碼:4.5ms低電平+4.5ms高電平 數據A:A為識別碼 數據B和C就是對應的空調數據。 分隔碼:540us低電平+5.2ms高電平。
格力的空調數據協議格式: 起始碼(s)+35位數據碼+連接碼(c)+32位數據碼 起始碼:9000us低電平+4500us高電平 連接碼:600us低電平+20000us高電平 邏輯0: 600us低電平 + 600us高電平 邏輯1: 600us低電平 + 1600us高電平 這樣會產生一個問題就是每個廠商他們使用的不統一,這樣會導致我們無法通過統一的標準格式去處理數據。這樣想到唯一的處理方式就是將對應的高低電平直接記錄用以表示整個數據協議格式。
每個位的低電平和高電平分別用兩個字節數據存儲,比如格力的:起始碼4個字節數據,35位數據碼140個字節,連接碼4個字節,32位數據碼128個字節,一共276個字節可以記錄完整數據。
紅外數據接收處理:NEC格式
1、將定時器通道配置為上升沿捕獲,當捕獲到一個上升沿時,計數器等清0,接著將捕獲極性改為下降沿捕獲。當第二次捕獲中斷時,捕獲到下降沿,并記錄此時時間,這個時間就是整個高電平的時間。 2、根據NEC編碼規則判斷該次時長代表的是0還是1。1.68 ms 高電平為1,0.56 ms 高電平為0,2.25ms高電平為重復碼。 3、如何判斷數據收完了?重復碼有沒有,或者說重復碼又什么時候收完?可以在初始化定時,設置定時器10ms溢出中斷一次,根據NEC協議可以知道,因為每次上升沿捕獲時都會計數器等清0,那么收完整個數據都不會溢出中斷一次,所以當溢出中斷一次就代表數據收完了。 4、判斷重復碼什么時候收完?因為數據碼和重復碼中間有段空閑,而 10ms溢出中斷一次,測試空閑時長應該是30ms左右,那么只需要設置溢出中斷標志,每次觸發都加1,在上升沿捕獲時清0,那么如果溢出中斷標志>3,就代表40ms內沒收到過高電平了,那么就說明數據接收完了,且沒有重復碼的產生。根據NEC重復碼的協議,我們10ms溢出中斷一次,為了接收全部的重復碼則判斷當收到重復碼時,如果溢出中斷標志>9時,就代表重復碼收完。
void Tim_Init(void) ? ??? ??? ??? ? ?
{?? ??? ?GPIO_InitTypeDef ?GPIO_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;TIM_TimeBaseInitTypeDef ?TIM_TimeBaseStructure;TIM_ICInitTypeDef ?TIM1_ICInitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//TIM1時鐘使能?//GPIOA8 ?復用功能,上拉GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//復用功能GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽輸出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF_TIM1); //GPIOA8復用為TIM1TIM_TimeBaseStructure.TIM_Prescaler=167; ?預分頻器,1M的計數頻率,1us加1.?? ?TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上計數模式TIM_TimeBaseStructure.TIM_Period=10000; ? //設定計數器自動重裝值 最大10ms溢出 ?TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;?TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);?//初始化TIM2輸入捕獲參數TIM1_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 ?? ?選擇輸入端 IC1映射到TI1上TIM1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;?? ?//上升沿捕獲TIM1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上TIM1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;?? ? //配置輸入分頻,不分頻?TIM1_ICInitStructure.TIM_ICFilter = 0x03;//IC1F=0003 8個定時器時鐘周期濾波TIM_ICInit(TIM1, &TIM1_ICInitStructure);//初始化定時器2輸入捕獲通道TIM_ITConfig(TIM1,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允許更新中斷 ,允許CC1IE捕獲中斷?? ?TIM_Cmd(TIM1,ENABLE ); ?? ? ?? ?//使能定時器1NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//搶占優先級1NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;?? ??? ?//子優先級3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;?? ??? ??? ?//IRQ通道使能NVIC_Init(&NVIC_InitStructure);?? ?//初始化NVIC寄存器NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//搶占優先級3NVIC_InitStructure.NVIC_IRQChannelSubPriority =2;?? ??? ?//子優先級2NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;?? ??? ??? ?//IRQ通道使能NVIC_Init(&NVIC_InitStructure);?? ?//初始化NVIC寄存器
}//遙控器接收狀態
//[7]:收到了引導碼標志
//[6]:得到了一個按鍵的所有信息
//[5]:保留?? ?
//[4]:標記上升沿是否已經被捕獲?? ??? ??? ??? ??? ??? ??? ??? ? ??
//[3:0]:溢出計時器
u8 ?? ?RmtSta=0;?? ? ??? ? ?
u16 Dval;?? ??? ?//下降沿時計數器的值
u32 RmtRec=0;?? ?//紅外接收到的數據?? ? ? ?? ??? ? ? ?
u8 ?RmtCnt=0;?? ?//按鍵按下的次數?? ??
//定時器1溢出中斷
void TIM1_UP_TIM10_IRQHandler(void)
{if(TIM_GetITStatus(TIM1,TIM_IT_Update)==SET) //溢出中斷{if(RmtSta&0x80)//上次有數據被接收到了{?? ?RmtSta&=~0X10;?? ??? ??? ??? ??? ??? ?//取消上升沿已經被捕獲標記if((RmtSta&0X0F)==0X00)RmtSta|=1<<6;//標記已經完成一次按鍵的鍵值信息采集if((RmtSta&0X0F)<14)RmtSta++;else{RmtSta&=~(1<<7);//清空引導標識RmtSta&=0XF0;?? ?//清空計數器?? ?}?? ??? ??? ??? ??? ??? ? ?? ? ? ?? ?}?? ??? ??? ??? ??? ??? ??? ? ? ?}TIM_ClearITPendingBit(TIM1,TIM_IT_Update); ?//清除中斷標志位?
}?
//定時器1輸入捕獲中斷服務程序?? ??
void TIM1_CC_IRQHandler(void)
{ ?? ??? ? ? ??? ??if(TIM_GetITStatus(TIM1,TIM_IT_CC1)==SET) //處理捕獲(CC1IE)中斷{?? ? ?if(RDATA)//上升沿捕獲{TIM_OC1PolarityConfig(TIM1,TIM_ICPolarity_Falling);?? ??? ?//CC1P=1 設置為下降沿捕獲TIM_SetCounter(TIM1,0);?? ? ? ?? ?//清空定時器值RmtSta|=0X10;?? ??? ??? ??? ??? ?//標記上升沿已經被捕獲}else //下降沿捕獲{Dval=TIM_GetCapture1(TIM1);//讀取CCR1也可以清CC1IF標志位TIM_OC1PolarityConfig(TIM1,TIM_ICPolarity_Rising); //CC1P=0?? ?設置為上升沿捕獲if(RmtSta&0X10)?? ??? ??? ??? ??? ?//完成一次高電平捕獲?{if(RmtSta&0X80)//接收到了引導碼{if(Dval>300&&Dval<800)?? ??? ??? ?//560為標準值,560us{RmtRec<<=1;?? ?//左移一位.RmtRec|=0;?? ?//接收到0?? ? ??}else if(Dval>1400&&Dval<1800)?? ?//1680為標準值,1680us{RmtRec<<=1;?? ?//左移一位.RmtRec|=1;?? ?//接收到1}else if(Dval>2200&&Dval<2600)?? ?//得到按鍵鍵值增加的信息 2500為標準值2.5ms{RmtCnt++; ?? ??? ?//按鍵次數增加1次RmtSta&=0XF0;?? ?//清空計時器?? ??? ?}}else if(Dval>4200&&Dval<4700)?? ??? ?//4500為標準值4.5ms{RmtSta|=1<<7;?? ?//標記成功接收到了引導碼RmtCnt=0;?? ??? ?//清除按鍵次數計數器}?? ??? ??? ??? ??? ??? ??}RmtSta&=~(1<<4);}?? ??? ??? ??? ? ?? ??? ? ? ? ?? ? ? ??? ??? ??? ??? ??? ? ??}TIM_ClearITPendingBit(TIM1,TIM_IT_CC1); ?//清除中斷標志位?
}
//處理紅外鍵盤
//返回值:
//?? ? 0,沒有任何按鍵按下
//其他,按下的按鍵鍵值.
u8 Jx_IrDataHandle(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)//檢驗遙控識別碼(ID)及地址?{?t1=RmtRec>>8;t2=RmtRec; ?? ?if(t1==(u8)~t2)sta=t1;//鍵值正確?? ??} ??if((sta==0)||((RmtSta&0X80)==0))//按鍵數據錯誤/遙控已經沒有按下了{RmtSta&=~(1<<6);//清除接收到有效按鍵標識RmtCnt=0;?? ??? ?//清除按鍵次數計數器}} ?return sta;
}
紅外發送處理: 根據我們上面接收到的紅外數據,然后通過對應的PWM波設置對應高低電平的占空比,然后在38K的載波進行數據發送就可形成紅外數據。
總結
以上是生活随笔 為你收集整理的红外数据的基本原理和处理机制 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。