單片機常用芯片系列(三)——紅外通信

在這裏插入圖片描述在這裏插入圖片描述就是反碼,寫代碼的時候反過來即可
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述其中前16位爲用戶識別碼,能區別不同的紅外遙控設備,以防止不同的機種遙控碼互相干擾。後16位爲8位的操作碼和8位的操作反碼,用於覈對數據是否接收準確。收端根據數據碼做出應該執行上面動作的判斷。



#include "uart.h"			 //此文件中定義了單片機的一些特殊功能寄存器
	

typedef unsigned int u16;	  //對數據類型進行聲明定義
typedef unsigned char u8;

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

sbit IRIN=P3^2;

u8 IrValue[6];
u8 Time;


/*******************************************************************************
* 函 數 名         : delay
* 函數功能		   : 延時函數,i=1時,大約延時10us
*******************************************************************************/
void delay(u16 i)
{
	while(i--);	
}


/*******************************************************************************
* 函數名         : IrInit()
* 函數功能		   : 初始化紅外線接收
* 輸入           : 無
* 輸出         	 : 無
*******************************************************************************/

void IrInit()
{
	IT0=1;//下降沿觸發
	EX0=1;//打開中斷0允許
	EA=1;	//打開總中斷

	IRIN=1;//初始化端口
}


/*******************************************************************************
* 函 數 名       : main
* 函數功能		 : 主函數
* 輸    入       : 無
* 輸    出    	 : 無
*******************************************************************************/
void main()
{	
	IrInit();
	delay(50000);
	uart_init();
	while(1)
	{	
		uart_send_byte(0);
		uart_send_byte(IrValue[2]);
		delay(50000);
	}		
}

/*******************************************************************************
* 函數名         : ReadIr()
* 函數功能		   : 讀取紅外數值的中斷函數
* 輸入           : 無
* 輸出         	 : 無
*******************************************************************************/

void ReadIr() interrupt 0
{
	u8 j,k;
	u16 err;
	Time=0;					 
	delay(700);	//7ms
	if(IRIN==0)		//確認是否真的接收到正確的信號
	{	 
		
		err=1000;				//1000*10us=10ms,超過說明接收到錯誤的信號
		while((IRIN==0)&&(err>0))	//等待前面9ms的低電平過去  		
		{			
			delay(1);
			err--;
		} 
		if(IRIN==1)			//如果正確等到9ms低電平
		{
			err=500;
			while((IRIN==1)&&(err>0))		 //等待4.5ms的起始高電平過去
			{ 
				delay(1);
				err--;
			}
			for(k=0;k<4;k++)		//共有4組數據
			{				
				for(j=0;j<8;j++)	//接收一組數據
				{

					err=60;		
					while((IRIN==0)&&(err>0))//等待信號前面的560us低電平過去
					{
						delay(1);
						err--;
					}
					err=500;
					while((IRIN==1)&&(err>0))	 //計算高電平的時間長度。
					{
						delay(10);	 //0.1ms
						Time++;
						err--;
						if(Time>30)
						{
							return;
						}
					}
					IrValue[k]>>=1;	 //k表示第幾組數據
					if(Time>=8)			//如果高電平出現大於565us,那麼是1
					{
						IrValue[k]|=0x80;
					}
					Time=0;		//用完時間要重新賦值							
				}
			}
		}
		if(IrValue[2]!=~IrValue[3])
		{
			return;
		}
	}			
}

#include "uart.h"


// 串口設置爲: 波特率9600、數據位8、停止位1、奇偶校驗無
// 使用的晶振是11.0592MHz的,注意12MHz和24MHz的不行
void uart_init(void)
{
	// 波特率9600
	SCON=0X50;			//設置爲工作方式1
	TMOD=0X20;			//設置計數器工作方式2
	PCON=0X80;			//波特率加倍
	TH1=0XF3;				//計數器初始值設置,注意波特率是4800的
	TL1=0XF3;
	//ES=1;						//打開接收中斷
	//EA=1;						//打開總中斷
	TR1=1;
}

// 通過串口發送1個字節出去
void uart_send_byte(unsigned char c)
{
   // 第1步,發送一個字節
   SBUF = c;

   // 第2步,先確認串口發送部分沒有在忙
   while (!TI);

   // 第3步,軟件復位TI標誌位
   TI = 0;
}

void uart_send_sentence(unsigned char *sen)
{
	while(*sen!='\0')
	{
		uart_send_byte(*sen);
		sen++;
	}
}
#ifndef __UART_H__
#define __UART_H__

#include <reg51.h>





void uart_init(void);
void uart_send_byte(unsigned char c);
void uart_send_sentence(unsigned char *sen);




#endif



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