外部中斷(紅外通信)

以前用來紅外通信控制小車的程序

typedef unsigned char UCHAR8;
/* 
    初始化 指定下降沿觸發 
    1 產生外部中斷
    2 IRTime 對下降沿計數 將脈衝時序信號轉爲長度
      接收完成(irok==1)後,進行紅外處理 Ircordpro() 將脈衝的長度轉爲編碼值 >7 0 <7 1.一共32位四字節。
    3 碼值處理
      紅外處理好(irpro_ok==1)後,把遙控器按下的編碼轉換爲對應的數字  如 fd03(fd前03後互補fd+03=256) 代表遙控器的暫停播放
    4 鍵值處理
 */
sbit IR=P3^2;  //紅外接口標誌 外部中斷
bit irpro_ok,irok;
UCHAR8 IRcord[4];
UCHAR8 irdata[33];
while(1)//主循環
{
    if(irok)             //如果接收好了進行紅外處理
    {   
        Ircordpro();
        irok=0;
    }
 
    if(irpro_ok)         //如果處理好後進行工作處理,如按對應的按鍵後顯示對應的數字等 如 fd03(fd前03後互補fd+03=256) 代表遙控器的暫停播放
    {
        Ir_work();
    }
}
/*-----外部中斷0初始化----------*/
void EX0init(void)
{
    IT0 = 1;   //指定外部中斷0下降沿觸發,INT0 (P3.2)
    EX0 = 1;   //使能外部中斷
    EA = 1;    //開總中斷
}
void tim0_isr (void) interrupt 1 using 1
{
    irtime++;  //用於計數2個下降沿之間的時間
}
/*------外部中斷0中斷處理----------*/
 
void EX0_ISR (void) interrupt 0 //外部中斷0服務函數 interrupt 2 外部中斷1
{
    static UCHAR8  i;             //接收紅外信號處理
    static bit startflag;                //是否開始處理標誌位
 
    if(startflag)                         
    {
        if(irtime<63&&irtime>=33)//引導碼 TC9012的頭碼,9ms+4.5ms
            i=0;
        irdata[i]=irtime;//存儲每個電平的持續時間,用於以後判斷是0還是1
        irtime=0;
        i++;
        if(i==33)
        {
            irok=1;
            i=0;
        }
    }
    else
    {
        irtime=0;
        startflag=1;
    }
 
}
/*------鍵值處理----------*/
 
void Ir_work(void)
{
    switch(IRcord[2])
    {
        case 0x45:direct(0);break;//停止    
        case 0x40:direct(1);break;//向前
        case 0x19:direct(2);break;//向後
        case 0x07:direct(3);break;//左轉
        case 0x09:direct(4);break;//右轉
        case 0x0C:PWMper=10;LCD_Write_String(9,1,"1");break;//PWM : 10%
        case 0x18:PWMper=20;LCD_Write_String(9,1,"2");break;//PWM : 20%
        case 0x5E:PWMper=30;LCD_Write_String(9,1,"3");break;//PWM : 30%
        case 0x08:PWMper=40;LCD_Write_String(9,1,"4");break;//PWM : 40%
        case 0x1C:PWMper=50;LCD_Write_String(9,1,"5");break;//PWM : 50%
        case 0x5A:PWMper=60;LCD_Write_String(9,1,"6");break;//PWM : 60%
        case 0x42:PWMper=70;LCD_Write_String(9,1,"7");break;//PWM : 70%
        case 0x52:PWMper=80;LCD_Write_String(9,1,"8");break;//PWM : 80%
        case 0x4A:PWMper=90;LCD_Write_String(9,1,"9");break;//PWM : 90%
        default:break;
    };
        
        
       irpro_ok=0;//處理完成標誌
 
  }
/*-----紅外碼值處理--------*/
 
void Ircordpro(void)//紅外碼值處理函數
{ 
    UCHAR8 i, j, k;
    UCHAR8 cord,value;
 
    k=1;
    for(i=0;i<4;i++)      //處理4個字節
    {
        for(j=1;j<=8;j++) //處理1個字節8位
        {
            cord=irdata[k];
            if(cord>7)//大於某值爲1,這個和晶振有絕對關係,這裏使用12M計算,此值可以有一定誤差
                value|=0x80;
            if(j<8)
            {
                value>>=1;
            }
            k++;
        }
    IRcord[i]=value;
    value=0;     
    } 
     irpro_ok=1;//處理完畢標誌位置1
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章