stm32f103讀取紅外接收HS0038A2
軟件:
IAR 7.4
STM32CubeMX 4.14.0
硬件:
STM32F103VBT6
原理圖,和手冊建議的基本一致,只是上拉電阻不是手冊建議的10K以上,這里的面板距離控制器比較遠(yuǎn),可能是考慮到線阻。
HAL配置,使用Cubemx。
HS0038A2的輸出,帶有上拉電阻,接著一個led燈,因此TIM3的IC腳浮空。
設(shè)計者恰好把IR設(shè)計在TIM3的通道4上。如果使用了通道1/2, 就可以使用PWM輸入方式來捕捉紅外脈沖,可以拿到每個脈沖的數(shù)據(jù)。
IC模式使用下降沿。
紅外控制這里是常用的NEC協(xié)議。遙控器輸出高電平,而HS0038A2轉(zhuǎn)換低電平輸出。 如,一個9ms高+4.5ms的低,組成一個header,OUT數(shù)據(jù)線上信號是 9ms低+4ms高,空閑時數(shù)據(jù)線是高(避免干擾)。
因此,我們只檢測下降沿中斷,就可以識別紅外的一個脈沖信號(1幀信號發(fā)出,9ms一開始就拉底,而后4.5ms拉高再拉低)。邏輯1為2.25ms,邏輯0為1.12ms.
Tim3還給其他外設(shè)提供即時,所以這里使用了1us的分辨率。
需要啟用Tim3的中斷,因為使用了Freertos,所以其中斷設(shè)置到最低15級。也不怕其他外設(shè)中斷紅外讀取。
代碼.h
/*
*HS0038A2
*ir.h
*
*/
#ifndef_IR_H
#define_IR_H
#include"tim.h"
#include"cmsis_os.h"
#defineDELTA200
#defineHEADER_MIN13500-DELTA
#defineHEADER_MAX13500+DELTA
#defineDATA1_MIN2250-DELTA
#defineDATA1_MAX2250+DELTA
#defineDATA0_MIN1120-DELTA
#defineDATA0_MAX1120+DELTA
#defineIR_ADDR2
typedefenum{
NECSTATE_IDLE=0,
NECSTATE_START=1,
NECSTATE_RECEIVE=2,
}NEC_State;
#endif
代碼.c:
/*
*ir.c
*/
#include"ir.h"
externosMessageQIdQ_IrHandle;
staticuint32_tccr_prev=0;
staticuint32_tccr_cur=0;
staticuint32_ttimeout=0;
staticuint8_tpulse_cnt=0;
staticuint32_tir_code;
NEC_Statestate=NECSTATE_IDLE;
voidHAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef*htim)
{
if(htim->Instance==TIM3&&htim->Channel==HAL_TIM_ACTIVE_CHANNEL_4){
ccr_cur=__HAL_TIM_GET_COMPARE(&htim3,TIM_CHANNEL_4);
uint32_tdelta_t;
if(ccr_cur>ccr_prev){
delta_t=ccr_cur-ccr_prev;
}
else{
delta_t=0xffff-ccr_prev+ccr_cur;//0xffff溢出
}
//接收到信息頭,就接收4個8字節(jié)
。
。
。
//校驗
if((uint8_t)(~code[0])!=code[1]||(uint8_t)(~code[2])!=code[3])
return;
if(code[0]!=IR_ADDR)
return;
//放到隊列
if(Q_IrHandle!=NULL){
osMessagePut(Q_IrHandle,code[2],0);
}
}
//超時110ms
if(timeout>=110*1000){
state=NECSTATE_IDLE;
pulse_cnt=0;
ir_code=0;
timeout=0;
}
ccr_prev=ccr_cur;
}
//
}
檢測到信息頭后,連續(xù)讀32bit到一個uint32_t數(shù)據(jù)中。
這里沒有依靠最后1給560us來做結(jié)束判斷,只是一個 pulse_cnt>=32 來做判斷,開始寫到 pulse_cnt>=31,結(jié)果反碼總是差0x80。
最后分離出4個字節(jié),做地址檢測,以及校驗。 校驗是使用 ~ 取反碼,IAR下需要強(qiáng)制轉(zhuǎn)換到uint8_t,否則判斷條件為假。
也沒有做連續(xù)按鍵處理。
超時處理,一個是判斷脈沖持續(xù)時間在3ms內(nèi),另一個是判斷脈沖總時間在110ms內(nèi)。
因為板子用可控硅控制罩極電機(jī),啟動電機(jī)后,能看到OUT輸出干擾信號,但是被headr判斷給擋掉了。