51微控制器紅外接收

鈔尨小哥哥發表於2020-11-03

嘿嘿好久不見哦,從開學就一直很忙,最近又參加了一個比賽哈哈,這次就分享一下我最近學的微控制器紅外這塊吧

紅外線(Infrared–>IR):頻率介於微波與可見光之間的電磁波,波長在0.76um-1.5nm之間,來傳輸訊號,是不可見光

在這裡插入圖片描述
這個帶鎧甲的就是一種紅外接收頭(鐵皮封裝式哈)
在這裡插入圖片描述
在這裡插入圖片描述
這個跟發光二極體很像的燈就是紅外發射管啦
在這裡插入圖片描述
在這裡插入圖片描述
為了使訊號更好的被髮送出去,經常會將二進位制資料訊號調製為脈衝訊號,通過紅外發射管發射

兩種脈衝調製技術(二進位制編碼技術):PPM和PWM
PPM:通過脈衝串之間的時間間隔來實現訊號調製(脈時調製)
PWM:利用脈衝寬度來實現訊號調製(脈寬調製)
區別:一個是利用兩脈衝之間的寬度來確定是訊號1還是訊號0;另一種則是利用高低電平的持續時間來確定

通常紅外遙控為了提高抗干擾效能和降低電源消耗,常使用載波的方式傳送二進位制編碼
常用的載波頻率:38hz(這是由發射端使用的455khz晶振來決定的,在發射端要對晶振進行整數分頻,分頻係數一般會取12–>455/12=38)
紅外遙控器是將遙控訊號(二進位制脈衝碼)調製在38khz的載波上,經緩衝放大後由紅外發射管發射
紅外接收器是將遙控發射來的紅外光訊號轉換為電訊號,在進行整流,限幅,檢波,整形,形成指令脈衝,輸出至遙控微處理器
紅外發射接收電路圖(手繪哈哈)
在這裡插入圖片描述
結論:發射1–>接收為0;發射0–>接收為1
紅外資料碼的格式:起始碼–>使用者碼>使用者碼>資料碼>資料反碼(編碼為4個位元組,共32位)
在這裡插入圖片描述
脈時調製(PPM):
在這裡插入圖片描述
結論:位0:低電平時間:0.56ms,高電平時間0.56ms
位1:低電平時間:0.56ms,高電平時間1.69ms
所以我們就可以利用時間來判斷它是位1還是位0
C51程式碼:

/*-----------------------------------------------
  名稱:遙控器紅外解碼數碼管顯示
  日期:2020.11.1
  內容:8位數碼管顯示:使用者碼,使用者碼,資料碼,資料反碼
------------------------------------------------*/
#include<reg52.h>    //包含標頭檔案,一般情況不需要改動,標頭檔案包含特殊功能暫存器的定義

sbit IR=P3^2;  //紅外介面標誌

#define DataPort P0 //定義資料埠 程式中遇到DataPort 則用P0 替換
sbit LATCH1=P2^2;//定義鎖存使能埠 段鎖存
sbit LATCH2=P2^3;//               位鎖存
/*------------------------------------------------
                全域性變數宣告
------------------------------------------------*/

