我用的紅外遙控是使用的nec協議,即使用pwm來調製傳送的資訊 nec協議,其特徵如下:
1、8位位址和8位指令長度;
2、位址和命令2次傳輸(確保可靠性)
3、pwm脈衝位置調製,以發射紅外載波的占空比代表「0」和「1」;
4、載波頻率為38khz;
5、位時間為1.125ms或2.25ms;
nec碼的位定義:乙個脈衝對應560us的連續載波,乙個邏輯1傳輸需要2.25ms(560us脈衝+1680us低電平),乙個邏輯0的傳輸需要1.125ms(560us脈衝+560us低電平)。而遙控接收頭在收到脈衝的時候為低電平,在沒有脈衝的時候為高電平,這樣,我們在接收頭端收到的訊號為:邏輯1應該是560us低+1680us高,邏輯0應該是560us低+560us高。
nec遙控指令的資料格式為:同步碼頭、位址碼、位址反碼、控制碼、控制反碼。同步碼由乙個9ms的低電平和乙個4.5ms的高電平組成,位址碼、位址反碼、控制碼、控制反碼均是8位資料格式。按照低位在前,高位在後的順序傳送。採用反碼是為了增加傳輸的可靠性(可用於校驗)。
紅外置收頭與stm32連線如上圖所示,既然是pwm調製,很容易想到了stm32的通用定時器的輸入捕獲和輸出比較功能,這裡由於stm32是接收紅外遙控傳送的資訊,所以與紅外置收頭連線的io口要設定位輸入模式,因為在空閒狀態的時候輸入始終要保持高電平,所以要配置成上拉輸入。
rcc->apb2enr|=1<<3;
gpiob->crh&=0xffffff0f;
gpiob->crh|=0x00000080;
gpiob->odr|=1<<9;
因為pb.9是通用定時器的通道四,所以還要對定時器進行配置,額。。。好長時間沒有用定時器了,都忘得差不多了,又得重新拾起來
void time4_init()
rcc->apb1enr|=1<<2;//開啟定時器四的時鐘
tim4->sr=0;//其實復位值就是0,多此一舉了
tim4->dier|=1<<4;//允許定時器四的捕獲中斷
tim4->psc=71;//計數頻率設定為1m cnt每增加一 時間為1us
tim4->arr=10000;//計數器每隔10ms溢位一次
tim4->ccmr2|=1<<8;//cc4通道被配置為輸入,ic4對映在ti4上;
tim4->ccer&=~(1<<13);//通道四配置為上公升沿捕獲
tim4->ccmr2|=3<<12;//進行濾波處理
tim4->ccer|=1<<12;//通道四捕獲使能
tim4->cr1|=1<<0;//定時器四計數使能
因為紅外置收頭接收的訊號第乙個資料必然是同步碼,首先低電平保持9ms,然後乙個跳變,高電平保持4.5ms,而我們判斷接收的資料是邏輯0還是邏輯1,或者是同步碼,都是要根據高電平的持續時間來判定的,所以要關心高電平保持時間,故定時器四初始化時要配置為上公升沿捕獲,好了,定時器也設定好了,接下來該設定定時器四的中斷處理函式啦
對啦,要先把nvic中的tim4中斷開啟
void nvic_init()
nvic->iser[0]|=1<<30;//tim4的中斷編號為30
void tim4_irqhandler(void)
if(tim4->sr&0x10)
if(cs==1)//發生上公升沿捕獲
tim4->cnt=0;
tim4->ccer|=1<<13;
tim4->sr=0;
dcb=1;
if(cs==0)//發生下降沿捕獲
tim4->sr=0;
if(dcb==1)
dcb=0;
temp=tim4->ccr4;
tim4->ccer&=~(1<<13);//改為上公升沿捕獲
if(temp>4200&&temp<4700)
led1=~led1;
ok1=1;
if(ok1==1)
if(temp>1400&&temp<1800)
data=(data<<1);
data|=1<<0;
ray_flag++;
if(temp>300&&temp<800)
data=(data<<1);
data&=~(1<<0);
ray_flag++;
if(ray_flag==32)
ok2=1;
led0=~led0;
if(ray_flag>=32)//nec協議 一次傳送的資料位為32位
ok2=1;
tim4->sr=0;
中斷服務程式配置好了,接下來就是中程式啦
int main()
stm32_clock_init(9);
delay_init(72);
gpio_init();
nvic_init();
time4_init();
usart1_init();
while(1)
if(ok1==1&&ok2==1)
usart1_senddata(temp);
ok1=0;
ok2=0;
ray_flag=0;
使用的是串列埠列印資料,串列埠配置程式就不寫啦
最大的教訓就是 if(temp>4200&&temp<4700)和if(4200
STM32 紅外遙控器
紅外 原理 遙控器作為發射器,發射38khz的載波,接收器在接收到載波時為低電平 按照nec protocol的pwm,該協議的特點 1 8位位址和8位指令長度 2 位址和命令分兩次傳送,並有傳送位址和命令反碼,便於校驗,確保傳輸的準確 3 pwm脈衝位置調製,以發射紅外載波的占空比來表示 0 和 ...
stm32關定時器 STM32定時器TIM3程式
include led.h include delay.h include key.h include sys.h include usart.h include timer.h stm32開發板實驗8 定時器中斷實驗 int main void delay init 延時函式初始化 nvic co...
stm32紅外遙控的外部中斷實現
花了整整兩天時間終於算是基本把紅外解碼搞明白了,其實並不是很難,用了兩天時間,說來慚愧啊,原因就是細節上的問題,不過最終總算找出問題來了。使用外部中斷來解碼,就先對外部中斷進行配置吧 void exti init rcc apb2enr 1 0 使用外部中斷要開afio復用時鐘,因為要用到用到它的暫...