基于单片机的电子密码锁设计

更新时间:2024-05-28 01:24:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

摘要

本论文详细地论述了以单片机为处理器的密码锁自动控制器的硬件、软件设计和系统编程的问题。本控制器以ATMEL公司的AT89S51单片机为核心键盘、显示电路,输出控制电路,告警提示电路等构成。

利用目前使用的微处理器AT89S51 作为控制元件设计了一种电子密码锁。其具有可设置多组密码、多次改写和保存密码的优点,克服了普通锁需要随身携带钥匙且易丢失、保密性差的缺点,在宾馆、办公大楼、仓库、保险柜和家庭普遍适用。

关键词 AT89S51 LCD12864 电子密码锁 4×4矩阵键盘

I

Abstract

The hardware layout and software development for single chip microprocessor Electronic Trick Lock controller and system programming are presented in detail in this paper. Based on the ATMEL company’s AT89C51 single chip microprocessor, the whole system consists of keyboard and display circuit, output control signal circuit, alarm circuit and so on.

Used present microprocessor AT89C52 as control part, designed a electronic trick lock. It can be set up some cipher code, changed many times and kept cipher code. It overcame the weakness of common lock that must take key and be lost easily. It is suitable to hotel, offices of building, storehouses, safes and families.

Key words AT89S51 LCD12864 Electronic password lock 4×4 keyboard

II

目录

第一章 绪论 ............................................................. 1

1.1 课题背景和意义 .................................................. 1 1.2 电子密码锁发展趋势 .............................................. 2 第二章 总体设计方案的确定 ............................................... 3

2.1 电子密码锁设计的具体要求 ........................................ 3 2.2 总体设计方案选定 ................................................ 3 第三章 系统硬件设计 ..................................................... 5

3.1 单片机AT89S51简介 .............................................. 5

3.1.1 主要特性 .................................................. 5 3.1.2 引脚功能说明 .............................................. 6 3.2 AT89S51相对于89C51增加的新功能包括: .......................... 7 3.3 液晶显示FYD12864的介绍 ......................................... 8

3.3.1 基本特性 .................................................. 8 3.3.2方框图 .................................................... 9 3.3.3模块接口说明 .............................................. 9 3.4 硬件电路的设计 ................................................. 11

3.4.1 最小系统的设计 ........................................... 11 3.4.2 芯片擦除 ................................................. 13 3.4.3 开锁机构 ................................................. 13 3.4.4 键盘设计 ................................................. 14 3.4.5显示电路设计 ............................................. 15 3.5 电路设计总图 ................................................... 16 第四章 系统软件设计 .................................................... 18

4.1 主程序模块 ..................................................... 18 4.2 键盘扫描及识别子程序 ........................................... 19 4.3 系统模块密码设置子程序 ......................................... 21 4.4 程序调试 ....................................................... 21 参考文献 ............................................................... 24 附录Ⅰ 电子密码锁整体设计图 ........................................... 25 附录II 电子密码锁整体PCB设计图 ...................................... 26 附录III 电子密码锁程序源代码 .......................................... 27

I

第一章 绪论

1.1 课题背景和意义

随着电子技术和计算机技术的飞速发展,单片机性能不断完善,性能价格比显著提高,技术日趋完善。由于单片机具有体积小、重量轻、价格便宜、功耗低、控制功能强及运算速度快等特点,因而在国民经济建设、军事及家用电器等各个领域均得到了广泛的应用。本设计利用单片机及附加电子元器件实现数据采集和控制算法,来完成某一实际功能,检验并提高同学对整体电路设计和把握能力,了解单片机系统设计流程,以及电路板的实际制作和调试能力。同时也加强对数字电路、单片机和微机原理等课程知识的实际应用能力,也为同类产品的进一步发展奠定理论和实践基础。

随着人们生活水平的提高和安全意识的加强,对安全的要求也就越来越高。锁自古以来就是把守护门的铁将军,人们对它要求甚高,既要安全可靠的防盗,又要使用方便,这也是制锁者长期以来研制的主题。随着电子技术的发展,各类电子产品应运而生,电子密码锁就是其中之一。据有关资料介绍,电子密码锁的研究从20世纪30年代就开始了,在一些特殊场所早就有所应用。这种锁是通过键盘输入一组密码完成开锁过程。研究这种锁的初衷,就是为提高锁的安全性。由于电子锁的密钥量(密码量)极大,可以与机械锁配合使用,并且可以避免因钥匙被仿制而留下安全隐患。电子锁只需记住一组密码,无需携带金属钥匙,免除了人们携带金属钥匙的烦恼,而被越来越多的人所欣赏。电子锁的种类繁多,例如数码锁,指纹锁,磁卡锁,IC卡锁,生物锁等。但较实用的还是按键式电子密码锁。

20世纪80年代后,随着电子锁专用集成电路的出现,电子锁的体积缩小,可靠性提高,成本较高,是适合使用在安全性要求较高的场合,且需要有电源提供能量,使用还局限在一定范围,难以普及,所以对它的研究一直没有明显进展。

目前,在西方发达国家,电子密码锁技术相对先进,种类齐全,电子密码锁已被广泛应用于智能门禁系统中,通过多种更加安全,

1

更加可靠的技术实现大门的管理。在我国电子锁整体水平尚处于国际上70年代左右,电子密码锁的成本还很高,市场上仍以按键电子锁为主,按键式和卡片钥匙式电子锁已引进国际先进水平,现国内有几个厂生产供应市场。但国内自行研制开发的电子锁,其市场结构尚未形成,应用还不广泛。国内的不少企业也引进了世界上先进的技术,发展前景非常可观。希望通过不断的努力,使电子密码锁在我国也能得到广泛应用

