1. 程式人生 > >stm32紅外遙控的外部中斷實現

stm32紅外遙控的外部中斷實現

花了整整兩天時間終於算是基本把紅外解碼搞明白了,其實並不是很難,用了兩天時間,說來慚愧啊,原因就是細節上的問題,不過最終總算找出問題來了。使用外部中斷來解碼,就先對外部中斷進行配置吧

void exti_init()

{

 RCC->APB2ENR|=1<<0;//使用外部中斷要開AFIO複用時鐘,因為要用到用到它的暫存器來選擇出發IO口

 AFIO->EXTICR[2]|=1<<4;//將出發外部中斷的IO配置為PB.9

 EXTI->IMR|=1<<9;//中斷線9的中斷開啟

 EXTI->EMR|=1<<9;//時間也開啟

 EXTI->RTSR|=1<<9;//上升沿出發中斷

}

開始,弄了還幾次程式,發現總是我一個勁的按遙控,訊號燈卻一直不閃爍,我勒個去。原來是把AFIO的EXTICR暫存器給忘了,預設值的出發中斷IO當然是PA口啦,我用的是PB口,所以一定要配置一下啦,也是很久沒有使用外部中斷的緣故吧!老是不用忘了也是正常的!所以要多學多用啊!

PB.9口配置為上拉輸入,不解釋

外部中斷口配置好了,電路也是連線好的,接下來就是中斷服務程式了,中斷服務程式切記儘量不要新增任何延時,不然後果會很麻煩的!切記中斷的作用就是根據外部的環境變化迅速的作出反應,所以時間越短越好,如果做不到這一點,在大的工程中儘量少用,不然除了問題很難找到原因,浪費時間

中斷服務程式如下

void EXTI9_5_IRQHandler(void)

{

 if(EXTI->PR&0x200)//判斷是否是PB.9的邊沿觸發的中斷

 {

  if(CS==1)//發生上升沿捕獲

  {

   EXTI->RTSR&=~(1<<9);

   EXTI->FTSR|=1<<9;//中斷觸發方式改為下降沿

   EXTI->PR|=1<<9;

   dcb=1;//一個數據位要根據高電平的持續時間來判定,故上升沿和下降沿必然是成對出現的

   num=0;//計數清零,開始計時

  }

  if(CS==0)//發生下降沿捕獲

  {

     if(dcb==1)  //判斷之前是否有上升沿

       {

  dcb=0;

  EXTI->RTSR|=1<<9;//改為上升沿捕獲

  EXTI->FTSR&=~(1<<9);

  if(num>210&&num<235)//判定是否為同步碼

  {

   led1=~led1;

   OK1=1;//如果是同步碼 那麼第一把鑰匙就到手啦

  }

  if(OK1==1)//接收到同步碼以後,就可以開始接收資料了

  { 

  if(num>70&&num<90)

  {

data=(data<<1);

data|=1<<0;//邏輯1

ray_flag++;

  }

  if(num>15&&num<40)

  {

data=(data<<1);

data&=~(1<<0);//邏輯0

ray_flag++;

  }

 if(ray_flag==32)//接收到4位元組資料

 {

    OK2=1;//得到第二把鑰匙

led0=~led0;

  }

}

     EXTI->PR|=1<<9;//掛起暫存器清零

  }

   }

 }

 }

服務程式也寫好了,接下來就要寫主程式了

int main()

{

 Stm32_Clock_Init(9);//時鐘初始化

 delay_init(72);//延時初始化

 gpio_init();//IO初始化

 nvic_init();//中斷編號初始化

 exti_init();//外部中斷初始化

 usart1_init();//串列埠初始化

 while(1)

 {

  time();

  if(OK1==1&&OK2==1)//兩把鑰匙都有啦,就可以把接收到的資料打印出來啦

  {

   EXTI->IMR&=~(1<<9);

   OK1=0;

   OK2=0;

   ray_flag=0;

   usart1_senddata(data);

   EXTI->IMR|=1<<9;

  }

 }

}