unsigned char code DuanMa[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};// 顯示段碼值
unsigned char code WeiMa[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//顯示位碼

unsigned char TempData[8];//儲存顯示值的全域性變數
unsigned char  irtime;//紅外用全域性變數
unsigned char IRcode[4];
unsigned char irdata[33];

bit irpro_ok,irok;

/*------------------------------------------------
                  函式宣告
------------------------------------------------*/

void Ir_work(void);
void Ircordpro(void);

/*------------------------------------------------
                 顯示函式:動態顯示數碼管
------------------------------------------------*/
void Display(unsigned char FirstBit,unsigned char Num)
{
	static unsigned char i=0;
	DataPort=0;	//清空資料,防止重影
	LATCH1=1;  	//段鎖存
	LATCH1=0;

	DataPort=WeiMa[i+FirstBit];
	LATCH2=1;	//位鎖存
	LATCH2=0;

	DataPort=TempData[i];//取顯示資料,段碼
	LATCH1=1;	//段鎖存
	LATCH1=0;

	i++;
	if(i==Num)
		i=0;
}
/*------------------------------------------------
                  定時器0中斷處理
------------------------------------------------*/

void tim0_isr (void) interrupt 1 using 1
{
  irtime++;  //用於計數2個下降沿之間的時間
}

/*------------------------------------------------
                  定時器中斷子程式
------------------------------------------------*/
void Timer1_isr (void) interrupt 3
{
	TH1=(65536-2000)/256;	 //重新賦初值2us
	TL1=(65536-2000)%256;
	Display(0,8);	//呼叫數碼管掃描
}
/*------------------------------------------------
                  外部中斷0中斷處理
------------------------------------------------*/
void EX0_ISR (void) interrupt 0 //外部中斷0服務函式
{
  static unsigned char  i;             //接收紅外訊號處理
  static bit startflag=0;                //是否開始處理標誌位

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;
				 startflag=0;
	  			}
          }
  	 else 	//第一個下降沿進入中斷執行此處
		{
		irtime=0;
		startflag=1;
		}
}

/*------------------------------------------------
                定時器0初始化
------------------------------------------------*/
void TIM0init(void)//定時器0初始化
{

  TMOD=0x02;//定時器0工作方式2,TH0是重灌值,TL0是初值
  TH0=0x00; //過載值
  TL0=0x00; //初始化值
  ET0=1;    //開中斷
  TR0=1;    
}

/*------------------------------------------------
                定時器初始化子程式
------------------------------------------------*/
void Init_Timer1(void)//定時器0初始化
{

  TMOD |=0x01;//定時器0工作方式1
  EA=1;//開總中斷
  ET1=1;//開定時器中斷
  TR1=1;// 開定時器   
}
/*------------------------------------------------
                  外部中斷0初始化
------------------------------------------------*/
void EX0init(void)
{
 IT0 = 1;   //指定外部中斷0下降沿觸發,INT0 (P3.2)
 EX0 = 1;   //使能外部中斷
 EA = 1;    //開總中斷
}
/*------------------------------------------------
                  鍵值處理
------------------------------------------------*/

void Ir_work(void)//紅外來鍵值散轉程式
{
	TempData[0]=DuanMa[IRcode[0]/16];
	TempData[1]=DuanMa[IRcode[0]%16];
	TempData[2]=DuanMa[IRcode[1]/16];
	TempData[3]=DuanMa[IRcode[1]%16];
	TempData[4]=DuanMa[IRcode[2]/16];
	TempData[5]=DuanMa[IRcode[2]%16];
	TempData[6]=DuanMa[IRcode[3]/16];
	TempData[7]=DuanMa[IRcode[3]%16];
	irpro_ok=0;//處理完成標誌
}
/*------------------------------------------------
                紅外碼值處理
------------------------------------------------*/
void Ircordpro(void)//紅外碼值處理函式
{ 
  unsigned char i, j, k;
  unsigned char 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++;
         }
     IRcode[i]=value;
     value=0;     
     } 
	 irpro_ok=1;//處理完畢標誌位置1
}

/*------------------------------------------------
                    主函式
------------------------------------------------*/
void main(void)
{
	EX0init(); //初始化外部中斷
 	TIM0init();//初始化定時器
	Init_Timer1();

	while(1)//主迴圈
   	{
    	if(irok)                        //如果接收好了進行紅外處理
	  	{   
	   		Ircordpro();
 	   		irok=0;
	  	}

    	if(irpro_ok)                   //如果處理好後進行工作處理,如按對應的按鍵後顯示對應的數字等
	  	{
	   		Ir_work();
  	  	}
   	}
}

現象:00FF:使用者碼,4Ab5:資料碼和資料反碼
在這裡插入圖片描述
好睏啊,發射那就下次再聊嘍,晚安,一起加油
在這裡插入圖片描述
再給你們康康我的ipad殼殼吧(雖然ipad還沒到哈哈)
good night
在這裡插入圖片描述

相關文章