1.2 电子密码锁发展趋势

电子密码锁应用于金融业,其根本的作用是“授权”,即被“授权”的人才可以存取钱、物。广义上讲,金融业的“授权”主要包括以下三种层次的内容:1、授予保管权,如使用保管箱、保险箱和保险柜;2、授予出入权,如出入金库、运钞车和保管室;3、授予流通权,如自动存取款。目前,金融行业电子密码锁的应用主要集中在前两个层面上。下面将介绍几种在金融行业中使用较多的电子密码锁以及它们的技术发展方向。当然,以上所说的授权技术再高超,都必须由精良的“锁具”担当承载结构部件,实现开启、闭锁的功能,而且承担实体防护作用,抵抗住或尽量延迟破坏行为,让电子密码锁“软、硬不吃”。一般情况下,锁具防盗的关键是锁身外壳、闭锁的部件的强度、锁止型式、配合间隙和布局。提高电子密码锁之防护能力的必然途径是报警,在金融业的许多场所有人值守、有电视监控,具有报警功能,可以综合物理防范和人力防范两种作用。报警的前提是具备探测功能,根据电子密码锁的使用场所和防护要求,可选择多种多样的探测手段。在中国的城市金融业中,实现联网报警已经成为对各金融网点的基本要求。根据国内外的实践经验,金融业实行安全防范风险等级很有必要,即依据使用的防盗报警器材的性能、安装布局和人员值守状况等,可以评估被防护物或区域的防护能力,得出风险等级,其中,电子密码锁的性能至关重要。

由于数字、字符、图形图像、人体生物特征和时间等要素均可成为钥匙的电子信息,组合使用这些信息能够使电子密码锁获得高度的保密性,如防范森严的金库,需要使用复合信息密码的电子密码锁,这样对盗贼而言是“道高一尺、魔高一丈”。组合使用信息也能够使电子密码锁获得无穷扩展的可能,使产品多样化,对用户而言是“千挑百选、自得其所”。

2

第二章 总体设计方案的确定

2.1 电子密码锁设计的具体要求

(1)本设计为了防止密码被窃取要求在输入密码时在LCD屏幕上显示*号。 (2)设计开锁密码位六位密码的电子密码锁。

(3)能够LCD显示在密码正确时显示PASSWORD OK,密码错误时显示PASSWORD ERROR,输入密码时显示INPUT PASSWORD。

(4)实现输入密码错误超过限定的三次电子密码锁定。 (5)4×4的矩阵键盘其中包括0-9的数字键和A-F的功能键

(6)本产品具备报警功能,当输入密码错误时蜂鸣器响并且LED灯亮。

(7)密码可以由用户自己修改设定(只支持6位密码),修改密码之前必须再次输入

密码,在输入新密码时候需要二次确认,以防止误操作 。

2.2 总体设计方案选定

方案一:采用数字电路控制。

用以74LS112双JK触发器构成的数字逻辑电路作为密码锁的核心控制,共设了9个用户输入键,其中只有4个是有效的密码按键,其它的都是干扰按键,若按下干扰键,键盘输入电路自动清零,原先输入的密码无效,需要重新输入;如果用户输入密码的时间超过10秒(一般情况下,用户不会超过10秒,若用户觉得不便,还可以修改)电路将报警20秒,若电路连续报警三次,电路将锁定键盘2分钟,防止他人的非法操作。采用数字电路设计的方案好处就是设计简单但控制的准确性和灵活性差。故不采用。

方案二:采用一种是用以AT89S51为核心的单片机控制方案。

选用单片机AT89S51 作为本设计的核心元件,利用单片机灵活的编程设计和丰富的IO端口,及其控制的准确性,实现基本的密码锁功能。在单片机的外围电路外接输入键盘用于密码的输入和一些功能的控制,外接LCD1602显示器用于显示作用。其原理如下图2.1所示:

3

图2.1 单片机控制密码锁原理图

可以看出方案二控制灵活准确性好且保密性强还具有扩展功能,根据现实生活的需要此次设计采用此方案

4

第三章 系统硬件设计

3.1 单片机AT89S51简介

AT89S51是美国ATMEL公司生产的低功耗,高性能CMOS8位单片机,片内含4k bytes的可系统编程的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准8051指令系统及引脚。它集Flash程序存储器,既可在线编程(ISP)也可用传统方法进行编程及通用8位微处理器于单片芯片中,ATMEL公司的功能强大,低价位AT89S51单片机可为您提供许多高性价比的应用场合,可灵活应用于各种控制领域。

3.1.1 主要特性

??与MCS-51 兼容

??4K字节可编程闪烁存储器 ??寿命:1000写/擦循环 ??数据保留时间:10年 ??全静态工作:0Hz-24Hz ??三级程序存储器锁定 ??128*8位内部RAM ??32可编程I/O线

??两个16位定时器/计数器 ??5个中断源 ??可编程串行通道

??低功耗的闲置和掉电模式 ??片内振荡器和时钟电路

5

3.1.2 引脚功能说明

图2.2 单片机引脚图

Vcc:电源电压 GND:接地

P0口:P0口是一组8位漏极开路型双向I/0口,也即地址/数据总线复用口。作为输出口用时,每位能驱动8个TTL逻辑门电路,对端口写“1”可作为高阻抗输入端用。在访问外部数据存储器或程序存储器时,这组口线分时转换地址(低8位)和数据总线复用,在访问期间激活内部上拉电阻。在F1ash编程时,P0口接收指令字节,而在程序校验时,输出指令字节,校验时,要求外接上拉电阻。

