A. 基於51單片機的紅外遙控開關的C 程序
這個簡單就是一個解碼函靈敏而已!
int jiema()
{
unsigned int data,temp;
RESET:
for( i=0;i<8;i++ ) //**9ms
{
delay_nms(1);
if((PIND&0B00000100)==0B00000100 )
goto RESET; //是檢測在8毫秒內如果出現高電平就退出解碼程序
}
temp = 8000;
while( ( (PIND&0B00000100)==0B00000000 ) && (temp!=0) )
{temp--;}
// 等待4.5ms高電平的到來,避開9毫秒低電平引導脈沖
// temp--需0.25us, temp=8000可實現2ms延時,防止干擾脈沖造成的死機。
delay_nus(1804); //**4.5ms
for( j=0;j<4;j++)
{
for( i=0;i<8;i++ )
{
temp = 4000;
while( ((PIND&0B00000100)==0B00000000 ) && (temp!=0) )
{temp--;}
delay_nus(334);
if((PIND&0B00000100)==0B00000100 ) // 檢測到高電平1的話說明該位為1,延時1毫秒等待脈沖高電平結束
{
data |= (1<<i); // dataH= ~data dataL= data
delay_nus(379);
}
else data &= ~(1<<i); // 檢測到低電平0的話,說明該位為0,繼續檢測下一位
}
IR_BUF[j]=data;
}
if(IR_BUF[2] = ~IR_BUF[3]) //校驗
{
PORTA=IR_BUF[2];
delay_nms(500);
}
B. 單片機做紅外遙控器的問題求教。。。
最簡單的就是通過定時器在P3.2腳輸出38K載波P3.1直接輸出串口數據
接收用3隻腳的紅外接收頭
C. 急需基於51單片機的紅外遙控開關的設計原理圖和程序(c語言版)
/*------------------------------------------------*/
#include<reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
sbit IR=P3^2; //紅外介面標志
#define DataPort P0 //定義數據埠 程序中遇到DataPort 則用P0 替換
sbit DUAN=P2^6;//定義鎖存使能埠 段鎖存
sbit WEI=P2^7;// 位鎖存
/*------------------------------------------------
全局變數聲明
------------------------------------------------*/
unsigned char code dofly_DuanMa[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};// 顯示段碼值0~F
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分別對應相應的數碼管點亮,即位碼
unsigned char TempData[8]; //存儲顯示值的全局變數
unsigned char irtime;//紅外用全局變數
bit irpro_ok,irok;
unsigned char IRcord[4];
unsigned char irdata[33];
/*------------------------------------------------
函數聲明
------------------------------------------------*/
void Ir_work(void);
void Ircordpro(void);
/*------------------------------------------------
顯示函數,用於動態掃描數碼管
輸入參數 FirstBit 表示需要顯示的第一位,如賦值2表示從第三個數碼管開始顯示
如輸入0表示從第一個顯示。
Num表示需要顯示的位數,如需要顯示99兩位數值則該值輸入2
------------------------------------------------*/
void Display(unsigned char FirstBit,unsigned char Num)
{
static unsigned char i=0;
DataPort=0; //清空數據,防止有交替重影
DUAN=1; //段鎖存
DUAN=0;
DataPort=dofly_WeiMa[i+FirstBit]; //取位碼
WEI=1; //位鎖存
WEI=0;
DataPort=TempData[i]; //取顯示數據,段碼
DUAN=1; //段鎖存
DUAN=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; //重新賦值 2ms
TL1=(65536-2000)%256;
Display(0,8); // 調用數碼管掃描
}
/*------------------------------------------------
外部中斷0中斷處理
------------------------------------------------*/
void EX0_ISR (void) interrupt 0 //外部中斷0服務函數
{
static unsigned char 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;
}
}
/*------------------------------------------------
定時器0初始化
------------------------------------------------*/
void TIM0init(void)//定時器0初始化
{
TMOD=0x02;//定時器0工作方式2,TH0是重裝值,TL0是初值
TH0=0x00; //重載值
TL0=0x00; //初始化值
ET0=1; //開中斷
TR0=1;
}
/*------------------------------------------------
定時器初始化子程序
------------------------------------------------*/
void Init_Timer1(void)
{
TMOD |= 0x01; //使用模式1,16位定時器,使用"|"符號可以在使用多個定時器時不受影響
//TH1=0x00; //給定初值
//TL1=0x00;
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]=dofly_DuanMa[IRcord[0]/16];
TempData[1]=dofly_DuanMa[IRcord[0]%16];
TempData[2]=dofly_DuanMa[IRcord[1]/16];
TempData[3]=dofly_DuanMa[IRcord[1]%16];
TempData[4]=dofly_DuanMa[IRcord[2]/16];
TempData[5]=dofly_DuanMa[IRcord[2]%16];
TempData[6]=dofly_DuanMa[IRcord[3]/16];
TempData[7]=dofly_DuanMa[IRcord[3]%16];
//Display(0,8); // 調用數碼管掃描
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++;
}
IRcord[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();
}
}
}
51P3^2是外部中斷,紅外接收管接這個引腳就能接收到數據然後顯示在數碼管上
D. 求助:基於單片機的遙控開關設計
遙控開關很簡單的,如果要從單片機重新來進行設計還不如直接購買專業晶元RFE272來直接設計,而且成本低、技術更可靠,功耗更低。
如果一定要自己設計,那麼可以採用EV1527、SC2260之類的晶元作為發射編碼晶元。接電路可以採用SYN480晶元,解碼晶元可以採用單片機編程來解碼,或直接採用專業的新型的無線遙控解碼晶元RFE272。此晶元可以解碼EV1527、PT2262、PT2260、SC2260、HS1527等晶元的編碼。下圖供你參考: