- /***************************************************************
- 此程序是在电子密码锁的基础上增加的红外遥控功能
- 采用STC89C52单片机
- 外中断口P3.2为红外接收头接口
- 红外和键盘两种模式转换用P2.3控制,0为键盘模式,1为红外输入
- 遥控器使用常用的HT6122核心的
- 液晶用1602 引脚定义在I2C_drive.h中
- 存储器采用的24C04 引脚定义在I2C_drive.h中
- P1口接4X4矩阵按键
- ****************************************************************/
- #include<reg52.h>
- #include <string.h>
- #include "I2C_drive.h" //包含I2C总线驱动程序软件包
- #include "LCD_drive.h" //包含I2C总线驱动程序软件包
- #define uchar unsigned char
- #define uint unsigned int
- uchar code_buf[6]; //存储器密码缓冲区
- uchar incode_buf[6]; //输入密码缓冲区
- uchar IR_buf[4]={0x00,0x00,0x00,0x00};//IR_buf[0]、IR_buf[1]为用户码低位、用户码高位接收缓冲区
- // IR_buf[2]、IR_buf[3]为键数据码和键数据码反码接收缓冲区
- uchar key; //键顺序码
- uchar temp; //暂存
- sbit BEEP=P1^5; //蜂鸣器
- sbit RELAY=P3^6; //继电器
- sbit IRIN = P3^2; //遥控输入脚 红外
- sbit panduan=P2^3; //红外,键盘转换引脚,接地为键盘模式,悬空为红外模式
- uchar count_5ms,sec; //5ms和1s计数器
- bit flag_2s=0; //2s标志位,2s时间到,该位置1
- bit flag_comp=0; //比较对错标志位,比较正确,该标志位置1
- bit biaozhi=0;
- bit hongwai=1;
- bit jianpan=1;
- /******************************************************************************/
- void Delay(int num){//延时函数
- while(num--) ;
- }
- void beep(){//-扬声器--按键音
- unsigned char a;//定义变量用于发声的长度设置
- for(a=100;a>0;a--){//声音的长度
- BEEP = ~BEEP;
- Delay(50);//音调设置延时
- }
- BEEP = 1;//音乐结束后扬声器拉高关闭
- }
- /********以下是0.14ms的x倍延时函数********/
- void delayy(uchar x) //延时x*0.14ms
- {
- uchar i;
- while(x--)
- for (i = 0; i<13; i++);
- }
- /********以下是矩阵按键扫描函数********/
- void MatrixKey()
- {
- P1=0xff;
- P1=0xef; //置第1行P1.4为低电平,开始扫描第1行
- temp=P1; //读P1口按键
- temp=temp & 0x0f; //判断低4位是否有0,即判断列线(P1.0~P1.3)是否有0
- if (temp!=0x0f) //若temp不等于0x0f,说明有键按下
- {
- Delay_ms(20); //延时10ms去抖
- temp=P1; //再读取P1口按键
- temp=temp & 0x0f; //再判断列线(P1.0~P1.3)是否有0
- if (temp!=0x0f) //若temp不等于0x0f,说明确实有键按下
- {
- temp=P1; //读取P1口按键,开始判断键值
- biaozhi=1;
- hongwai=1;
- jianpan=0;
- switch(temp)
- {
- case 0xee:key=15;break;
- case 0xed:key=14;break;
- case 0xeb:key=13;break;
- case 0xe7:key=12;break;
- }
- temp=P1; //将读取的键值送temp
- beep(); //蜂鸣器响一声
- temp=temp & 0x0f; //取出列线值(P1.0~P1.3)
- while(temp!=0x0f) //若temp不等于0x0f,说明按键还没有释放,继续等待
- {
- biaozhi=0;
- jianpan=1;
- temp=P1; //若按键释放,再读取P1口
- temp=temp & 0x0f;// 判断列线(P1.0~P1.3)是否有0
- }
- }
- }
- P1=0xff;
- P1=0xdf; //置第2行P1.5为低电平,开始扫描第2行
- temp=P1;
- temp=temp & 0x0f;
- if (temp!=0x0f)
- {
- Delay_ms(20);
- temp=P1;
- temp=temp & 0x0f;
- if (temp!=0x0f)
- {
- temp=P1;
- biaozhi=1;
- hongwai=1;
- jianpan=0;
- switch(temp)
- {
- case 0xde:key=11;break;
- case 0xdd:key=10;break;
- case 0xdb:key=9;break;
- case 0xd7:key=8;break;
- }
- temp=P1;
- beep();
- temp=temp & 0x0f;
- while(temp!=0x0f)
- {
- biaozhi=0;
- jianpan=1;
- temp=P1;
- temp=temp & 0x0f;
- }
- }
- }
- P1=0xff;
- P1=0xbf; //置第3行P1.6为低电平,开始扫描第3行
- temp=P1;
- temp=temp & 0x0f;
- if (temp!=0x0f)
- {
- Delay_ms(20);
- temp=P1;
- temp=temp & 0x0f;
- if (temp!=0x0f)
- {
- temp=P1;
- biaozhi=1;
- hongwai=1;
- jianpan=0;
- switch(temp)
- {
- case 0xbe:key=7;break;
- case 0xbd:key=6;break;
- case 0xbb:key=5;break;
- case 0xb7:key=4;break;
- }
- temp=P1;
- beep();
- temp=temp & 0x0f;
- while(temp!=0x0f)
- {
- biaozhi=0;
- jianpan=1;
- temp=P1;
- temp=temp & 0x0f;
- }
- }
- }
- P1=0xff;
- P1=0x7f; //置第4行P1.7为低电平,开始扫描第4行
- temp=P1;
- temp=temp & 0x0f;
- if (temp!=0x0f)
- {
- Delay_ms(20);
- temp=P1;
- temp=temp & 0x0f;
- if (temp!=0x0f)
- {
- temp=P1;
- biaozhi=1;
- hongwai=1;
- jianpan=0;
- switch(temp)
- {
- case 0x7e:key=3;break;
- case 0x7d:key=2;break;
- case 0x7b:key=1;break;
- case 0x77:key=0;break;
- }
- temp=P1;
- beep();
- temp=temp & 0x0f;
- while(temp!=0x0f)
- {
- biaozhi=0;
- jianpan=1;
- temp=P1;
- temp=temp & 0x0f;
- }
- }
- }
- }
- /*********************红外按键矩阵函数*************************************************************************************************/
- void hongwaijvzhen ()
- {
- if(hongwai==0)
- {
- switch (IR_buf[2]){
- case 0x16: key = 0 ;break; //POWER //ON
- case 0x0c: key = 1 ;break; //MUTE //OFF
- case 0x18: key = 2 ;break; //0-9键控制
- case 0x5e: key = 3 ;break; //
- case 0x08: key = 4 ;break;
- case 0x1c: key = 5 ;break;
- case 0x5a: key = 6 ;break;
- case 0x11: key = 7 ;break;
- case 0x52: key = 8 ;break;
- case 0x4a: key = 9 ;break;
- case 0x45: key = 10;break; //A
- case 0x46: key = 11;break; //B
- case 0x47: key = 12;break;
- case 0x44: key = 13;break; //D
- case 0x40: key = 14;break; //#
- case 0x43: key = 15;break;
- }
- biaozhi=0;
- hongwai=1;
- }
- }
- /********以下是开机画面信息********/
- uchar code jianpan1_data[] = {" << KEY >> "}; //定义第1行显示的字符
- uchar code jianpan2_data[] = {" PATTERN(1) "}; //定义第2行显示的字符
- uchar code hongwai1_data[] = {" << REMOTE >> "}; //定义第1行显示的字符
- uchar code hongwai2_data[] = {" PATTERN(2) "}; //定义第2行显示的字符
- /***************************************/
- uchar code line1_data[] = {" KEY LOCK "}; //定义第1行显示的字符
- uchar code line2_data[] = {" MADE IN CHINA "}; //定义第2行显示的字符
- /********以下是输入密码画面信息********/
- uchar code in_line1[] = {" PLEASE INPUT "}; //定义第1行显示的字符
- uchar code in_line2[] = {"PASSWORD:------ "}; //定义第2行显示的字符
- /********以下是密码输入正确信息********/
- uchar code inok_line1[] = {"INPUT PASSWORD "}; //定义第1行显示的字符
- uchar code inok_line2[] = {" INOPUT OK "}; //定义第2行显示的字符
- /********以下是密码输入错误信息********/
- uchar code inerr_line1[] = {"INPUT PASSWORD "}; //定义第1行显示的字符
- uchar code inerr_line2[] = {" INPUT ERR "}; //定义第2行显示的字符
- /********以下是密码设置画面信息********/
- uchar code modify_line1[] = {"MODIFY PASSWORD "}; //定义第1行显示的字符
- uchar code modify_line2[] = {"PASSWORD:------ "}; //定义第2行显示的字符
- /********以下是密码设置正确信息********/
- uchar code setok_line1[] = {"MODIFY PASSWORD "}; //定义第1行显示的字符
- uchar code setok_line2[] = {" MODIFY OK "}; //定义第2行显示的字符
- /********以下是开机画面显示函数********/
- void StartDisp()
- {
- uchar i;
- lcd_clr(); //调清屏函数
- lcd_wcmd(0x00|0x80); //设置显示位置为第1行第0列
- i = 0;
- while(line1_data[i] != '\0') //若没有到达第1行字符串尾部
- {
- lcd_wdat(line1_data[i]); //显示第1行字符
- i++; //指向下一字符
- }
- lcd_wcmd(0x40|0x80); //设置显示位置为第2行第0列
- i = 0;
- while(line2_data[i] != '\0') //若没有到达第2行字符串尾部
- {
- lcd_wdat(line2_data[i]); //显示第2行字符
- i++; //指向下一字符
- }
- }
- /********以下是密码输入画面显示函数********/
- void CodeInDisp()
- {
- uchar i;
- lcd_clr(); //调清屏函数
- lcd_wcmd(0x00|0x80); //设置显示位置为第1行第0列
- i = 0;
- while(in_line1[i] != '\0') //若没有到达第1行字符串尾部
- {
- lcd_wdat(in_line1[i]); //显示第1行字符
- i++; //指向下一字符
- }
- lcd_wcmd(0x40|0x80); //设置显示位置为第2行第0列
- i = 0;
- while(in_line2[i] != '\0') //若没有到达第2行字符串尾部
- {
- lcd_wdat(in_line2[i]); //显示第2行字符
- i++; //指向下一字符
- }
- }
- /********以下是密码输入错误显示函数********/
- void CodeInErr()
- {
- uchar i;
- lcd_clr(); //调清屏函数
- lcd_wcmd(0x00|0x80); //设置显示位置为第1行第0列
- i = 0;
- while(inerr_line1[i] != '\0') //若没有到达第1行字符串尾部
- {
- lcd_wdat(inerr_line1[i]); //显示第1行字符
- i++; //指向下一字符
- }
- lcd_wcmd(0x40|0x80); //设置显示位置为第2行第0列
- i = 0;
- while(inerr_line2[i] != '\0') //若没有到达第2行字符串尾部
- {
- lcd_wdat(inerr_line2[i]); //显示第2行字符
- i++; //指向下一字符
- }
- }
- /********以下是密码输入正确显示函数********/
- void CodeInOk()
- {
- uchar i;
- lcd_clr(); //调清屏函数
- lcd_wcmd(0x00|0x80); //设置显示位置为第1行第0列
- i = 0;
- while(inok_line1[i] != '\0') //若没有到达第1行字符串尾部
- {
- lcd_wdat(inok_line1[i]); //显示第1行字符
- i++; //指向下一字符
- }
- lcd_wcmd(0x40|0x80); //设置显示位置为第2行第0列
- i = 0;
- while(inok_line2[i] != '\0') //若没有到达第2行字符串尾部
- {
- lcd_wdat(inok_line2[i]); //显示第2行字符
- i++; //指向下一字符
- }
- }
- /********以下是密码设置画面显示函数********/
- void CodeSetDisp()
- {
- uchar i;
- lcd_clr(); //调清屏函数
- lcd_wcmd(0x00|0x80); //设置显示位置为第1行第0列
- i = 0;
- while(modify_line1[i] != '\0') //若没有到达第1行字符串尾部
- {
- lcd_wdat(modify_line1[i]); //显示第1行字符
- i++; //指向下一字符
- }
- lcd_wcmd(0x40|0x80); //设置显示位置为第2行第0列
- i = 0;
- while(modify_line2[i] != '\0') //若没有到达第2行字符串尾部
- {
- lcd_wdat(modify_line2[i]); //显示第2行字符
- i++; //指向下一字符
- }
- }
- /********以下是密码设置正确显示函数********/
- void CodeSetOk()
- {
- uchar i;
- lcd_clr(); //调清屏函数
- lcd_wcmd(0x00|0x80); //设置显示位置为第1行第0列
- i = 0;
- while(setok_line1[i] != '\0') //若没有到达第1行字符串尾部
- {
- lcd_wdat(setok_line1[i]); //显示第1行字符
- i++; //指向下一字符
- }
- lcd_wcmd(0x40|0x80); //设置显示位置为第2行第0列
- i = 0;
- while(setok_line2[i] != '\0') //若没有到达第2行字符串尾部
- {
- lcd_wdat(setok_line2[i]); //显示第2行字符
- i++; //指向下一字符
- }
- }
- /********以下是密码输入函数********/
- void PassIn()
- {
- static uchar lcd_x=0; //显示指针,注意是静态局部变量
- static uchar count=0; //密码计数器 ,注意是静态局部变量
- static uchar code_n=0; //密码次数
- PASSWORD:
- lcd_clr(); //调清屏函数
- CodeInDisp();//密码输入画面函数
- do{
- /**********修改1***********/
- P1=0xf0;
- if(P1!=0xf0) //若有按键按下
- {
- MatrixKey(); //调矩阵按键扫描函数
- P1=0xf0;
- while(P1!=0xf0);//等待按键松开
- /***************************/
- if((key>=0)&&(key<=9)) //若按下是的0~9键(即密码只能是数字,字母键A~F无效)
- {
- incode_buf[count]=key; //将键值存入数组
- lcd_wcmd((0x49+lcd_x)|0x80); //设置显示位置为第2行第9+lcd_x列
- lcd_wdat(0x2a); //显示为"*",0x2a是"*"的LCD显示码
- count++; //输入下一位密码
- lcd_x++; //指向LCD的下一位置
- }
- }
- }while(count<6); //密码设置为6位
- if(count>=6){count=0;lcd_x=0;}
- if(memcmp(incode_buf,code_buf,6)==0) //若两个数组相等,则返回值为0,注意这里不能用strcmp函数进行比较
- {
- CodeInOk(); //若输入的密码正确,则显示输入正确的信息
- beep();beep();beep(); //输入正确后,蜂鸣器响三声
- flag_comp=1; //密码比较标志位置1
- code_n=0; //密码计数器清0
- RELAY=0; //打开继电器,开锁
- }
- else if(memcmp(incode_buf,code_buf,6)!=0)//若输入的密码不正确
- {
- code_n++; //密码计数器加1
- if(code_n>=3) //有三次输入的机会
- {
- CodeInErr(); //若三次输入均错误,显示密码错误信息
- flag_comp=0; //密码比较标志位清0
- code_n=0; //密码计数器清0
- }
- else goto PASSWORD; //若还有机会输入密码,则跳转到标号PASSWORD处继续输入
- }
- }
- /********以下是红外线密码输入函数**********************************************************************************/
- void PassInhongwai()
- {
- static uchar lcd_x=0; //显示指针,注意是静态局部变量
- static uchar count=0; //密码计数器 ,注意是静态局部变量
- static uchar code_n=0; //密码次数
- PASSWORD: lcd_clr(); //调清屏函数
- CodeInDisp();//密码输入画面函数
- do{
- /**********修改1***********/
- if(hongwai==0) //若有按键按下
- {
- hongwaijvzhen(); //调矩阵按键扫描函数
- while(!hongwai);//等待按键松开
- /***************************/
- if((key>=0)&&(key<=9)) //若按下是的0~9键(即密码只能是数字,字母键A~F无效)
- {
- incode_buf[count]=key; //将键值存入数组
- lcd_wcmd((0x49+lcd_x)|0x80); //设置显示位置为第2行第9+lcd_x列
- lcd_wdat(0x2a); //显示为"*",0x2a是"*"的LCD显示码
- count++; //输入下一位密码
- lcd_x++; //指向LCD的下一位置
- beep();
- }
- }
- }while(count<6); //密码设置为6位
- if(count>=6){count=0;lcd_x=0;}
- if(memcmp(incode_buf,code_buf,6)==0) //若两个数组相等,则返回值为0,注意这里不能用strcmp函数进行比较
- {
- CodeInOk(); //若输入的密码正确,则显示输入正确的信息
- beep();beep();beep(); //输入正确后,蜂鸣器响三声
- flag_comp=1; //密码比较标志位置1
- code_n=0; //密码计数器清0
- RELAY=0; //打开继电器,开锁
- }
- else if(memcmp(incode_buf,code_buf,6)!=0)//若输入的密码不正确
- {
- code_n++; //密码计数器加1
- if(code_n>=3) //有三次输入的机会
- {
- CodeInErr(); //若三次输入均错误,显示密码错误信息
- flag_comp=0; //密码比较标志位清0
- code_n=0; //密码计数器清0
- }
- else goto PASSWORD; //若还有机会输入密码,则跳转到标号PASSWORD处继续输入
- }
- }
- /********以下是密码设置函数*******************************************************************************************************/
- void PassSet()
- {
- static uchar lcd_x=0; //显示指针,注意是静态局部变量
- static uchar count=0; //密码计数器 ,注意是静态局部变量
- lcd_clr(); //调清屏函数
- CodeSetDisp(); //密码设置画面函数
- do{
- /********修改2**************/
- P1=0xf0;
- if(P1!=0xf0) //若有按键按下
- {
- MatrixKey(); //调矩阵按键扫描函数
- P1=0xf0;
- while(P1!=0xf0);//等待按键松开
- /**********************/
- if((key>=0)&&(key<=9)) //若按下是的0~9键(即密码只能是数字,字母键A~F无效)
- {
- code_buf[count]=key; //将键值存入数组code_buf[]中
- lcd_wcmd((0x49+lcd_x)|0x80); //设置显示位置为第2行第9+lcd_x列
- lcd_wdat(code_buf[count]+0x30); //将输入的密码通过LCD显示出来
- count++; //输入下一位密码
- lcd_x++; //指向LCD的下一位置
- }
- }
- }while(count<6); //密码设置为6位
- if(count>=6){count=0;lcd_x=0;}
- beep();beep();beep(); //输入完毕后,蜂鸣器响三声
- write_nbyte(0xa0,0x00,code_buf,6); //将数组code_buf[]中的6位密码写入24cxx从00开始的单元中
- lcd_clr(); //调清屏函数
- CodeSetOk(); //密码设置正确画面函数
- }
- /********************************************红外密码设置函数****************************************************************/
- void PassSethongwai()
- {
- static uchar lcd_x=0; //显示指针,注意是静态局部变量
- static uchar count=0; //密码计数器 ,注意是静态局部变量
- lcd_clr(); //调清屏函数
- CodeSetDisp(); //密码设置画面函数
- do{
- /********修改2**************/
- if(hongwai==0) //若有按键按下
- {
- hongwaijvzhen(); //调矩阵按键扫描函数
- while(!hongwai);//等待按键松开
- /**********************/
- if((key>=0)&&(key<=9)) //若按下是的0~9键(即密码只能是数字,字母键A~F无效)
- {
- code_buf[count]=key; //将键值存入数组code_buf[]中
- lcd_wcmd((0x49+lcd_x)|0x80); //设置显示位置为第2行第9+lcd_x列
- lcd_wdat(code_buf[count]+0x30); //将输入的密码通过LCD显示出来
- count++; //输入下一位密码
- lcd_x++; //指向LCD的下一位置
- beep();
- }
- }
- }while(count<6); //密码设置为6位
- if(count>=6){count=0;lcd_x=0;}
- beep();beep();beep(); //输入完毕后,蜂鸣器响三声
- write_nbyte(0xa0,0x00,code_buf,6); //将数组code_buf[]中的6位密码写入24cxx从00开始的单元中
- lcd_clr(); //调清屏函数
- CodeSetOk(); //密码设置正确画面函数
- }
- /****************开机初始模式显示函数******************************************/
- void kaijimoshi()
- {
- if(panduan==0) //如果P2.3脚接地显示《KEY》
- { // PATTERN(1)
- uchar i;
- lcd_clr(); //调清屏函数
- lcd_wcmd(0x00|0x80); //设置显示位置为第1行第0列
- i = 0;
- while(jianpan1_data[i] != '\0') //若没有到达第1行字符串尾部
- {
- lcd_wdat(jianpan1_data[i]); //显示第1行字符
- i++; //指向下一字符
- }
- lcd_wcmd(0x40|0x80); //设置显示位置为第2行第0列
- i = 0;
- while(jianpan2_data[i] != '\0') //若没有到达第2行字符串尾部
- {
- lcd_wdat(jianpan2_data[i]); //显示第2行字符
- i++; //指向下一字符
- }
- Delay_ms(3000); //延时3秒
- lcd_clr();
- }
- if(panduan==1) //如果P2.3脚悬空显示《REMOTE》
- { // PATTERN(2)
- uchar i;
- lcd_clr(); //调清屏函数
- lcd_wcmd(0x00|0x80); //设置显示位置为第1行第0列
- i = 0;
- while(hongwai1_data[i] != '\0') //若没有到达第1行字符串尾部
- {
- lcd_wdat(hongwai1_data[i]); //显示第1行字符
- i++; //指向下一字符
- }
- lcd_wcmd(0x40|0x80); //设置显示位置为第2行第0列
- i = 0;
- while(hongwai2_data[i] != '\0') //若没有到达第2行字符串尾部
- {
- lcd_wdat(hongwai2_data[i]); //显示第2行字符
- i++; //指向下一字符
- }
- Delay_ms(3000); //延时3秒
- lcd_clr();
- }
- }
- /********以下是主函数********/
- void main()
- {
- EA=1;EX0=1; //允许总中断中断,使能 INT0 外部中断
- IT0 = 1; //触发方式为脉冲负边沿触发
- IRIN=1; //遥控输入脚置1
- TMOD=0x01; //定时器T0方式1
- TH0=0xee;
- TL0=0x00; //5ms定时初值
- ET0=1; //开总中断,开定时器T0中断
- Delay_ms(10);
- lcd_init(); //调LCD初始化函数
- I2C_init(); //调I2C总线初始化函数(在I2C总线驱动程序软件包中)
- kaijimoshi();
- START: RELAY=1; //继电器关断
- lcd_clr();
- StartDisp(); //开机画面显示函数
- read_nbyte (0xa0,0x00,code_buf,6);//从24Cxx的0x00开始的单元中读出6个密码存入code_buf[]数组中
- P1=0xf0;
- while((P1==0xf0)&&(hongwai==0)); //如果红外和键盘不是同时按下,就进入到下一步,否则等待
- MatrixKey();
- /*******************************执行红外模式密码锁方式****************************************************************************/
- if(panduan==1)
- {
- SCAN: hongwaijvzhen (); //调矩阵按键扫描函数
- if(key!=0x0a)goto SCAN; //若按下的不是A键,跳转到标号SCAN处继续扫描
- TR0=1; //启动定时器T0
- Delay_ms(500); //延时500ms
- beep(); //蜂鸣器响一声
- if(flag_2s==1)flag_2s=0; //若2s到,则将 2s标志位清0
- else goto SCAN; //若2s未到,则跳转到标号SCAN处继续扫描
- PassInhongwai(); //调红外密码输入函数
- while(1)
- {
- if(flag_comp==1) //若输入的密码正确
- {
- hongwaijvzhen ();
- if(key==0x0b) //在密码正确的情况下若按下了B键
- {
- PassSethongwai(); // 调红外密码设置函数
- hongwaijvzhen ();
- if(key==0x0e)goto START;//若按下了E键,则跳转到标志START处重新开始
- }
- if(key==0x0e)goto START; //若按下了E键,则跳转到标志START处重新开始
- }
- if(flag_comp==0) //若输入的密码不正确
- {
- hongwaijvzhen ();
- if(key==0x0e)goto START;//若按下的是E键,跳转到标号START处重新开始
- }
- }
- }
- /************************执行键盘输入密码锁模式**********************************************************************************************/
- if(panduan==0)
- {
- DSCAN: MatrixKey(); //调矩阵按键扫描函数
- if(key!=0x0a)goto DSCAN; //若按下的不是A键,跳转到标号SCAN处继续扫描
- TR0=1; //启动定时器T0
- Delay_ms(500); //延时500ms
- beep(); //蜂鸣器响一声
- if(flag_2s==1)flag_2s=0; //若2s到,则将 2s标志位清0
- else goto DSCAN; //若2s未到,则跳转到标号SCAN处继续扫描
- PassIn(); //调密码输入函数
- /******************************************/
- while(1)
- {
- if(flag_comp==1) //若输入的密码正确
- {
- MatrixKey(); //扫描按键
- if(key==0x0b) //在密码正确的情况下若按下了B键
- {
- PassSet(); //若按下的是B键,调密码设置函数
- MatrixKey(); //扫描按键
- if(key==0x0e)goto START;//若按下了E键,则跳转到标志START处重新开始
- }
- if(key==0x0e)goto START; //若按下了E键,则跳转到标志START处重新开始
- }
- if(flag_comp==0) //若输入的密码不正确
- {
- MatrixKey(); //扫描按键
- if(key==0x0e)goto START;//若按下的是E键,跳转到标号START处重新开始
- }
- }
- }
- }
- /********以下是定时器T0中断函数********/
- void timer0() interrupt 1
- {
- TH0=0xee;TL0=0x00; //重装5ms定时初值
- count_5ms++; //5ms 计数值加1
- if(count_5ms==200) //若count_5ms为200,说明1s到(200×0ms=1000ms)
- {
- count_5ms=0; // count_5ms清0
- sec++; //秒计数器加1
- }
- if(sec==2)
- {
- flag_2s=1; //若2s到,将2s标志位置1
- TR0=0; //关断定时器T0
- }
- }
- /********以下是外中断0函数********/
- void IR_decode() interrupt 0
- {
- uchar j,k,count=0;
- EX0 = 0; //暂时关闭外中断0中断请求
- delayy(20); //延时20*0.14=2.8ms
- if (IRIN==1) //等待 IRIN低电平出现
- {
- EX0 =1; //开外中断0
- return; //中断返回
- }
- while (!IRIN) delayy(1); //等待IRIN变为高电平,跳过9ms的低电平引导码
- for (j=0;j<4;j++) //收集四组数据,即用户码低位、用户码高位、键值数据码和键值数码反码
- {
- for (k=0;k<8;k++) //每组数据有8位
- {
- while (IRIN) //等待IRIN变为低电平,跳过4.5ms的高电平引导码信号。
- delayy(1);
- while (!IRIN) //等待IRIN变为高电平
- delayy(1);
- while (IRIN) //对IRIN高电平时间进行计数
- {
- delayy(1); //延时0.14ms
- count++; //对0.14ms延时时间进行计数
- if (count>=30)
- {
- EX0=1; //开外中断0
- return; //0.14ms计数过长则返回
- }
- }
- IR_buf[j]=IR_buf[j] >> 1; //若计数小于6,数据最高位补"0",说明收到的是"0"
- if (count>=6) {IR_buf[j] = IR_buf[j] | 0x80;} //若计数大于等于6,数据最高位补"1",说明收到的是"1"
- count=0; //计数器清0
- }
- }
- if (IR_buf[2]!=~IR_buf[3]) //将键数据反码取反后与键数据码码比较,若不等,表示接收数据错误,放弃
- {
- EX0 = 1; //开外中断0
- return;
- }
- /******************************************************************/
- hongwai=0;
- beep(); //蜂鸣器响一声
- EX0 = 1; //开外中断0
- biaozhi=1;
- jianpan=1;
- }
复制代码 |