P1口:Pl 是一个带内部上拉电阻的8位双向I/O口,Pl的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对端口写“l”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流(IIL),Flash编程和程序校验期间,Pl接收低8位地址。

P2 口:P2 是一个带有内部上拉电阻的8 位双向I/O 口,P2 的输出缓冲级可驱动(吸收或输出电流)4 个TTL逻辑门电路。对端口写“1”,通过内部的上拉电阻把端口拉到高电

6

平,此时可作输入口,作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流(IIL),在访问外部程序存储器或16位地址的外部数据存储器(例如执行MOVX@DPTR指令)时,P2口送出高8位地址数据。在访问8 位地址的外部数据存储器(如执行MOVX@Ri 指令)时,P2 口线上的内容(也即特殊功能寄存器(SFR)区中P2寄存器的内容),在整个访问期间不改变。Flash编程或校验时,P2亦接收高位地址和其它控制信号。

P3 口:P3 口是一组带有内部上拉电阻的8 位双向I/0 口。P3 口输出缓冲级可驱动(吸收或输出电流)4 个TTL逻辑门电路。P3口除了作为一般的I/0口线外,更重要的用途是它的第二功能,如下表所示:P3口还接收一些用于Flash闪速存储器编程和程序校验的控制信号

RST:复位输入。当振荡器工作时,RST引脚出现两个机器周期以上高电平将使单片机复位。WDT 溢出将使该引脚输出高电平,设置SFR AUXR的DISRT0 位(地址8EH)可打开或关闭该功能。DISRT0位缺省为RESET输出高电平打开状态。

ALE/PROG:当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。即使不访问外部存储器,ALE 仍以时钟振荡频率的1/6 输出固定的正脉冲信号,因此它可对外输出时钟或用于定时目的。

PSEN:程序储存允许(PSEN)输出是外部程序存储器的读选通信号,当AT89S51 由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN有效,即输出两个脉冲。当访问外部数据存储器,没有两次有效的PSEN信号。

EA/VPP:外部访问允许。欲使CPU仅访问外部程序存储器(地址为0000H-FFFFH),EA端必须保持低电平(接地)。需注意的是:如果加密位LB1被编程,复位时内部会锁存EA端状态。如EA端为高电平(接Vcc端),CPU则执行内部程序存储器中的指令。F1ash存储器编程时,该引脚加上+12V的编程电压Vpp。

XTALl:振荡器反相放大器及内部时钟发生器的输入端。 XTAL2:振荡器反相放大器的输出端。

3.2 AT89S51相对于89C51增加的新功能包括:

(1)ISP在线编程功能,这个功能的优势在于改写单片机存储器内的程序不需要把芯片从工作环境中剥离,是一个强大易用的功能。

(2)最高工作频率为33MHz,89C51的极限工作频率为24MHz,就是说S51具有更高的工

7

作频率,从而具有了更快的计算速度。

(3)具有双工UART串行通道。

(4)内部集成看门狗计时器,不再需要像C51那样外接看门狗计时器单元电路。 (5)双数据指示器。 (6)电源关闭标识。

(7)全新的加密算法,这使得对于89S51的解密变为不可能,程序的保密性大大加强,这样就可以有效地保护知识产权不被侵犯。

(8)兼容性方面:向下完全兼容51全部字系列产品。

(9)程序存储器写入方式:二者的写入程序的方式不同,89C51只支持并行写入,同时需要VPP烧写高压。89S51则支持Isp在线编程写入技术。串行写入、速度更快、稳定性更好,烧写电压也仅仅需要4~5V即可。

(10)电源范围:89S51电源范围宽达4~5.5V,而89C51在低于4.8V和高于5.3V的时候则无法正常工作。

(11)烧写寿命更长:89S51标称的1000次,实际最少是1000~10000次,这样更有利于初学者反复烧写,降低学习成本。 综上所述本设计选定AT89S51。

3.3 液晶显示FYD12864的介绍 3.3.1 基本特性

低电源电压(VDD:+3.0--+5.5V); 显示分辨率:128×64点;

内置汉字字库,提供8192个16×16点阵汉字(简繁体可选); 内置 128个16×8点阵字符; 2MHZ时钟频率;

显示方式:STN、半透、正显; 驱动方式:1/32DUTY,1/5BIAS; 驱动方式:1/32DUTY,1/5BIAS; 视角方向:6点;

8

通讯方式:串行、并口可选;

工作温度: 0℃ - +55℃ ,存储温度: -20℃ - +60℃;

3.3.2方框图

3.3.3模块接口说明

串口接口

9

*注释1:如在实际应用中仅使用串口通讯模式,可将PSB接固定低电平,也可以将模块上的J8和“GND”用焊锡短接。

*注释2:模块内部接有上电复位电路,因此在不需要经常复位的场合可将该端悬空。 *注释3:如背光和模块共用一个电源,可以将模块上的JA、JK用焊锡短接。

并行接口

