以下是紅外線遠程控制密碼鎖的程序,還有一個是用遙控器的程序么有附上來,你可以選擇自帶的遙控器,或者選擇自己做。以下代碼是我可以直接使用的,請注意職業道德,尊重原創。
如果圖不是很清晰的話可以在這里下載pdf文檔,下載地址:**[紅外線遠程控制密碼鎖](http://download.csdn.net/detail/qq_21792169/9248979)**

本源碼是網絡人VS灰鴿子的一個朋友所寫,在這里分享出來希望能夠給大家有一定引導性的作用,不要直接復制,這樣對你的學習是沒有幫助的,希望大家還是堅持把代碼看下來,這樣我相信你會學到更多
~~~
#include <REG52.h>
#include<intrins.h>
#define LCM_Data ?P0
#define uchar unsigned char?
#define uint ?unsigned int
//#define w 6//定義密碼位數
//時間計算
#define Imax 14000 ? ?//此處為晶振為11.0592時的取值,?
#define Imin 8000 ? ?//如用其它頻率的晶振時,
#define Inum1 1450 ? ?//要改變相應的取值。
#define Inum2 700?
#define Inum3 3000
sbit lcd1602_rs=P2^5;
sbit lcd1602_rw=P2^6;
sbit lcd1602_en=P2^7;
sbit Scl=P3^4;//24C02串行時鐘
sbit Sda=P3^5;//24C02串行數據
sbit ALAM = P2^1;//報警
sbit KEY = P3^6;//開鎖
sbit open_led=P2^2;//開鎖指示燈
bit ?operation=0;//操作標志位
bit ?pass=0;//密碼正確標志
bit ?ReInputEn=0;//重置輸入充許標志
bit ?s3_keydown=0;//3秒按鍵標志位
bit ?key_disable=0;//鎖定鍵盤標志
unsigned char countt0,second;//t0中斷計數器,秒計數器
//解碼變量
unsigned char Im[4]={0x00,0x00,0x00,0x00};
//全局變量
uchar f;
unsigned char m,Tc;
unsigned char IrOK;
//void Delay5Ms(void);
unsigned char code a[]={0xFE,0xFD,0xFB,0xF7}; //控盤掃描控制表
unsigned char code start_line[]= {"password: ? ? ? "};
unsigned char code name[] = {"===Coded Lock==="};//顯示名稱
unsigned char code Correct[] = {" ? ? correct ? ?"};//輸入正確
unsigned char code Error[] ? = {" ? ? ?error ? ? "}; ?//輸入錯誤
unsigned char code codepass[]= {" ? ? ?pass ? ? ?"};?
unsigned char code LockOpen[]= {" ? ? ?open ? ? ?"};//OPEN
unsigned char code SetNew[] = {"SetNewWordEnable"};
unsigned char code Input[] ? = {"input: ? ? ? ? ?"};//INPUT
unsigned char code ResetOK[] = {"ResetPasswordOK "};
unsigned char code initword[]= {"Init password..."};
unsigned char code Er_try[]= {"error,try again!"};
unsigned char code again[]= {"input again ? ? "};
unsigned char InputData[6];//輸入密碼暫存區
unsigned char CurrentPassword[6]={1,3,1,4,2,0}; //當前密碼值
unsigned char TempPassword[6];
unsigned char N=0;//密碼輸入位數記數
unsigned char ErrorCont;//錯誤次數計數
unsigned char CorrectCont;//正確輸入計數
unsigned char ReInputCont; //重新輸入計數
unsigned char code initpassword[6]={0,0,0,0,0,0};
//=====================5ms延時==============================
void Delay5Ms()
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}
//===================400ms延時==============================
void Delay400Ms()
{
?unsigned char TempCycA = 5;
?unsigned int TempCycB;
?while(TempCycA--)
?{
? TempCycB=7269;
? while(TempCycB--);
?}
}
//=============================================================================================
//================================24C02========================================================
//=============================================================================================
void mDelay(uint t) //延時
{?
uchar i;
? ?while(t--)
? ?{
? ?for(i=0;i<125;i++)
? ?{;}
? ?}
}
? ?
void Nop()?//空操作
{
?_nop_();
?_nop_();
?_nop_();
?_nop_();
}
/*起始條件*/
void Start(void)
{
?Sda=1;
?Scl=1;
?Nop();
?Sda=0;
?Nop();
}
?/*停止條件*/
void Stop(void)
{
?Sda=0;
?Scl=1;
?Nop();
?Sda=1;
?Nop();
}
/*應答位*/
void Ack(void)
{
Sda=0;
Nop();
Scl=1;
Nop();
Scl=0;
}
/*反向應答位*/
void NoAck(void)
{
?Sda=1;
?Nop();
?Scl=1;
?Nop();
?Scl=0;
}
?/*發送數據子程序,Data為要求發送的數據*/
void Send(uchar Data)
{
? ?uchar BitCounter=8;
? ?uchar temp;
? ?do
? ?{
? ?temp=Data;
? ?Scl=0;
? ?Nop();
? ?if((temp&0x80)==0x80)
? ?Sda=1;
? ?else?
? ?Sda=0;
? ?Scl=1;
? ?temp=Data<<1;
? ?Data=temp;
? ?BitCounter--;
? ?}
? ?while(BitCounter);
? ?Scl=0;
}
/*讀一字節的數據,并返回該字節值*/
uchar Read()
{
? ? uchar temp=0;
uchar temp1=0;
uchar BitCounter=8;
Sda=1;
do{
Scl=0;
Nop();
Scl=1;
Nop();
if(Sda)
temp=temp|0x01;
else
temp=temp&0xfe;
if(BitCounter-1)
{
temp1=temp<<1;
temp=temp1;
}
BitCounter--;
}
while(BitCounter);
return(temp);
}
void WrToROM(uchar Data[],uchar Address,uchar Num)
{
? uchar i;
? uchar *PData;
? PData=Data;
? for(i=0;i<Num;i++)
? {
? Start();
? Send(0xa0);
? Ack();
? Send(Address+i);
? Ack();
? Send(*(PData+i));
? Ack();
? Stop();
? mDelay(20);
? }
}
void RdFromROM(uchar Data[],uchar Address,uchar Num)
{
? uchar i;
? uchar *PData;
? PData=Data;
? for(i=0;i<Num;i++)
? {
? Start();
? Send(0xa0);
? Ack();
? Send(Address+i);
? Ack();
? Start();
? Send(0xa1);
? Ack();
? *(PData+i)=Read();
? Scl=0;
? NoAck();
? Stop();
? }
}
//==================================================================================================
//=======================================LCD1602====================================================
//==================================================================================================
#define yi 0x80 //LCD第一行的初始位置,因為LCD1602字符地址首位D7恒定為1(100000000=80)
#define er 0x80+0x40 //LCD第二行初始位置(因為第二行第一個字符位置地址是0x40)
//----------------延時函數,后面經常調用----------------------
void delay(uint xms)//延時函數,有參函數
{
uint x,y;
for(x=xms;x>0;x--)
for(y=110;y>0;y--);
}
//--------------------------寫指令---------------------------
void write_1602com(uchar com)//****液晶寫入指令函數****
{
lcd1602_rs=0;//數據/指令選擇置為指令
lcd1602_rw=0; //讀寫選擇置為寫
P0=com;//送入數據
delay(1);
lcd1602_en=1;//拉高使能端,為制造有效的下降沿做準備
delay(1);
lcd1602_en=0;//en由高變低,產生下降沿,液晶執行命令
}
//-------------------------寫數據-----------------------------
void write_1602dat(uchar dat)//***液晶寫入數據函數****
{
lcd1602_rs=1;//數據/指令選擇置為數據
lcd1602_rw=0; //讀寫選擇置為寫
P0=dat;//送入數據
delay(1);
lcd1602_en=1; //en置高電平,為制造下降沿做準備
delay(1);
lcd1602_en=0; //en由高變低,產生下降沿,液晶執行命令
}
//-------------------------初始化-------------------------
void lcd_init()
{
write_1602com(0x01);//清顯示
write_1602com(0x38);//設置液晶工作模式,意思:16*2行顯示,5*7點陣,8位數據
write_1602com(0x0c);//開顯示不顯示光標
write_1602com(0x06);//整屏不移動,光標自動右移
}
//========================================================================================
//=========================================================================================
//==============將按鍵值編碼為數值=========================
unsigned char coding(unsigned char m1,unsigned char hh)?
{
unsigned char k;
if(IrOK==1)
{
IrOK=0;
switch(m1)
{
case (0x0c): k=1;break;
case (0x18): k=2;break;
case (0x5e): k=3;break;
//case (0xff): k='A';break;//
case (0x08): k=4;break;
case (0x1c): k=5;break;
case (0x5a): k=6;break;
//case (0x82): k='B';break;? //
case (0x42): k=7;break;
case (0x52): k=8;break;
case (0x4a): k=9;break;
//case (0x84): k='C';break;//
case (0x43): k='*';break;?//撤銷
case (0x16): k=0;break;
case (0x15): k='#';break;? //確認鍵
case (0x0d): k='D';break;? //重設密碼
case (0x45): k='A';break;//
case (0x47): k='A';break;//
case (0x44): k='A';break;//
case (0x40): k='A';break;//
case (0x07): k='A';break;//
case (0x09): k='A';break;//
case (0x19): k='A';break;//
//default:;
}
}
else
{
switch(hh)
{
case (0x11): k=1;break;
case (0x21): k=2;break;
case (0x41): k=3;break;
case (0x81): k='A';break;
case (0x12): k=4;break;
case (0x22): k=5;break;
case (0x42): k=6;break;
case (0x82): k='B';break;
case (0x14): k=7;break;
case (0x24): k=8;break;
case (0x44): k=9;break;
case (0x84): k='C';break;
case (0x18): k='*';break;
case (0x28): k=0;break;
case (0x48): k='#';break;
case (0x88): k='D';break;
//default:;
}
}
return(k);
}
//=====================按鍵檢測并返回按鍵值===============================
unsigned char keynum()
{
?unsigned char row,col,i;
?P1=0xf0;
?if((P1&0xf0)!=0xf0)
?{
? Delay5Ms();
? ? ? ? Delay5Ms();
? ?if((P1&0xf0)!=0xf0)
{
? ? row=P1^0xf0; ? ? ? ? ?//確定行線
i=0;
P1=a[i];? ? ? ? ?//精確定位
while(i<4)
{
if((P1&0xf0)!=0xf0)
?{
? col=~(P1&0xff);?//確定列線
? break; ? ? ? ? ? ?//已定位后提前退出 ??
?}
else?
?{
? i++;
? P1=a[i];
?}
}
}
else?
{
return 0;
}
while((P1&0xf0)!=0xf0);
return (row|col);//行線與列線組合后返回
?}
?else return 0;? ? ? ?//無鍵按下時返回0
}
//=======================一聲提示音,表示有效輸入========================
void OneAlam()
{
ALAM=0;
Delay5Ms();
? ? ALAM=1;
}
//========================二聲提示音,表示操作成功========================
void TwoAlam()
{
ALAM=0;
Delay5Ms();
? ? ALAM=1;
? ? Delay5Ms();
ALAM=0;
Delay5Ms();
? ? ALAM=1;
}
//========================三聲提示音,表示錯誤========================
void ThreeAlam()
{
ALAM=0;
Delay5Ms();
? ? ALAM=1;
? ? Delay5Ms();
ALAM=0;
Delay5Ms();
? ? ALAM=1;
? ? Delay5Ms();
ALAM=0;
Delay5Ms();
? ? ALAM=1;
}
//=====================顯示輸入的N個數字,用H代替以便隱藏============================
void DisplayOne()
{
//DisplayOneChar(9+N,1,'*');
write_1602com(yi+5+N);
write_1602dat('*');
}
//=======================顯示提示輸入=========================
void DisplayChar()
{
unsigned char i;
if(pass==1)
{
//DisplayListChar(0,1,LockOpen);
write_1602com(er);
for(i=0;i<16;i++)
{
write_1602dat(LockOpen[i]);
}
}
else
{
if(N==0)
{
//DisplayListChar(0,1,Error);
write_1602com(er);
for(i=0;i<16;i++)
{
write_1602dat(Error[i]);
}
}
else
{
//DisplayListChar(0,1,start_line);
write_1602com(er);
for(i=0;i<16;i++)
{
write_1602dat(start_line[i]);
}
}
}
}
void DisplayInput()
{
unsigned char i;
if(CorrectCont==1)
{
//DisplayListChar(0,0,Input);
write_1602com(er);
for(i=0;i<16;i++)
{
write_1602dat(Input[i]);
}
}
}
//========================重置密碼==================================================
//==================================================================================
void ResetPassword()
{
unsigned char i;
unsigned char j;
if(pass==0)
{
pass=0;
DisplayChar();
ThreeAlam();
}
else
{
? ? if(ReInputEn==1)
{
if(N==6)
{
ReInputCont++;
if(ReInputCont==2)
{
for(i=0;i<6;)
{
if(TempPassword[i]==InputData[i])//將兩次輸入的新密碼作對比
i++;
else
{
//DisplayListChar(0,1,Error);
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(Error[j]);
}
ThreeAlam();//錯誤提示
pass=0;
ReInputEn=0;//關閉重置功能,
ReInputCont=0;
DisplayChar();
break;
}
}?
if(i==6)
{
//DisplayListChar(0,1,ResetOK);
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(ResetOK[j]);
}
TwoAlam();//操作成功提示
WrToROM(TempPassword,0,6);//將新密碼寫入24C02存儲
ReInputEn=0;
}
ReInputCont=0;
CorrectCont=0;
}
else
{
OneAlam();
//DisplayListChar(0, 1, again); //顯示再次輸入一次
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(again[j]);
}
for(i=0;i<6;i++)
{
TempPassword[i]=InputData[i];//將第一次輸入的數據暫存起來
}
}
N=0;//輸入數據位數計數器清零
? }
? ?}
}
}
//=======================輸入密碼錯誤超過三過,報警并鎖死鍵盤======================
void Alam_KeyUnable()
{
P1=0x00;
{
ALAM=~ALAM;
Delay5Ms();
}
}
//=======================取消所有操作============================================
void Cancel()
{
unsigned char i;
unsigned char j;
//DisplayListChar(0, 1, start_line);?
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(start_line[j]);
}
TwoAlam();//提示音
for(i=0;i<6;i++)
{
InputData[i]=0;
}
KEY=1;//關閉鎖
ALAM=1;//報警關
operation=0;//操作標志位清零
pass=0;//密碼正確標志清零
ReInputEn=0;//重置輸入充許標志清零
//ErrorCont=0;//密碼錯誤輸入次數清零
CorrectCont=0;//密碼正確輸入次數清零
ReInputCont=0;//重置密碼輸入次數清零?
open_led=1;
s3_keydown=0;
key_disable=0;
N=0;//輸入位數計數器清零
}
//==========================確認鍵,并通過相應標志位執行相應功能===============================
void Ensure()
{
unsigned char i,j;
RdFromROM(CurrentPassword,0,6); //從24C02里讀出存儲密碼
? ? if(N==6)
{
? ?if(ReInputEn==0)//重置密碼功能未開啟
{
for(i=0;i<6;)
? ?{
if(CurrentPassword[i]==InputData[i])
{
i++;
}
else?
{
i=7;
ErrorCont++;
if(ErrorCont>=3&&KEY==1)//錯誤輸入計數達三次時,報警并鎖定鍵盤
{
write_1602com(er);
for(i=0;i<16;i++)
{
write_1602dat(Error[i]);
}
Alam_KeyUnable();
TR0=1;//開啟定時
key_disable=1;//鎖定鍵盤
pass=0;
break;
}
} ?
}
if(i==6)
{
CorrectCont++;
if(CorrectCont==1)//正確輸入計數,當只有一次正確輸入時,開鎖,
{
//DisplayListChar(0,1,LockOpen);
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(LockOpen[j]);
}
TwoAlam();//操作成功提示音
ErrorCont=0;
KEY=0;//開鎖
pass=1;//置正確標志位
TR0=1;//開啟定時
open_led=0;//開鎖指示燈亮
for(j=0;j<6;j++)//將輸入清除
{
InputData[i]=0;
}
}
else//當兩次正確輸入時,開啟重置密碼功能
{
//DisplayListChar(0,1,SetNew);
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(SetNew[j]);
}
TwoAlam();? ?//操作成功提示
ReInputEn=1;//允許重置密碼輸入
CorrectCont=0;//正確計數器清零
}
?}
else//=========================當第一次使用或忘記密碼時可以用131420對其密碼初始化============
{
if((InputData[0]==1)&&(InputData[1]==3)&&(InputData[2]==1)&&(InputData[3]==4)&&(InputData[4]==2)&&(InputData[5]==0))
?{
WrToROM(initpassword,0,6); //強制將初始密碼寫入24C02存儲
//DisplayListChar(0,1,initword);//顯示初始化密碼
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(initword[j]);
}
TwoAlam();
Delay400Ms();
TwoAlam();
N=0;
}
else
{
//DisplayListChar(0,1,Error);
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(Error[j]);
}
?ThreeAlam();//錯誤提示音
pass=0;
}
}
}
else//當已經開啟重置密碼功能時,而按下開鎖鍵,
{
//DisplayListChar(0,1,Er_try);
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(Er_try[j]);
}
ThreeAlam();
}
}
else
{
//DisplayListChar(0,1,Error);
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(Error[j]);
}
?ThreeAlam();//錯誤提示音
pass=0;
}
N=0;//將輸入數據計數器清零,為下一次輸入作準備
operation=1;
}
//==============================主函數===============================
void main()
{
?unsigned char KEY,NUM;
unsigned char i,j;
?P1=0xFF;?
EA=1;
TMOD=0x11;
IT1=1;//下降沿有效
EX1=1;//外部中斷1開
??
TH0=0;//T0賦初值
TL0=0;
TR0=0;//t0開始計時
?TL1=0xB0;
?TH1=0x3C;
?ET1=1;
?TR1=0;
?Delay400Ms(); //啟動等待,等LCM講入工作狀態
?lcd_init(); //LCD初始化
write_1602com(yi);//日歷顯示固定符號從第一行第0個位置之后開始顯示
for(i=0;i<16;i++)
{
write_1602dat(name[i]);//向液晶屏寫日歷顯示的固定符號部分
}
write_1602com(er);//時間顯示固定符號寫入位置,從第2個位置后開始顯示
for(i=0;i<16;i++)
{
write_1602dat(start_line[i]);//寫顯示時間固定符號,兩個冒號
}
write_1602com(er+9);//設置光標位置
write_1602com(0x0f);//設置光標為閃爍
?Delay5Ms(); //延時片刻(可不要)
?N=0;//初始化數據輸入位數
?while(1)
?{
if(key_disable==1)
Alam_KeyUnable();
else
ALAM=1;//關報警
KEY=keynum();
if(KEY!=0||IrOK==1)
{
if(key_disable==1)
{
second=0;
}
else
{
NUM=coding(Im[2],KEY);
{
switch(NUM)
{
case ('A'): ;break;
case ('B'):; ? ? break;
case ('C'): ;break;
case ('D'): ResetPassword();break; ? ? ?//重新設置密碼
case ('*'): Cancel();break; ? ? ?//取消當前輸入
case ('#'): Ensure(); break; ? //確認鍵,
default:?
{
//DisplayListChar(0,1,Input);
write_1602com(er);
for(i=0;i<16;i++)
{
write_1602dat(Input[i]);
}
? ?operation=0;
if(N<6) ? ? ? ? ? ? ? ? ? //當輸入的密碼少于6位時,接受輸入并保存,大于6位時則無效。
{ ?
OneAlam();//按鍵提示音
//DisplayOneChar(6+N,1,'*');
for(j=0;j<=N;j++)
{
write_1602com(er+6+j);
write_1602dat('*');
}
InputData[N]=NUM;
N++;
}
else//輸入數據位數大于6后,忽略輸入
{
N=6;
break;
}
}
}
}
}
}?
}
}
//*********************************中斷服務函數**************************************
void ?time1_int() interrupt 3?
{
?TL1=0xB0;
?TH1=0x3C;
?countt0++;
? if(countt0==20)
? ?{
countt0=0;
second++;
if(pass==1)
{
if(second==1)
{
open_led=1;//關指示燈
TR1=0;//關定時器
TL1=0xB0;
?TH1=0x3C;
second=0;
}
}
else
{
if(second==3)
{
TR1=0;
second=0;
key_disable=0;
s3_keydown=0;
TL1=0xB0;
TH1=0x3C;
}
else
? ?TR1=1;
}
? ?}
}
//外部中斷解碼程序_外部中斷0
void intersvr1() interrupt 2 using 1
{
TR0=1;
Tc=TH0*256+TL0;//提取中斷時間間隔時長
TH0=0;?
TL0=0; ? ? ? ? //定時中斷重新置零
if((Tc>Imin)&&(Tc<Imax))
{?
m=0;
f=1;
return;
} ? ? ? //找到啟始碼
if(f==1)
{
if(Tc>Inum1&&Tc<Inum3)?
{
Im[m/8]=Im[m/8]>>1|0x80; m++;?
}
? ?if(Tc>Inum2&&Tc<Inum1)?
{
Im[m/8]=Im[m/8]>>1; m++; //取碼
}
if(m==32)?
{
m=0; ?
f=0;
if(Im[2]==~Im[3])?
{
IrOK=1;
TR0=0;?
}
else IrOK=0; ? //取碼完成后判斷讀碼是否正確
}?//準備讀下一碼 ??
}
}
~~~