资源描述
《电子技术综合设计》
设计报告
设计题目: 基于STC89C52单片机的电子密码锁设计
组长姓名: 汪菲 学 号:
专业与班级: 信息12-1班
姓 名: 田宣宣 学 号:
专业与班级: 信息12-1班
姓 名: 侯宁博 学 号:
专业与班级: 信息12-1班
时 间: 2014 ~ 2015 学年第(1)学期
指导教师: 袁小平 成 绩: 日 期:2015年1月1日
一、设计摘要和课题任务
在日常生活和工作中,住宅与部门的安全防范、单位的文件档案、财务报表以及一些个人资料的保存多以加锁的办法来解决。目前门锁主要用弹子锁,其钥匙容易丢失;保险箱主要用机械密码锁,其结构较为复杂,制造精度要求高,成本高,且易出现故障,人们常需携带多把钥匙,使用极不方便,且钥匙丢失后安全性即大打折扣。针对这些锁具给人们带来的不便,为满足人们对锁的使用要求,增加其安全性,用密码代替钥匙的电子密码锁应运而生。它的出现为人们的生活带来了很大的方便,有很广阔的市场前景。
本文从经济实用的角度出发,采用89S51单片机与低功耗CMOS型E2PROM AT24C02作为主控芯片与数据存储器单元,结合外围的键盘输入、显示、报警、开锁等电路,用C语言编写主控芯片的控制程序,设计了一款可以多次更改密码具有报警功能的电子密码锁。
关键词: 单片机;密码锁;红外遥控
完成的功能:
1.密码锁初始设置6位密码,密码通过红外遥控器或4X4键盘输入,若密码正确,则将锁打开。 在按下每个按键的时候都会有蜂鸣器响声。
2.密码由用户自己设定,在开锁状态下,用户可自行修改密码。 本设计采用单片机为主控芯片,结合外围电路,组成电子密码锁,用户想要打开锁,必先通过提供的键盘输入正确的密码才能将锁打开,密码输入错误有提示,为了提高安全性,当密码输入错误一次将报警。密码可以由用户自己修改设定,锁打开后才能修改密码。修改密码之前必须再次输入密码,在输入新密码时候需要二次确认,以防止误操作。
3.系统工作时,用户通过红外遥控器或键盘输入密码,单片机将输入密码与设定密码进行比较,若密码正确,则发出开锁信号,将门打开,系统不报警;若密码不正确,则有相应的指示灯闪动,并要求重新输入密码,重新输入密码的次数不能超过3次,若3次输入的密码都不正确,则发出报警信号。
4.对密码进行存储,用户设定的密码掉电不丢失。
二、方案比较与选择
可行性分析:
本次设计采用STC89C52芯片,STC89C52是一个低电压,高性能CMOS 8位单片机.编程软件采用keil软件,由keil C生成HEX文件,然后烧入单片机。
密码输入采用红外遥控输入和4X4键盘输入方式。红外线输入采用通用遥控器,遥控接收采用HX1838一体化万能接收头。接收到的信号通过单片机INT0输入单片机。键盘采用的是4X4矩阵式按键键盘,它由行线和列线组成,也称行列式键盘,按键位于行列的交叉点上,密码锁的密码由键盘输入完成,与独立式按键键盘相比,要节省很多I/O口,让设计更容易实现。
密码存储采用EEPROM串行I C总线芯片AT24C02。通过单片机对24c02芯片进行密码存储,存储好密码后,通过按键输入密码与存储芯片里面的数据进行对比,根据数据是否一致,来执行相应的操作,还可以根据按键操作来执行是否更换数据。
报警部分由蜂鸣器及外围电路组成,加电后不发声,当密码输入错误时,单片机的P3.6引脚为低电平,三极管导通执行蜂鸣器报警声子程序发出警笛报警。
开锁用户通过键盘设置六位密码,并储存在EEPROM中作为锁码指令。首先按下键盘数字键0-9输入密码,最后按下确认键。当用户输入一密码后,单片机自动识码,如果识码不符,则提示重新输入,如果超过三次则报警。如果正确,系统使单片机其中一引脚线发出信号,经三极管放大后,由继电器驱动电磁阀动作将锁打开,实物中用继电器替代。
除红外遥控外其它部分可以采用Proteus软件进行仿真,使用C语言编程,使该设计的功能更容易进行规划调试及实现,同时也节约了开发成本,具有一定可行性。
三、系统设计
STC89C52
程序
键盘红外输入
报警模块
继电器模块
1602显示
24c02模块
如图所示,本次密码锁设计共有如下六部分组成:
四、电路设计
1)STC89C52RC单片机
第 38 页 共 38 页
STC89C52RC单片机为40引脚芯片如图所示。 I/O口线: P0、P1、P2、P3共四个八位P0口是三态双向口, 通称数据总线口, 因为只有该口能直接用于对外部存储器的读ˆ写操作。P1口是专门供用户使用的I/O口, 是准双向口。P2口是从系统扩展时作高8位地址线用。不扩展外部存储器时, P口也可以作为用户I/O口线使用, P2口也是准双向口。P3口是双功能口, 该口的每一位均可独立地定义为第一I/O 功能或第二I/O功能,作为第一功能使用时操作同P1口。(我们用STC的原因:STC89 系列单片机大部分具有在系统可编程(ISP)特性,ISP 的好处是:省去购买通用编程器,单片机在用户系统上即可下载/ 烧录用户程序)
2)晶振时钟电路
XTAL1:单芯片系统时钟的反向放大器输入端。
XTAL2:系统时钟的反向放大器输出端,一般在设计上只要在 XTAL1 和 XTAL2 上接上一只石英振荡晶体系统就可以动作了,此外可以在两个引脚与地之间加入一个 30PF 的小电容,可以使系统更稳定,避免噪声干扰而死机。
3)复位电路
RESET:芯片的重置引脚,高电平动作,当要对晶片重置时,只要对此引脚电平提升至高电平并保持两个机器周期以上的时间,芯片便能完成系统重置的各项动作,使得内部特殊功能寄存器之内容均被设成已知状态,并且至地址0000H处开始读入程序代码而执行程序。
本图为开关复位基本电路:
4)蜂鸣器电路
三极管主要是做驱动用的。因为单片机的IO口驱动能力不够让蜂鸣器发出声音,所以我们通过三极管放大驱动电流,从而可以让蜂鸣器发出声音,你要是输出低电平,三极管导通,集电极电流通过蜂鸣器让蜂鸣器发出声音,当输出高电平时,三极管截止,没有电流流过蜂鸣器,所以就不会发出声音。
(5)1602的使用:硬件接线:
液晶4端RS端为向液晶控制器写数据/写命令选择端。
液晶5端为读/写选择端,因为我们不从液晶读取任何数据,只向其写入命令和显示数据,因此此端始终选择为写状态,即低电平接地。
液晶6端为使能信号E,是操作时必需的信号。
(6) 红外遥控输入
红外线输入采用通用遥控器,遥控接收采用HX1838一体化万能接收头。接收到的信号通过单片机INT0输入单片机。通用红外遥控系统由发射和接收两大部分组成,应用编/解码专用集成电路芯片来进行控制操作,如图1所示。发射部分包括键盘矩阵、编码调制、LED红外发送器;接收部分包括光、电转换放大器、解调、解码电路。
遥控信号接收
接收电路可以使用一种集红外线接收和放大于一体的一体化红外线接收器,不需要任何外接元件,就能完成从红外线接收到输出与TTL电平信号兼容的所有工作,而体积和普通的塑封三极管大小一样,它适合于各种红外线遥控和红外线数据传输。接收器对外只有3个引脚:Out、GND、Vcc与单片机接口非常方便,如图7所示。
① 脉冲信号输出接,直接接单片机的IO 口。
② GND接系统的地线(0V);
③ Vcc接系统的电源正极(+5V);
(7) 继电器模拟开锁部分
电磁继电器一般由铁芯、线圈、衔铁、触点簧片等组成的。只要在线圈两端加上一定的电压,线圈中就会流过一定的电流,从而产生电磁效应,衔铁就会在电磁力吸引的作用下克服返回弹簧的拉力吸向铁芯,从而带动衔铁的动触点与静触点(常开触点)吸合。当线圈断电后,电磁的吸力也随之消失,衔铁就会在弹簧的反作用力返回原来的位置,使动触点与原来的静触点(常闭触点)释放。这样吸合、释放,从而达到了在电路中的导通、切断的目的。对于继电器的“常开、常闭”触点,可以这样来区分:继电器线圈未通电时处于断开状态的静触点,称为“常开触点”;处于接通状态的静触点称为“常闭触点”。继电器一般有两股电路,为低压控制电路和高压工作电路。
如果密码输入正确,系统使单片机其中一引脚线发出信号,经三极管放大后,由继电器驱动电磁阀动作将锁打开,实物中用继电器替代。
(8)密码存储部分
密码存储采用EEPROM串行I2C总线芯片AT24C02。通过单片机对24C02芯片进行密码存储,存储好密码后,通过按键输入密码与存储芯片里面的数据进行对比,根据数据是否一致,来执行相应的操作,还可以根据按键操作来执行是否更换数据。
(9) 矩阵键盘
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P2口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显b,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。
五、 程序设计:
本设计选用单片机STC89C52RC作为本设计的核心元件,利用单片机灵活的编程设计和丰富的I/O端口,及其控制的准确性,实现基本的密码锁功能。在单片机的外围电路:外接输入键盘用于密码的输入和一些功能的控制,外接AT24C02芯片用于密码的存储,外接LCD1602显示器用于显示作用。
当用户需要开锁时,先按键盘的数字键0-9输入密码。密码输完后按下确认键,如果密码输入正确则开锁,不正确显示密码错误重新输入密码,当三次密码错误则发出报警;当用户需要修改密码时,先按下键盘设置键后输入原来的密码,只有当输入的原密码正确后才能设置新密码。新密码输入无误后按确认键使新密码将得到存储,密码修改成功。
(1)程序设计框图:
具体程序在以后设计中通过图书馆、网上查询资料进行编写,调试。
(2) LCD1602的控制实现
void write_com(uchar com) //1602液晶写指令
{
rs=0;
lcden=0;
P1=com;
delayms(1);
lcden=1;
delayms(2);
lcden=0;
}
void write_date(uchar date) //1602液晶写数据
{
rs=1;
lcden=0;
P1=date;
delayms(1);
lcden=1;
delayms(2);
lcden=0;
}
void init_lcd(void) //初始化液晶,及画面初始化
{
wela=0;
lcden=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
}
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0){write_com(0x80 + x);}
else{write_com(0xC0 + x);}
while (*s)
{write_date( *s); s++;}
}
注意:写操作命令和写数据命令分别是两个独立的函数完成的,函数内部唯一的区别就是液晶数据命令选择端的高低电平的不同。我们小组通过先写了这些程序,作用是以后想要往1602的某一行某一列读写数据的时候可以直接调用LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)程序,其中X是指定某一列,y指定某一行,S表示要显示的字符。
(3) 矩阵键盘的控制实现
1、判断键盘中有无键按下 将全部行线Y0-Y3置低电平,然后检测列线的状态。只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。若所有列线均为高电平,则键盘中无键按下。
2、判断闭合键所在的位置 在确认有键按下后,即可进入确定具体闭合键的过程。其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。
uchar Keys_Scan()
{
uchar Tmp,KeyNO=0;
P2 = 0x0f;
delayms(1);
Tmp = P2 ^ 0x0f;
switch(Tmp)
{
case 1: KeyNO = 0; break;
case 2: KeyNO = 1; break;
case 4: KeyNO = 2; break;
case 8: KeyNO = 3; break;
default: KeyNO = 16;
}
P2 = 0xf0;
delayms(1);
Tmp = P2 >> 4 ^ 0x0f;
switch(Tmp)
{
case 1: KeyNO += 0; break;
case 2: KeyNO += 4; break;
case 4: KeyNO += 8; break;
case 8: KeyNO += 12;
}
Beep();
return KeyNO;
}
Keys_Scan()为键盘扫描程序首先让P2口高四位为0,低四位为1,。若有按键按下,则低四位中会有一个1翻转为0,高四位不会变,此时即可确定被按下的键的列位置。然后让P2口高四位为1,低四位为0,若有按键按下,则高四位中会有一个1翻转为0,低四位不会变,此时即可确定被按下的键的行位置。
(4) 存储器24C02:(模块化程序,可以直接拿来用,需要自己定义的就是SDA和SCK的控制引脚)
void I2C_start(void)
{
SDA_EEPROM=1;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA_EEPROM=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
}
void I2C_stop(void)
{
SDA_EEPROM=0;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA_EEPROM=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
}
void I2C_ackownledge(void)
{
SDA_EEPROM=0;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
}
void I2C_no_ackownledge(void)
{
SDA_EEPROM=1;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
}
void I2C_sendB(uchar byte)
{
uchar counter;
for(counter=0;counter<8;counter++)
{
if(byte&0x80) SDA_EEPROM=1;
else SDA_EEPROM=0;
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
byte<<=1;
}
_nop_();
_nop_();
SDA_EEPROM=1;
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
if(SDA_EEPROM==0) ack=1;
else ack=0;
SCL=0;
_nop_();
_nop_();
}
uchar I2C_receiveB(void)
{
uchar temp;
uchar counter;
temp=0;
SDA_EEPROM=1;
_nop_();
_nop_();
for(counter=0;counter<8;counter++)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
if(SDA_EEPROM==1) temp=(temp<<1)|0x01;
else temp=temp<<1;
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
}
_nop_();
_nop_();
return(temp);
}
bit I2C_send_string(uchar no,uchar address)
{
uchar counter;
for(counter=0;counter<no;counter++)
{
I2C_start();
I2C_sendB(C02_write);
if(ack==0) return(0);
I2C_sendB(address+counter);
if(ack==0) return(0);
I2C_sendB(UserPassword[counter]);
I2C_stop();
delay_ms(20);
}
return(1);
}
//读EEPROMPassword
bit I2C_receive_string(uchar no,uchar address)
{
uchar counter;
for(counter=0;counter<no;counter++)
{
I2C_start();
I2C_sendB(C02_write);
if(ack==0) return(0);
I2C_sendB(address+counter);
if(ack==0) return(0);
I2C_start();
I2C_sendB(C02_read);
if(ack==0) return(0);
IIC_Password[counter]=I2C_receiveB();
I2C_no_ackownledge();
I2C_stop();
}
}
(5) 红外发射与接收部分:
void EX0_ISR (void) interrupt 0 //外部中断1服务函数
{
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 Ir_work(void)
{
switch(IRcord[2])
{
case 0x16: KeyNo = 0; break;//遥控按键0
case 0x0c: KeyNo = 1; break;//遥控按键1
case 0x18: KeyNo = 2; break;//遥控按键2
case 0x5e: KeyNo = 3; break;//遥控按键3
case 0x08: KeyNo = 4; break;//遥控按键4
case 0x1c: KeyNo = 5; break;//遥控按键5
case 0x5a: KeyNo = 6; break;//遥控按键6
case 0x42: KeyNo = 7; break;//遥控按键7
case 0x52: KeyNo = 8; break;//遥控按键8
case 0x4a: KeyNo = 9; break;//遥控按键9
case 0x19: KeyNo = 10; break;//遥控按键100+
case 0x0d: KeyNo = 11; break;//遥控按键200+
default: KeyNo = 16;
}
IRcord[0]=0; //清除输入数据
IRcord[1]=0; //清除输入数据
IRcord[2]=0; //清除输入数据
IRcord[3]=0; //清除输入数据
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
}
(6)器件采购
元件名称
数量
元件名称
数量
STC89C52RC芯片
一个
12MHZ晶振
一个
LCD显示屏
一个
二极管
一个
三极管
两个
按键
十七个
LED
一个
103滑动变阻器
一个
蜂鸣器
一个
SRA-06VDC继电器
一个
AT24C02芯片
一个
红外遥控器
一个
红外接收头
一个
导线
若干
六、系统调试:
一)、硬件调试:
电子密码锁演示电路的调试:此电路板由多个部分组成,接线繁琐,极易出错。检查按键无故障、导线无断线、连线接头无互相搭联后可先写一个软件调试程序,依次检查按键键盘,继电器,蜂鸣器,LCD1602液晶屏和红外遥控的控制程序;若未正常工作,则可能是连线接错。根据每个模块的工作情况依次查找直到电路正常工作为止。
二)、软件调试:
本系统的软件系统很大,全部采用C语言编写,除语法与逻辑差错外,当确认程序没问题时,直接下载到单片机仿真调试。采取自下到上的方法,单独调好每一个模块,最后完成一个完整的系统调试。
在整个程序的编写过程中,研究每个子程序是否好使,我是通过Keil C和proteus两个软件来实现的。Proteus是一个单片机的仿真软件,通过它可以不用连接硬件就能检查程序是否好使。Keil C则帮助我检查程序是否存在语法错误之类的问题,还可以生成hex文件,供proteus软件仿真使用。通过这两个软件,我把整个的程序调试正确。最后交通灯的大部分功能都已经基本实现,所以进行编程调试了, 硬件和软件都能按设计要求实行个功能。
七、课程设计总结
电子设计综合技术课程是在学习模电、数电、单片机等课程基础上所设计的一门提高我们对理论应用、设计能力的一门综合实践课程,寓教学于实物实践,使我们可以充分发挥自己的创新能力、动手能力,提高我们对所学专业的认识。
我们首先从设计仿真着手,使用仿真软件进行仿真,进行电路的排布,编写程序,查找搜集资料,通过在图书馆以及在网络上的查询,找到与设计有关电路以及C语言与单片机仿真的资料,熟悉并理解各单元电路、元器件的工作原理和基本应用及各集成块的引脚图和各引脚的逻辑功能,学习知识与软件,掌握C语言与单片机串行通信技术的基本原理。再对知识归纳总结、分析整理。运用所学知识构建电路图,使用虚拟串口对硬件电路进行仿真调试。接下来,我们采购元件,进行实物焊接,由于在大二已经进行电子工艺实习课程的训练,焊接实物比较顺利地实现,但继电器开锁部分不能实现功能,经过我们向老师、学长请教,组员查找资料改进电路,多次对实物调试,最终实物功能实现了仿真要求。
通过这次的电子设计课程,让我们认识到了一些自己的不足和缺点。使我们找到了与他人的差距。这些对我们以后的学习有着很大的帮助,我们很高兴在这次的设计中让我们学习到更多的知识。在这次电子设计的电路设计和制作的时候,我们发现Proteus并不是很好学习的,特别是要做一个可以使自己满意的电路更是很难了。在电路的设计过程程中要求我们要考虑到整个电路设计方案的完整性和合理性。而在做实物的时候,既要了解自己选择的电子器件对电压和电流要求的同时,还要考虑到这个参数的设定对自己设计方案其他方面的影响。如果只是这一个元件参数的设计还是比较好做的,但是整个电路的元件参数总体设计下来可就不是那么的容易了,所以在电子设计过程中,我们总结一定要胆大心细:对电子产品功能、电路实现要敢于创新,在实施计划时要细致谨慎,只有这样,才能提高团队以及个人的创新实践能力。
在整个设计中,组员分工协作非常重要,团队进行任务要有规划,要充分发挥每组员的长处,从而调动个人的积极性和提高团队的效率。我们的团队需要一个在关键时刻能够果断决策的带头人,同时整个团队的每个成员都要学着做一个聆听者,虚心接受组员的意见与建议,这样,才能让整个团队在有限的时间内创造出无限的价值。
最后,感谢老师和同学在我们的课程设计中所提供的悉心指导,此次长达将近一学期的课程设计的点点滴滴,电路焊接失误的苦闷,一个个小功能实现时的喜悦,让我们终生难以忘记,我们一定会在未来的学习、工作中,继续保持这种认真的态度,继续努力,期待未来遇见更好的自己。
八、 参考文献:
[1] 冯育长. 单片机系统设计与实例分析[M],西安:西安电子科技大学出版社,2007
[2] 付家才. 单片机控制工程实践技术[M],北京:化学工业出版社,2004
[3] 李晓静. 液晶显示控制器与单片机的接口及编程[J],电子技术,2004
[4] 潘新民,王艳芳. 微型计算机控制技术[M],北京:电子工业出版社,2004
[5] 朱清慧,张凤蕊等. Proteus教程——电子线路设计、制版与仿真[M],北京:清华大学出版社,2008
[6] 徐科军. 传感器与检测技术[M],北京:电子工业出版社,2008
附录:Proteus图
附录:程序
#include<reg52.h>
#include<intrins.h>
#include<string.h>
#define uint unsigned int
#define uchar unsigned char
//---------------------------------
sbit BEEP=P3^0; //蜂鸣器
sbit JDQ=P3^1;
sbit rs = P3^5; //1602液晶
sbit wela = P3^6; //1602液晶
sbit lcden = P3^7;
#define C02_write 0xa0 //写
#define C02_read 0xa1 //读
sbit SCL=P3^4; //时钟
sbit SDA_EEPROM=P3^3; //数据
bit ack;
bit dd;
uchar IIC_Password[8]=""; //IIC密码
uchar DSY_BUFFER[8]=""; //显示缓冲
uchar UserPassword[8]=""; //使用者密码
uchar TwoPassword[8]=""; //使用者密码
uchar OnePassword[8]=""; //使用者密码
uchar KeyNo =16;
//---------------------------------
sbit IR=P3^2; //红外接口标志
char code Tab[16]="0123456789ABCDEF";
unsigned char irtime;//红外用全局变量
bit irpro_ok,irok;
unsigned char IRcord[4];
unsigned char irdata[33];
void Ir_work(void);
void Ircordpro(void);
//---------------1602--------------------------------------
void delayms(uint z) //延时N ms
{
uint x,y;
for(x=z;x>0;x--)
for(y=120;y>0;y--);
}
void write_com(uchar com) //1602液晶写指令
{
rs=0;
lcden=0;
P1=com;
delayms(1);
lcden=1;
delayms(2);
lcden=0;
}
void write_date(uchar date) //1602液晶写数据
{
rs=1;
lcden=0;
P1=date;
delayms(1);
lcden=1;
delayms(2);
lcden=0;
}
void init_lcd(void) //初始化液晶,及画面初始化
{
// uchar num;
wela=0;
lcden=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
}
//指定x,y写入字符串函数
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0){write_com(0x80 + x);} //第一行
else{write_com(0xC0 + x);} //第二行
while (*s) //
{write_date( *s); s++;} //写入数据
}
void tim0_isr (void) interrupt 1 using 1
{
irtime++; //用于计数2个下降沿之间的时间
}
void EX0_ISR (void) interrupt 0 //外部中断1服务函数
{
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;
}
}
void TIM0init(void)//定时器0初始化
{
TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
TH0=0x00; //重载值
TL0=0x00; //初始化值
ET0=1; //开中断
TR0=1;
}
void EX0init(void)
{
IT0 = 1; //指定外
展开阅读全文