管管脚脚号 名称 1 VSS 2 VCC 3 4 S) 5 R/W(SID) E(SCLK) DB0 DB1 DB2 DB3 DB4 DB5 DB6 DB7 PSB NC /RESET 18 19 20 VOUT A K V0 RS(C电平 0V 3.0+5V - 管脚功能描述 电源地 电源正 6 7 8 9 10 11 12 13 14 15 16 17 对比度(亮度)调整 RS=“H”,表示DB7——DB0为显示数据 H/L RS=“L”,表示DB7——DB0为显示指令数据 R/W=“H”,E=“H”,数据被读到DB7——DB0 H/L R/W=“L”,E=“H→L”, DB7——DB0的数据被写到IR或DR H/L 使能信号 H/L H/L H/L H/L H/L H/L H/L H/L H/L - H/L - VDD VSS 三态数据线 三态数据线 三态数据线 三态数据线 三态数据线 三态数据线 三态数据线 三态数据线 H:8位或4位并口方式,L:串口方式(见注释1) 空脚 复位端,低电平有效(见注释2) LCD驱动电压输出端 背光源正端(+5V)(见注释3) 背光源负端(见注释3) *注释1:如在实际应用中仅使用并口通讯模式,可将PSB接固定高电平,也可以将模块上的J8和“VCC”用焊锡短接。

*注释2:模块内部接有上电复位电路,因此在不需要经常复位的场合可将该端悬空。 *注释3:如背光和模块共用一个电源,可以将模块上的JA、JK用焊锡短接。

10

3.4 硬件电路的设计

本设计单片机硬件资源的分配:

P0.0~P0.7用于LCD液晶显示作用。 P3.0、P3.7用于蜂鸣器和报警灯的控制。 P2.0用于开锁电路的控制。 P1.0~P1.7用于键盘电路的控制。

P2.0~P2.4用于LCD显示模块的控制端口的控制。

3.4.1 最小系统的设计

当MCS-5l系列单片机的复位引脚RST(全称RESET)出现2个机器周期以上的高电平时,单片机就执行复位操作。如果RST持续为高电平,单片机就处于循环复位状态。根据应用的要求,复位操作通常有两种基本形式:上电复位和开关复位。图3.3即为手动(开关)复位电路。

图3.3 手动复位电路

复位后的状态

a、复位后PC值为0000H,表明复位后的程序从0000H开始执行。 b、SP值为07H,表明堆栈底部在07H,一般需要重新设置SP值。

c、P0~P3口值为FFH。P0~P3口用作输入口时,必须先写入“1”。单片机在复位后,已使P0~P3口每一端线为“1”,为这些端线用作输入口做好了准备。

11

WDT 溢出将使该引脚输出高电平,所以本设计采用图3.4的手动复位电路:

C322uR9100R 图3.4 本设计手动复位电路

AT89S51 中有一个用于构成内部振荡器的高增益反相放大器,引脚XTAL1 和XTAL2 分别是该放大器的输入端和输出端。这个放大器与作为反馈元件的片外石英晶体或陶瓷谐振器一起构成自激振荡器,振荡电路参见图3.5。外接石英晶体(或陶瓷谐振器)及电容Cl、C2 接在放大器的反馈回路中构成并联振荡电路。对外接电容Cl、C2 虽然没有十分严格的要求,但电容容量的大小会轻微影响振荡频率的高低、振荡器工作的稳定性、起振的难易程序及温度稳定性。如果使用石英晶体,我们推荐电容使用30pF±10pF,而如使用陶瓷谐振器建议选择40pF±10F。用户也可以采用外部时钟。采用外部时钟的电路如图1所示。这种情况下,外部时钟脉冲接到XTAL1端,即内部时钟发生器的输入端,XTAL2则悬空。由于外部时钟信号是通过一个2分频触发器后作为内部时钟信号的,所以对外部时钟信号的占空比没有特殊要求,但最小高电平持续时间和最大的低电平持续时间应符合产品技术条件的要求。

图3.5 单片机自激震荡电路

12

由于单片机有内部振荡器,所以本设计采用图3.6的晶振电路:

C133pX2CRYSTALC233p图3.6 晶振电路

C3 3.4.2 芯片擦除

整个PEROM阵列和三个锁定位的电擦除可通过正确的控制信号组合,并保持ALE管脚处于低电平10ms 来完成。在芯片擦操作中,代码阵列全被写“1”且在任何非空存储字节被重复编程以前,该操作必须被执行。

此外,AT89S51设有稳态逻辑,可以在低到零频率的条件下静态逻辑,支持两种软件可选的掉电模式。在闲置模式下,CPU停止工作。但RAM,定时器,计数器,串口和中断系统仍在工作。在掉电模式下,保存RAM的内容并且冻结振荡器,禁止所用其他芯片功能,直到下一个硬件复位为止。

3.4.3 开锁机构

用户通过LCD提示信息,用键盘输入正确密码,从而达到开锁的目的。当用户输入的密码正确并且是在按下确定键的话,单片机便输出开门信号,送到开锁驱动 电路,然后驱动电磁锁,达到开门的目的。电路驱动和开锁两级组成。由D5、R1、T10组成驱动电路,其中T10可以选择普通的小功率三极管如9014、9018都可以满足要求。D5作为开锁的提示;由D6、C24、T11组成。其中D6、C24是为了消除电磁锁可能产生的反向高电压以及可能产生的电磁干扰。T11可选用中功率的三极管如8050,电磁锁的选用要视情况而定,但是吸合力要足够且由一定的余量。

13

在本次设计中,基于节省材料的原则,暂时用发光二极管代替电磁锁,发光管亮,表示开锁;灭,表示没有开锁。

图3.7 密码锁开锁机构电路图

3.4.4 键盘设计

本设计就采用行列式键盘,同时也能减少键盘与单片机接口时所占用的I/O线的数目,在按键比较多的时候,通常采用这样方法。

每一条水平(行线)与垂直线(列线)的交叉处不相通,而是通过一个按键来连通,利用这种行列式矩阵结构只需要N条行线和M条列线,即可组成具有N×M个按键的键盘。

在这种行列式矩阵键盘非键盘编码的单片机系统中,键盘处理程序首先执行等待按键并确认有无按键按下的程序段。

4×4矩阵键盘的工作原理

在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式,如图5所示。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。

扫描原理

把每个键都分成水平和垂直的两端接入,比如说扫描码是从垂直的入,那就代表那一

14

行所接收到的扫描码是同一个bit,而读入扫描码的则是水平,扫描的动作是先输入扫描码,再去读取输入的值,经过比对之后就可知道是哪个键被按下。

比如说扫描码送入01111111,前面的0111是代表此时扫描第一行P1.0列,而后面的1111是让读取的4行接脚先设为VDD,若此时第一行的第三列按键被按下,那读取的结果就会变成01111101(注意1111变成1101),其中LSB的第三个bit会由1变成0,这是因为这个按键被按下之后,会被垂直的扫描码电位short,而把读取的LSB的bit电位拉到0,此即为扫描原理。

由於这种按键是机械式的开关,当按键被按下时,键会震动一小段时间才稳定,为了避免让8051误判为多次输入同一按键,

我们必须在侦测到有按键被按下,就Delay一小段时间,使键盘以达稳定状态,再去判读所按下的键,就可以让键盘的输入稳定。图3.8为键盘整体模框图:

图3.8 键盘整体模框图

3.4.5显示电路设计

显示设计采用字符型液晶屏设计,由单片机的p0口控制显示,由p2.0~p2.4控制lcd的控制端口。

本设计采用以下液晶显示设计:

15

图3.9 LCD液晶显示电路抓图

3.5 电路设计总图

Proteus软件是Labcenter Electronics公司的一款电路设计与仿真软件,它包括ISIS、ARES等软件模块,ARES模块主要用来完成PCB的设计,而ISIS模块用来完成电路原理图的布图与仿真。Proteus的软件仿真基于VSM技术,它与其他软件最大的不同也是最大的优势就在于它能仿真大量的单片机芯片,比如MCS-51系列、PIC系列等等,以及单片机外围电路,比如键盘、LED、LCD等等。通过Proteus软件的使用我们能够轻易地获得一个功能齐全、实用方便的单片机实验室。

本密码锁采用proteus进行电路图设计,经过元件选型,用万能实验版进行硬件焊接,以实现硬件部分。

下图为proteus设计的密码锁电路图整体抓图

16

17

第四章 系统软件设计

因设计主要是作用汇编语言来开发的51单片机项目程序,所以首先必须有一个可以在Windows XP或Windows vista操作系统下执行的汇编语言编译器,本设计采用Keil编译器进行编程,因为它可以支持一系列的51单片机。

开初始化 旧密新密存入再次输入重模式识别按手密码输设置完毕密码比开

图4.1 主程序的流程图

4.1主程序模块

主程序主要是完成系统初始化、设置中断向量、检查有无键按下、以及调用显示等等。主程序部分如下所示:

void main() {

uchar m=0; EA=1; EX0=1;

18

IT0=0; LED=0; LED1=0;

InitLCD();//初始12864

ClearScreen(0);//清屏 SetStartLine(0);//显示开始行

while(1)

{ jianpan(); if(flag==2) {

}

if(m==3)

{ }

if(flag==1) {

}

} }

void EX_INT0() interrupt 0 { }

shizhi();

delay(2000);

4.2 键盘扫描及识别子程序

键盘采用查询的方式,放在主程序中,当没有按键按下的时候,单片机循环主程序,一旦有按键按下,便转向相应的子程序处理,处理结束再返回。其程序流程如图4.2所示

键盘部分程序如下: key:

;键盘程序名称

call ks

;调用子程序ks

19

jnz k1 jmp key

;判断是否有键按下 ;跳回键盘程序

ks:mov p1,#0f0h; mov a,p1; xrl a,#0f0h; ret;

图4.2 键盘扫描程序流程图

20

4.3系统模块密码设置子程序

由于设计是分模块化进行,所以子程序是整体软件系统的组成部分,子程序不但可以使程序化整为零,使其复杂简单化,同时也方便阅读,修改等,每个功能模块都有它自己的子程序,在本设计中是用LCD显示数据,所以就要用到显示子程序,设计中用的是矩阵键盘,所以就用到键盘扫描子程序,例如还有显示初始化子程序、LCD忙检测子程序、关闭状态显示子程序、开锁状态显示子程序、密码输入及修改状态显示子程序、密码输入错误后的提示子程序等。如下图为密码修改子程序流程图

选旧密码新密码存入缓重新再次输是否大比较密锁返

图4.3 设置密码子程序

4.4程序调试

在硬件支持的环境下,用proteus设计好的电路,Keil编好的程序编译成芯片可识别的S51文件,利用PC机写进proteus程序图芯片内进行仿真测试,并对其出现的错误进行修改,由图4.4~图4.8可看出最终调试成功。

21

图4.4 keil编译程序成功

图4.5 keil生成hex文件

图4.6 proteus调用keil的hex文件进行仿真

22

图4.7 仿真成功密码正确

图4.8 密码正确绿灯亮

23

参考文献

[01] 何宏主编. 单片机原理与接口技术. 北京:国防工业出版社. 2006.07 [02] 杨西明, 朱骐主编. 单片机编程与应用入门. 北京:机械工业出版社.2004.06 [03] 先锋工作室编著. 单片机程序设计实例. 北京: 清华大学出版社.2003.01 [04] 谢宜仁主编. 单片机实用技术问答. 北京: 人民邮电出版社. 2003.02 [05] 梁丽.电子密码锁的计算机仿真设计.计算机仿真.2005

[06] 房小翠,王金凤编著. 单片机实用系统设计技术. 北京: 国防工业出版社. 1999.06 [07] 王宽仁. 可靠安全的智能密码锁. 电子技术应用 . 2001

[08] 董继成. 能防止多次试探密码的单片机密码锁.国外电子元器件. 2004.3 [09] 李朝清. PC机及单片机数据通信技术. 北京:北京航空航天大学出版社. 1999. [10] 路而红.专用集成电路设计与电子设计自动化.北京:清华大学出版社. 2004 [11] 刘文涛.MCS-51单片机培训教程(C51)版.电子工业出版社. 2005.8 [12] 王为青 程国钢.单片机Keil Cx51 应用开发技术.人民邮电出版社.2007.2 [13] 范风强 兰婵丽.单片机语言C51应用实战集锦.电子工业出版社. 2003.3 [14] 龚运新.单片机C语言开发技术.清华大学出版社. 2006.10 [15] 邵贝贝.单片机嵌入式应用的在线开发方法.清华大学出版社. 2006.3 [16] 王宜怀.单片机原理及其嵌入式应用教程.北京希望电子出版社. 2002.8

24

附录Ⅰ 电子密码锁整体设计图

LCD2LM016LVSSVDDVEERSRWE45610k10k10k10k10k10k10k10kw7w1w2w3w4w5w6w8123C133pX2CRYSTAL19U1XTAL1P0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7P2.0/A8P2.1/A9P2.2/A10P2.3/A11P2.4/A12P2.5/A13P2.6/A14P2.7/A15P3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RD393837363534333221222324252627281011121314151617w1w2w3w4w5w6w7w8vccp2.0C233p18XTAL2C3922uRSTR9100R293031PSENALEEAR21kQ1NPNR31kD1LED-REDSPEAKERh1l4h2h3h4123F456E789DA0BCl11l22l33l44h45h36h27h18P1.0/T2P1.1/T2EXP1.2P1.3P1.4P1.5P1.6P1.7AT89C52DIL4012MHzl3l1l2Q2p2.0NPNR4100Rw17w28w39w410w511w612w713w814D0D1D2D3D4D5D6D7LS1RL1G4W-1114P-12VD2LED-GREEN 25

附录II 电子密码锁整体PCB设计图

26

附录III 电子密码锁程序源代码

/****project.c************/ #include #include #include sbit LED=P3^7; sbit LED1=P3^0; #include \#include \#include \void main() { uchar m=0; EA=1; EX0=1; IT0=0; LED=0; LED1=0;

InitLCD();//初始12864

ClearScreen(0);//清屏 SetStartLine(0);//显示开始行 Display(2,0,0*16,0); Display(2,0,1*16,1); Display(2,0,2*16,2); Display(2,0,3*16,3);

Display(1,0,0*16,4);

while(1)

{

27

jianpan(); if(flag==2) {

ClearScreen(0);//清屏

SetStartLine(0);//显示开始行

Display(2,0,0*16,9); Display(2,0,1*16,10); Display(2,0,2*16,11); Display(2,0,3*16,12); flag=0; LED=0; delay(2000);

ClearScreen(0);//清屏

SetStartLine(0);//显示开始行

Display(2,0,0*16,0); } if(m==3)

{ }

LED1=1; m=0;

Display(2,0,1*16,1); Display(2,0,2*16,2); Display(2,0,3*16,3); Display(1,0,0*16,4); m++;

if(flag==1) {

ClearScreen(0);//清屏

SetStartLine(0);//显示开始行

28

Display(2,0,0*16,5); Display(2,0,1*16,6); Display(2,0,2*16,7); Display(2,0,3*16,8); flag=0; LED=1;

}

} }

void EX_INT0() interrupt 0 { ClearScreen(0);//清屏 SetStartLine(0);//显示开始行 Display(2,0,0*16,13); Display(2,0,1*16,14); Display(2,0,2*16,15); Display(2,0,3*16,16); shizhi(); delay(2000);

ClearScreen(0);//清屏

SetStartLine(0);//显示开始行 Display(2,0,0*16,0); Display(2,0,1*16,1); Display(2,0,2*16,2); Display(2,0,3*16,3); Display(1,0,4*16,4);

}

/*******12864.h*************/ #define uint unsigned int #define uchar unsigned char

29

#define ulong unsigned long

#define DATA P0 //LCD12864数据线 sbit RS=P2^2; // 数据\\指令 选择 sbit RW=P2^1; // 读\\写 选择 sbit EN=P2^0; // 读\\写使能 sbit cs1=P2^4; // 片选1 sbit cs2=P2^3; // 片选2

/********************************/ /* 定义中文字库

*/

/********************************/ uchar code Hzk[]={

/*-- 文字: 输 0 --*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x88,0x68,0x1F,0xC8,0x08,0x10,0xC8,0x54,0x52,0xD1,0x12,0x94,0x08,0xD0,0x10, 0x00, 0x09,0x19,0x09,0xFF,0x05,0x00,0xFF,0x12,0x92,0xFF,0x00,0x5F,0x80,0x7F,0x00, 0x00, /*-- 文字: 入 1--*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x00,0x00,0x00,0x00,0x00,0x01,0xE2,0x1C,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, 0x00, 0x80,0x40,0x20,0x10,0x0C,0x03,0x00,0x00,0x00,0x03,0x0C,0x30,0x40,0x80,0x80, 0x00, /*-- 文字: 密 2--*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x10,0x8C,0x44,0x04,0xE4,0x04,0x95,0xA6,0x44,0x24,0x14,0x84,0x44,0x94,0x0C, 0x00, 0x02,0x02,0x7A,0x41,0x41,0x43,0x42,0x7E,0x42,0x42,0x42,0x43,0xF8,0x00,0x00, 0x00,

/*-- 文字: 码 3--*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x04,0x84,0xE4,0x5C,0x44,0xC4,0x00,0x02,0xF2,0x82,0x82,0x82,0xFE,0x80,0x80, 0x00, 0x02,0x01,0x7F,0x10,0x10,0x3F,0x00,0x08,0x08,0x08,0x08,0x48,0x88,0x40,0x3F, 0x00, /*-- 文字: : 4--*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

30

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00, 0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00, /*-- 文字: 密 5--*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x10,0x8C,0x44,0x04,0xE4,0x04,0x95,0xA6,0x44,0x24,0x14,0x84,0x44,0x94,0x0C, 0x00, 0x02,0x02,0x7A,0x41,0x41,0x43,0x42,0x7E,0x42,0x42,0x42,0x43,0xF8,0x00,0x00, 0x00, /*-- 文字: 码 6--*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x04,0x84,0xE4,0x5C,0x44,0xC4,0x00,0x02,0xF2,0x82,0x82,0x82,0xFE,0x80,0x80, 0x00, 0x02,0x01,0x7F,0x10,0x10,0x3F,0x00,0x08,0x08,0x08,0x08,0x48,0x88,0x40,0x3F, 0x00, /*-- 文字: 正 7--*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x00,0x02,0x02,0xC2,0x02,0x02,0x02,0xFE,0x82,0x82,0x82,0x82,0x82,0x02,0x00, 0x00, 0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40, 0x00, /*-- 文字: 确 --8*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x04,0x84,0xE4,0x5C,0x44,0xC4,0x20,0x10,0xE8,0x27,0x24,0xE4,0x34,0x2C,0xE0, 0x00, 0x02,0x01,0x7F,0x10,0x10,0x3F,0x80,0x60,0x1F,0x09,0x09,0x3F,0x49,0x89,0x7F, 0x00, /*-- 文字: 密 9--*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x10,0x8C,0x44,0x04,0xE4,0x04,0x95,0xA6,0x44,0x24,0x14,0x84,0x44,0x94,0x0C, 0x00, 0x02,0x02,0x7A,0x41,0x41,0x43,0x42,0x7E,0x42,0x42,0x42,0x43,0xF8,0x00,0x00, 0x00, /*-- 文字: 码 10--*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x04,0x84,0xE4,0x5C,0x44,0xC4,0x00,0x02,0xF2,0x82,0x82,0x82,0xFE,0x80,0x80, 0x00, 0x02,0x01,0x7F,0x10,0x10,0x3F,0x00,0x08,0x08,0x08,0x08,0x48,0x88,0x40,0x3F, 0x00, /*-- 文字: 错 11--*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x40,0x30,0xEF,0x24,0x64,0x48,0x48,0x7F,0x48,0x48,0x48,0x7F,0x48,0x48,0x40, 0x00, 0x01,0x01,0x7F,0x21,0x11,0x00,0xFF,0x49,0x49,0x49,0x49,0x49,0xFF,0x00,0x00, 0x00,

31

/*-- 文字: 误 12--*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x40,0x42,0xCC,0x00,0x00,0x80,0x9E,0x92,0x92,0x92,0x92,0x92,0x9E,0x80,0x00, 0x00, 0x00,0x00,0x7F,0x20,0x94,0x84,0x44,0x24,0x14,0x0F,0x14,0x24,0x44,0x84,0x84, 0x00,

/*-- 文字: 设 --13*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x40,0x41,0xCE,0x04,0x00,0x80,0x40,0xBE,0x82,0x82,0x82,0xBE,0xC0,0x40,0x40, 0x00,0x00,0x00,0x7F,0x20,0x90,0x80,0x40,0x43,0x2C,0x10,0x10,0x2C,0x43,0xC0, 0x40, 0x00,

/*-- 文字: 置 --14*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x00,0x20,0x2F,0xA9,0xA9,0xAF,0xE9,0xB9,0xA9,0xAF,0xA9,0xA9,0x2F,0x20,0x00, 0x00,0x80,0x80,0x80,0xFF,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xFF,0x80,0x80, 0x80,0x00,

/*-- 文字: 密 --15*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x00,0x58,0x24,0x04,0xF4,0x04,0x8D,0xB6,0x44,0x34,0xCC,0x94,0x24,0xCC,0x04, 0x00,0x02,0x06,0x02,0x79,0x41,0x41,0x41,0x7D,0x41,0x41,0x41,0x40,0x78,0x00, 0x00,0x00,

/*-- 文字: 码 --16*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x02,0x82,0xE2,0x5E,0x42,0xC2,0x00,0x02,0xFA,0x82,0x82,0x82,0xFE,0x80,0x00, 0x00,0x01,0x00,0x7F,0x10,0x10,0x3F,0x00,0x04,0x04,0x04,0x44,0x84,0x40,0x3F, 0x00,0x00,

/*-- 文字: 为 --17*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x00,0x10,0x10,0x12,0x14,0x1C,0x10,0xF0,0x9F,0x10,0x10,0x10,0x10,0xF8,0x10, 0x00,0x00,0x00,0x40,0x20,0x10,0x08,0x06,0x01,0x00,0x11,0x26,0x40,0x20,0x1F, 0x00,0x00,

/*-- 文字: 五 --18*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

32

0x00,0x02,0x82,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0xC2,0x82,0x02,0x00,0x00, 0x00,0x20,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x30, 0x20,0x00,

/*-- 文字: 位 --19*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x00,0xC0,0x30,0xEC,0x03,0x2A,0xC8,0x09,0x0A,0x0E,0x08,0xE8,0x48,0x08,0x00, 0x00,0x01,0x00,0x00,0x7F,0x20,0x20,0x20,0x27,0x20,0x30,0x2E,0x21,0x20,0x20, 0x20, 0x00,

/*-- 文字: 成 --20*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x00,0x00,0xF8,0x48,0x48,0x48,0xC8,0x08,0xFF,0x08,0x09,0x0A,0xC8,0x88,0x08, 0x00,0x40,0x30,0x0F,0x00,0x08,0x50,0x4F,0x20,0x10,0x0B,0x0C,0x12,0x21,0x40, 0xF0,0x00,

/*-- 文字: 功 --21*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x00,0x04,0x04,0x04,0xFC,0x04,0x14,0x14,0x10,0x90,0x7F,0x10,0x10,0xF0,0x00, 0x00,0x04,0x0C,0x04,0x04,0x03,0x42,0x22,0x11,0x0C,0x23,0x20,0x60,0x20,0x1F, 0x00,0x00,

/*-- 文字: 新 --22*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x20,0x24,0x2C,0x35,0xE6,0x34,0x2C,0x24,0x00,0xFC,0x24,0x24,0xE2,0x22,0x22, 0x00,0x21,0x11,0x4D,0x81,0x7F,0x05,0x59,0x21,0x18,0x07,0x00,0x00,0xFF,0x00, 0x00,0x00,

/*-- 文字: 旧 --23*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/

0x00,0x00,0xFE,0x00,0x00,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0xFE,0x00, 0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x7F,0x20,0x20,0x20,0x20,0x20,0x20,0x7F, 0x00,0x00,

};

/****************************************/ /* 定义ASCII字库8列*16行

*/

/****************************************/ uchar code Ezk[]={ /*-- 文字: 0 --*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/

0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F, 0x00,

33

/*-- 文字: 1 --*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/

0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00, 0x00, /*-- 文字: 2 --*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/

0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30, 0x00, /*-- 文字: 3 --*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/

0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E, 0x00, /*-- 文字: 4 --*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/

0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24, 0x00, /*-- 文字: 5 --*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/

0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E, 0x00, /*-- 文字: 6 --*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/

0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E, 0x00, /*-- 文字: 7 --*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/

0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00, 0x00, /*-- 文字: 8 --*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/

0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C, 0x00, /*-- 文字: 9 --*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/

0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F, 0x00, /*-- 文字: A --*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/

0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38, 0x20,

34

/*-- 文字: B --*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/

0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E, 0x00, /*-- 文字: C --*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/

0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08, 0x00, /*-- 文字: D --*/

/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/

0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F, 0x00, };

/*状态检查,LCD是否忙*/ void CheckState() {

uchar dat;//状态信息(判断是否忙)

RS=0; // 数据\\指令选择,D/I(RS)=“L” ,表示 DB7∽DB0 为显示指令数据 RW=1; //R/W=“H” ,E=“H”数据被读到DB7∽DB0 do{

DATA=0x00; EN=1; //EN下降源

_nop_(); //一个时钟延时 dat=DATA;

EN=0;

dat=0x80 & dat; //仅当第7位为0时才可操作(判别busy信号) }while(!(dat==0x00)); }

/*写命令到LCD中*/

SendCommandToLCD(uchar com) {

CheckState();//状态检查,LCD是否忙

RS=0; //向LCD发送命令。RS=0写指令,RS=1写数据

35

RW=0;//R/W=“L” ,E=“H→L”数据被写到 IR 或 DR DATA=com; //com :命令 EN=1;//EN下降源 _nop_(); _nop_(); EN=0; }

/*设置页 0xb8是页的首地址*/ void SetLine(uchar page) {

page=0xb8|page; //10111xxx 0<=page<=7 设定页地址--X 0-7,8行为一页64/8=8 SendCommandToLCD(page); }

/*设定显示开始行,0xc0是行的首地址*/ void SetStartLine(uchar startline) {

startline=0xc0|startline; //1100 0000

SendCommandToLCD(startline); //设置从哪行开始:0--63,一般从0 行开始显示 }

/*设定列地址--Y 0-63 ,0x40是列的首地址*/ void SetColumn(uchar column) {

column=column &0x3f; //column最大值为64,越出 0=

/*开关显示,0x3f是开显示,0x3e是关显示*/ void SetOnOff(uchar onoff) {

onoff=0x3e|onoff; //0011 111x,onoff只能为0或者1

36

}

SendCommandToLCD(onoff);

/*写显示数据 */ void WriteByte(uchar dat) {

CheckState();//状态检查,LCD是否忙 RS=1; //RS=0写指令,RS=1写数据

RW=0;////R/W=“L” ,E=“H→L”数据被写到 IR 或 DR DATA=dat;//dat:显示数据 EN=1; //EN下降源 _nop_(); _nop_(); EN=0; }

/*选择屏幕screen: 0-全屏,1-左屏,2-右屏*/ void SelectScreen(uchar screen) {

switch(screen) { case 0: cs1=0;//全屏

_nop_(); _nop_(); _nop_(); cs2=0;

_nop_(); _nop_(); _nop_(); break; case 1: cs1=0;//左屏

_nop_(); _nop_(); _nop_(); cs2=1;

_nop_(); _nop_(); _nop_(); break; case 2: cs1=1;//右屏

_nop_(); _nop_(); _nop_();

37

本文来源:https://www.bwwdw.com/article/w677.html

Top