基于12864液晶显示图片

更新时间:2024-06-08 00:19:01 阅读量: 综合文库 文档下载

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

武汉理工大学《能力拓展训练》说明书

1、摘要

本次课程设计基于AT89C52为核心控制器,FYD12864液晶为显示器设计的液晶显示电路。该电路可通过调用FYD12864液晶内部自带的字库(包含8192个标准中文汉字)显示16×16点的中文汉字、16×8的数字及英文字符,该过程只需要像DDRAM中写入要显示的字符的ASCII码,当事先指定显示数据的位置,即可将所需显示的字符显示在液晶的指定位置。使用KNY12864液晶的绘图功能,将所需显示图片或字符的字模数据写入到CGRAM中,开图片显示,即可将该图片或字符同时显示在液晶上。

本次设计的扩展功能为用红外遥控控制图像移动,红外遥控的1、2、3、4、

5、6、7、8八个按键分别控制图像的上移、下移、左移、右移、静止、继续、初始界面、重新设置等八项功能。为实现图像的移动,可通过数据指针改变写入CGRAM的数据,使得输出的图像数据相对于原来在行或者列上按着一定的规律在变化即可,移动速度的快慢可由刷新的频率或者每次移动的行或者列数来决定。至于在液晶上显示动画,为了有更好的动画效果,需要每秒刷新10幅图像,而在该12864液晶上,每幅图像需要1K的ROM空间,而52的ROM空间有限,所以在实现动画上有点困难,故本设计中不实现该功能。

2、软件简介

2.1 Proteus简介

Proteus软件是英国Labcenter electronics公司出版的EDA工具软件(该软件中国总代理为广州风标电子技术有限公司)。它不仅具有其它EDA工具软件的仿真功能,还能仿真单片机及外围器件。它是目前最好的仿真单片机及外围器件的工具。虽然目前国内推广刚起步,但已受到单片机爱好者、从事单片机教学的教师、致力于单片机开发应用的科技工作者的青睐。Proteus是世界上著名的EDA工具(仿真软件),从原理图布图、代码调试到单片机与外围电路协同仿真,一键切换到PCB设计,真正实现了从概念到产品的完整设计。是目前世界上唯一将电路仿真软件、PCB设计软件和虚拟模型仿真软件三合一的设计平台,其处理器模型支持8051、HC11、PIC10/12/16/18/24/30/DsPIC33、AVR、ARM、8086和MSP430等,2010年即将增加Cortex和DSP系列处理器,并持续增加其他系列处理器模型。在编译方面,它也支持IAR、Keil和MPLAB等多种编译器。

Proteus功能模块: (1)智能原理图设计(ISIS)

1

武汉理工大学《能力拓展训练》说明书

丰富的器件库:超过27000种元器件,可方便地创建新元件; 智能的器件搜索:通过模糊搜索可以快速定位所需要的器件;

智能化的连线功能:自动连线功能使连接导线简单快捷,大大缩短绘图时间; 支持总线结构:使用总线器件和总线布线使电路设计简明清晰;

可输出高质量图纸:通过个性化设置,可以生成印刷质量的BMP图纸,可以方便地供WORD、POWERPOINT等多种文档使用。 (2)完善的电路仿真功能(Prospice)

ProSPICE混合仿真:基于工业标准SPICE3F5,实现数字/模拟电路的混合仿真;

超过27000个仿真器件:可以通过内部原型或使用厂家的SPICE文件自行设计仿真器件,Labcenter也在不断地发布新的仿真器件,还可导入第三方发布的仿真器件;

多样的激励源:包括直流、正弦、脉冲、分段线性脉冲、音频(使用wav文件)、指数信号、单频FM、数字时钟和码流,还支持文件形式的信号输入;

丰富的虚拟仪器:13种虚拟仪器,面板操作逼真,如示波器、逻辑分析仪、信号发生器、直流电压/电流表、交流电压/电流表、数字图案发生器、频率计/计数器、逻辑探头、虚拟终端、SPI调试器、I2C调试器等;

生动的仿真显示:用色点显示引脚的数字电平,导线以不同颜色表示其对地电压大小,结合动态器件(如电机、显示器件、按钮)的使用可以使仿真更加直观、生动;

高级图形仿真功能(ASF):基于图标的分析可以精确分析电路的多项指标,包括工作点、瞬态特性、频率特性、传输特性、噪声、失真、傅立叶频谱分析等,还可以进行一致性分析;

(3)独特的单片机协同仿真功能(VSM)

支持主流的CPU类型:如ARM7、8051/52、AVR、PIC10/12、PIC16、PIC18、PIC24、dsPIC33、HC11、BasicStamp、8086、MSP430等,CPU类型随着版本升级还在继续增加,如即将支持CORTEX、DSP处理器;

支持通用外设模型:如字符LCD模块、图形LCD模块、LED点阵、LED七段显示模块、键盘/按键、直流/步进/伺服电机、RS232虚拟终端、电子温度计等等,其COMPIM(COM口物理接口模型)还可以使仿真电路通过PC机串口和外部电路实现双向异步串行通信;

2

武汉理工大学《能力拓展训练》说明书

实时仿真:支持UART/USART/EUSARTs仿真、中断仿真、SPI/I2C仿真、MSSP仿真、PSP仿真、RTC仿真、ADC仿真、CCP/ECCP仿真;

编译及调试:支持单片机汇编语言的编辑/编译/源码级仿真,内带8051、AVR、PIC的汇编编译器,也可以与第三方集成编译环境(如IAR、Keil和Hitech)结合,进行高级语言的源码级仿真和调试; (4)实用的PCB设计平台

原理图到PCB的快速通道:原理图设计完成后,一键便可进入ARES的PCB设计环境,实现从概念到产品的完整设计;

先进的自动布局/布线功能:支持器件的自动/人工布局;支持无网格自动布线或人工布线;支持引脚交换/门交换功能使PCB设计更为合理;

完整的PCB设计功能:最多可设计16个铜箔层,2个丝印层,4个机械层(含板边),灵活的布线策略供用户设置,自动设计规则检查,3D 可视化预览;

多种输出格式的支持:可以输出多种格式文件,包括Gerber文件的导入或导出,便利与其它PCB设计工具的互转(如protel)和PCB板的设计和加工。

Proteus资源丰富:

(1)Proteus可提供的仿真元器件资源:仿真数字和模拟、交流和直流等数千种元器件,有30多个元件库。

(2)Proteus可提供的仿真仪表资源:示波器、逻辑分析仪、虚拟终端、SPI调试器、I2C调试器、信号发生器、模式发生器、交直流电压表、交直流电流表。理论上同一种仪器可以在一个电路中随意的调用。

(3)除了现实存在的仪器外,Proteus还提供了一个图形显示功能,可以将线路上变化的信号,以图形的方式实时地显示出来,其作用与示波器相似,但功能更多。这些虚拟仪器仪表具有理想的参数指标,例如极高的输入阻抗、极低的输出阻抗。这些都尽可能减少了仪器对测量结果的影响。

(4)Proteus可提供的调试手段 Proteus提供了比较丰富的测试信号用于电路的测试。这些测试信号包括模拟信号和数字信号。

2.2 Keil简介

Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。Keil提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境

3

武汉理工大学《能力拓展训练》说明书

(uVision)将这些部分组合在一起。运行Keil软件需要WIN98、NT、WIN2000、WINXP等操作系统。如果你使用C语言编程,那么Keil几乎就是你的不二之选,即使不使用C语言而仅用汇编语言编程,其方便易用的集成环境、强大的软件仿真调试工具也会令你事半功倍。

Keil C51开发系统基本知识Keil C51开发系统基本知识 (1)系统概述

Keil C51软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows界面。另外重要的一点,只要看一下编译后生成的汇编代码,就能体会到Keil C51生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。在开发大型软件时更能体现高级语言的优势。下面详细介绍Keil C51开发系统各部分功能和使用。

(2)Keil C51单片机软件开发系统的整体结构

C51工具包的整体结构,uVision与Ishell分别是C51 for Windows和for Dos的集成开发环境(IDE),可以完成编辑、编译、连接、调试、仿真等整个开发流程。开发人员可用IDE本身或其它编辑器编辑C或汇编源文件。然后分别由C51及C51编译器编译生成目标文件(.OBJ)。目标文件可由LIB51创建生成库文件,也可以与库文件一起经L51连接定位生成绝对目标文件(.ABS)。ABS文件由OH51转换成标准的Hex文件,以供调试器dScope51或tScope51使用进行源代码级调试,也可由仿真器使用直接对目标板进行调试,也可以直接写入程序存贮器如EPROM中。

Keil C51生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。在开发大型软件时更能体现高级语言的优势。

3、设计原理及方案

3.1 AT89C52单片机介绍

AT89C52是一个低电压,高性能CMOS 8位单片机,片内含8k bytes的可反复擦写的Flash只读程序存储器和256 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,AT89C52单片机在电子行业中有着广泛的应用。

其主要功能特性有以下几点: (1)兼容MCS51指令系统

4

武汉理工大学《能力拓展训练》说明书

(2)8k可反复擦写(大于1000次)Flash ROM; (3)32个双向I/O口; (4)256x8bit内部RAM;

(5)3个16位可编程定时/计数器中断; (6)时钟频率0-24MHz;

(7)2个串行中断,可编程UART串行通道; (8)2个外部中断源,共8个中断源; (9)2个读写中断口线,3级加密位;

(10)低功耗空闲和掉电模式,软件设置睡眠和唤醒功能;

(11)有PDIP、PQFP、TQFP及PLCC等几种封装形式,以适应不同产品的需求。

AT89C52为8 位通用微处理器,采用工业标准的C51内核,在内部功能及管脚排布上与通用的8xc52 相同,其主要用于会聚调整时的功能控制。功能包括对会聚主IC 内部寄存器、数据RAM及外部接口等功能部件的初始化,会聚调整控制,会聚测试图控制,红外遥控信号IR的接收解码及与主板CPU通信等。其引脚图如图3.1.1所示。

图3.1.1 AT89C52引脚图

P0口:P0口是一组8 位漏极开路型双向I/O 口,也即地址/数据总线复用口。

5

武汉理工大学《能力拓展训练》说明书

作为输出口用时,每位能吸收电流的方式驱动8 个TTL逻辑门电路,对端口P0 写“1”时,可作为高阻抗输入端用。在访问外部数据存储器或程序存储器时,这组口线分时转换地址(低8 位)和数据总线复用,在访问期间激活内部上拉电阻。在Flash 编程时,P0口接收指令字节,而在程序校验时,输出指令字节,校验时,要求外接上拉电阻。

P1口:P1是一个带内部上拉电阻的8 位双向I/O 口,P1的输出缓冲级可驱动(吸收或输出电流)4 个TTL 逻辑门电路。对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流(IIL)。与AT89C51 不同之处是,P1.0 和P1.1 还可分别作为定时/计数器2 的外部计数输入(P1.0/T2)和输入(P1.1/T2EX),参见表1。Flash 编程和程序校验期间,P1接收低8 位地址。

表3.1.1 .P1.0和P1.1的第二功能

引脚号 P1.0 P1.1 功能特性 T2,时钟输出 T2EX(定时/计数器2) P2口:P2 是一个带有内部上拉电阻的8 位双向I/O 口,P2 的输出缓冲级可驱动(吸收或输出电流)4 个TTL 逻辑门电路。对端口P2 写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口,作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流(IIL)。在访问外部程序存储器或16 位地址的外部数据存储器(例如执行MOVX @DPTR 指令)时,P2 口送出高8 位地址数据。在访问8 位地址的外部数据存储器(如执行MOVX @RI 指令)时,P2 口输出P2 锁存器的内容。Flash 编程或校验时,P2亦接收高位地址和一些控制信号。

P3口:P3 口是一组带有内部上拉电阻的8 位双向I/O 口。P3口输出缓冲级可驱动(吸收或输出电流)4 个TTL 逻辑门电路。对P3 口写入“1”时,它们被内部上拉电阻拉高并可作为输入端口。此时,被外部拉低的P3口将用上拉电阻输出电流(IIL)。P3口除了作为一般的I/O口线外,更重要的用途是它的第二功能P3口还接收一些用于Flash 闪速存储器编程和程序校验的控制信号。 RST:复位输入。当振荡器工作时,RST引脚出现两个机器周期以上高电平将使单片机复位。

ALE/PROG:当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)

6

武汉理工大学《能力拓展训练》说明书

输出脉冲用于锁存地址的低8 位字节。一般情况下,ALE 仍以时钟振荡频率的1/6 输出固定的脉冲信号,因此它可对外输出时钟或用于定时目的。要注意的是:每当访问外部数据存储器时将跳过一个ALE 脉冲。对Flash 存储器编程期间,该引脚还用于输入编程脉冲(PROG)。如有必要,可通过对特殊功能寄存器(SFR)区中的8EH 单元的D0 位置位,可禁止ALE 操作。该位置位后,只有一条 MOVX 和MOVC指令才能将ALE 激活。此外,该引脚会被微弱拉高,单片机执行外部程序时,应设置ALE 禁止位无效。

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

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

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

3.2 FYD12864液晶芯片介绍

12864C-1是一种具有4位/8位并行、2线或3线串行多种接口方式,内部含

有国标一级、二级简体中文字库的点阵图形液晶显示模块;其显示分辨率为128×64,内置8192个16*16 点汉字,和128个16*8点ASCII字符集.利用该模块灵活的接口方式和简单、方便的操作指令,可构成全中文人机交互图形界面。可以显示8×4行16×16点阵的汉字.也可完成图形显示.低电压低功耗是其又一显著特点。由该模块构成的液晶显示方案与同类型的图形点阵液晶显示模块相比,不论硬件电路结构或显示程序都要简洁得多,且该模块的价格也略低于相同点阵的图形液晶模块。

(1)基本特性: 低电源电压(VDD:+3.0--+5.5V) 显示分辨率:128×64点

内置汉字字库,提供8192个16×16点阵汉字(简繁体可选) 内置128个16×8点阵字符

7

武汉理工大学《能力拓展训练》说明书

2MHZ时钟频率 显示方式:STN、半透、正显 驱动方式:1/32DUTY,1/5BIAS 视角方向:6点

背光方式:侧部高亮白色LED,功耗仅为普通LED的1/5—1/10 通讯方式:串行、并口可选

内置DC-DC转换电路,无需外加负压 无需片选信号,简化软件设计

工作温度:0℃-+55℃,存储温度:-20℃-+60℃ (2)内部结构

FYD12864液晶的内部结构控制如图3.2.1所示。

图 3.2.1 液晶内部结构图

(3)模块接口说明 管脚号 1 2 3 4

管脚名称 VSS VCC V0 RS(CS) 表 3.1.1 12864管脚说明 电平 管脚功能描述 0V 3.0+5V - H/L 电源地 电源正 对比度(亮度)调整 RS=“H”,表示DB7—DB0为显示数据 RS=“L”,表示DB7—DB0为显示指令数据 8 武汉理工大学《能力拓展训练》说明书

5 R/W(SID) H/L 6 E(SCLK) H/L 7—14 DB0—DB7 H/L 15 PSB H/L 16 NC - 17 /RESET H/L 18 VOUT - 19 A VDD 20 K VSS (4)模块主要硬件结构说明 表 3.2.2 RS,R/W的配合选择决定控制界面的4种模式 RS R/W 功能说明 L L MPU写指令到指令暂存器 L H 读出忙标志(BF)及地址计数器(AC)的状态 H L MPU写入数据到数据暂存器 H H MPU从数据暂存器(DR)中读出数据 表 3.2.3 E信号 E状态 执行动作 结果 高——>低 I/O缓冲——>DR 配合/W进行写数据或指令 高 DR——>I/O缓冲 配合R惊醒读数据或指令 低/低——>高 无动作

a. 忙标志:BF

R/W=“H”,E=“H”,数据被读到DB7—DB0 R/W=“L”,E=“H→L”,DB7—DB0的数据被写到IR或DR 使能信号 三态数据线 H:8位或4位并口方式,L:串口方式 空脚 复位端,低电平有效 LCD驱动电压输出端 背光源正端(+5V) 背光源负端 BF标志提供内部工作情况.BF=1表示模块在进行内部操作,此时模块不接受外部指令和数据.BF=0时,模块为准备状态,随时可接受外部指令和数据. 利用STATUS RD 指令,可以将BF读到DB7总线,从而检验模块之工作状态.

b. 字型产生ROM (CGROM)

字型产生ROM(CGROM)提供8192个此触发器是用于模块屏幕显示开和关的控制。DFF=1为开显示(DISPLAY ON),DDRAM 的内容就显示在屏幕上,DFF=0为关显示(DISPLAY OFF)。

DFF 的状态是指令DISPLAY ON/OFF和RST信号控制的。

c. 显示数据RAM (DDRAM)

模块内部显示数据RAM提供64×2个位元组的空间,最多可控制4行16字

(64个字)的中文字型显示,当写入显示数据RAM时,可分别显示CGROM与CGRAM的字型;此模块可显示三种字型,分别是半角英数字型(16*8)、CGRAM字型及CGROM的中文字型,三种字型的选择,由在DDRAM中写入

9

武汉理工大学《能力拓展训练》说明书

的编码选择,在0000H—0006H的编码中(其代码分别是0000、0002、0004、0006共4个)将选择CGRAM的自定义字型,02H—7FH的编码中将选择半角英数字的字型,至于A1以上的编码将自动的结合下一个位元组,组成两个位元组的编码形成中文字型的编码BIG5(A140—D75F),GB(A1A0-F7FFH)。

d. 字型产生RAM (CGRAM)

字型产生RAM提供图象定义(造字)功能, 可以提供四组16×16点的自定义图象空间,使用者可以将内部字型没有提供的图象字型自行定义到CGRAM中,便可和CGROM中的定义一样地通过DDRAM显示在屏幕中。

e. 地址计数器AC

地址计数器是用来贮存DDRAM/CGRAM之一的地址,它可由设定指令暂存器来改变,之后只要读取或是写入DDRAM/CGRAM的值时,地址计数器的值就会自动加一,当RS为“0”时而R/W为“1”时,地址计数器的值会被读取到DB6——DB0中。

f. 光标/闪烁控制电路

此模块提供硬体光标及闪烁控制电路,由地址计数器的值来指必RAM中的光标或闪烁位置。 (5)主要指令说明

表3.3.3 基本指令说明表 指 令 指令码 RR/DD6 D5 D4 D3 D2 D1 D0 S W 7 0 0 0 0 0 1 功能 将DDRAM填满\并且设定DDRAM的地址计数器(AC)到\设定DDRAM的地址计数器(AC)到\并且将游标移到开头原点位置;这个指令不改变DDRAM 的内容 D=1: 整体显示 ON C=1: 游标ON B=1:游标位置反白允许 指定在数据的读取与写入时,设定游标的移动方向及指定显示的移位 设定游标的移动与显示的移位控制位;这个指令不改变DDRAM 的内容 DL=0/1:4/8位数据 RE=1: 扩充指令操作 清除 显示 0 0 0 0 地址 0 0 0 0 归位 显示状0 0 0 0 态开/关 进入点 设定 0 0 0 0 游标或显示移0 0 0 0 位控制 功能 0 0 0 0 设定

0 0 0 0 1 X 0 0 0 0 1 0 D C B 1 I/D S 0 1 S/C R/L X X 1 DL X RE X X 10

武汉理工大学《能力拓展训练》说明书

RE=0: 基本指令操作 设定CGRA0 0 M 地址 设定DDRA0 0 M 地址 读取忙标志和0 1 地址 写数据1 0 到RAM 0 1 ACACACACACAC设定CGRAM 地址 5 4 3 2 1 0 设定DDRAM 地址(显示位ACACACACACAC址) 1 0 5 4 3 2 1 0 第一行:80H-87H 第二行:90H-97H 读取忙标志(BF)可以确认内部BACACACACACACAC动作是否完成,同时可以读出F 6 5 4 3 2 1 0 地址计数器(AC)的值 数据 将数据D7——D0写入到内部的RAM (DDRAM/CGRAM/IRAM/GRAM) 读出1 1 数据 从内部RAM读取数据RAMD7——D0 的值 (DDRAM/CGRAM/IRAM/GRAM) 表3.3.4 扩展指令说明表 指 指令码 功能 令 RS R/W D7 D6 D5 D4 D3 D2 D1 D0 待命 进入待命模式,执行其模式 0 0 0 0 0 0 0 0 0 1 他指令都棵终止 待命模式 卷动SR=1:允许输入垂直卷动地址地址 0 0 0 0 0 0 0 0 1 SR 开关SR=0:允许输入IRAM和开启 CGRAM地址 选择2行中的任一行作反白显示,并可决定反反白 白与否。初始值R1R00 0 0 0 0 0 0 1 R1 R0 选择 =00,第一次设定为反白显示,再次设定变回正常 睡眠 SL=0:进入睡眠模式 0 0 0 0 0 0 1 SL X X 模式 SL=1:脱离睡眠模式 CL=0/1:4/8位数据 扩充 RE=1: 扩充指令操作 功能 0 0 0 0 1 CL X RE G 0 RE=0: 基本指令操作 设定 G=1/0:绘图开关 设定设定绘图RAM 绘图先设定垂直(列)地址RAM AC6AC5…AC0 0 0 0 AC3 AC2 AC1 AC0 地址 0 0 1 再设定水平(行)地址AC6 AC5 AC4 AC3 AC2 AC1 AC0 AC3AC2AC1AC0 将以上16位地址连续写入即可 11

武汉理工大学《能力拓展训练》说明书

(6)读写时序图

图3.2.2 写数据时序图

图3.2.3 读数据时序图

3.3 设计方案

本次课程设计基于AT89C52为核心控制器,FYD12864液晶为显示器设计的

液晶显示电路。该电路可通过调用FYD12864液晶内部自带的字库(包含8192个标准中文汉字)显示16×16点的中文汉字、16×8的数字及英文字符,该过程只需要像DDRAM中写入要显示的字符的ASCII码,当事先指定显示数据的位置,即可将所需显示的字符显示在液晶的指定位置。使用KNY12864液晶的绘图功能,将所需显示图片或字符的字模数据写入到CGRAM中,开图片显示,即可将该图片或字符同时显示在液晶上。

扩展中实现图像的上、下、左、右移动,实现该功能主要基于数据指针读取

的字模数据的位置发生改变来实现的。字模数据是固化在52ROM里面的,通过数据指针将这些字模数据读到CGRAM中,然后开显示,即可将图像或字符显示在12864液晶上。根据FYD12864液晶读取数据的顺序特性,在读取字模数据

12

武汉理工大学《能力拓展训练》说明书

时,按照一定的规律跳过固定的数据个数,后面补上另一幅图像固定的数据个数,事实上就是将两幅图像拼凑到液晶上,最后通过刷新显示的图像,给人的感觉就是图像在液晶上移动。可能移动效果会比较差,但大体实现移动的功能。

要控制图像移动的方向,需要外部键盘输入,MPU判断键值来改变移动方

向。由于图像的移动需要MPU不断的像CGRAM中写入图像数据,然后刷新液晶显示来实现,这样子MPU必须忙于数据的写入,无法去检测键盘的输入。即使可以,检测的实时性会很低。但是52中有一项功能可不受当前指令执行影响,那就是中断,只要有中断产生,即可暂停当前指令的执行,进入中断服务程序进行处理。设计中,我采用红外遥控的方法,将红外接收器SM0038接收到的信号输入到外部中断0的输入口,通过在中断服务程序中对红外进行解码,改变标志位flag的值来实现移动方向的改变,当然前提是开外部中断0。

4、程序设计

4.1 程序流程图

主程序和中断服务程序流程图如下所示:

13

武汉理工大学《能力拓展训练》说明书

开始进入中断系统初始化关外部中断0显示初始界面及图像判断是否是干扰否判断flag的值红外解码Flag=1图像上移Flag=2图像下移Flag=3图像左移Flag=4图像右移是根据解码设定flag的值是判断flag值是否发生变化否是判断是否完成移动否根据原flag的值进行移动开外部中断0中断返回

图 4.1.1主程序流程图图 4.1.2 外部中断处理流程图

4.2 程序代码

4.2.1 主函数文件main.c

#include

#include \ #include

#define uchar unsigned char #define uint unsigned int

///////////////////////////////////////////////////

//红外接收接P3.2 红外遥控每个按键的定义可以看Code_Chang(); ///////////////////////////////////////////////////

////有关的位声明///////////////////////////////////

14

武汉理工大学《能力拓展训练》说明书

sbit IRIN=P3^2;

uchar Reive[4]={0},yaokong,Last,Last1; void Init_R() { Reive[0]=0; Reive[1]=0; Reive[2]=0; Reive[3]=0; }

void delay0(uchar x) //x*0.14MS {

uchar i; while(x--) {

for (i = 0; i<13; i++) {} } }

unsigned char Code_Chang(unsigned char yaokong) { switch (yaokong) { case 0x10:flag=1;break; case 0x03:flag=2;break; case 0x01:flag=3;break; case 0x06:flag=4;break; case 0x09:flag=0;break; case 0x1d:flag=6;break; default:flag=0;break; } return flag; }

void IR_IN() interrupt 0 using 0 { unsigned char j,i,N=0; unsigned char k=0; Init_R(); EX0 = 0; delay0(15); if (IRIN==1) { EX0 =1; return; }

//确认IR信号出现

15

武汉理工大学《能力拓展训练》说明书

while (!IRIN) //等IR变为高电平,跳过9ms的前导低电平信号。 {delay0(1);} for (j=0;j<4;j++) //收集四组数据 { for (i=0;i<8;i++) //每组数据有8位 { while (IRIN); //等IR变为低电平,跳过4.5ms的前导高电平信号。 while (!IRIN); //等IR变为高电平 while (IRIN) //计算IR高电平时长 { delay0(1); N++; if (N>=30) { EX0=1; return; } //0.14ms计数过长自动离开。 } //高电平计数完毕 Reive[j]=Reive[j] >> 1; //数据最高位补“0” if (N>=8) {Reive[j] = Reive[j] | 0x80;} //数据最高位补“1” N=0; }//end for i }//end for j if (Reive[2]!=~Reive[3]) { EX0=1; return; } yaokong=Reive[2]; flag=Code_Chang(yaokong); if(flag>0&&flag<5) { Last=flag; } EX0=1; }

/********************************************************* * 主函数 */ void main() { uchar line=8; // Last=flag; IE = 0x81; TCON = 0x01;

16

武汉理工大学《能力拓展训练》说明书

}

IRIN=1;

delay1(100); //上电,等待稳定 init_display(); while(1) { switch (flag) { case 0:break; case 1:picture_move_Up(Photo1,8);break; case 2:picture_move_Down(Photo1,Photo3,8);break; case 3:picture_mov_Left(Photo1,Photo2); picture_mov_Left(Photo2,Photo1);break; case 4:picture_mov_Right(Photo2,Photo1); picture_mov_Right(Photo1,Photo2);break; case 6:flag=Last;break; default:flag=0;break; } }

4.2.2 液晶显示函数文件12864.h

#include #include

#define uchar unsigned char #define uint unsigned int

uint time=2000,flag=0;//闪烁间隔时间--显示方式标志位flag /************* 12864LCD引脚定义 *************/ #define LCD_data P0 //数据口

sbit LCD_RS = P2^0; //寄存器选择输入 sbit LCD_RW = P2^1; //液晶读/写控制 sbit LCD_EN = P2^2; //液晶使能控制 sbit LCD_PSB = P2^3; //串/并方式控制 sbit LCD_RST = P2^5; //液晶复位端口

#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

/*********************************************************/ uchar code DIS1[] = {\ 武汉理工大学 %uchar code DIS2[] = {%uchar code DIS3[] = {\ 能力扩展训练 %uchar code DIS4[] = {\电信0805 23号 \

/*********************************************************/ /* 图像字模省略 */ /*********************************************************/ uchar code Photo1[] ={}; uchar code Photo2[]={};

17

武汉理工大学《能力拓展训练》说明书

uchar code Photo3[1]={0};//该数组为调用前面的数据用

/*******************************************************************/ /* 延时函数 */ void delay1(int ms) {

while(ms--) {

uchar y; for(y=0;y<100;y++) ; } }

/*******************************************************************/ /*检查LCD忙状态 */ bit lcd_busy()

{ bit result; LCD_RS = 0; LCD_RW = 1; LCD_EN = 1; delayNOP();

result = (bit)(P0&0x80); LCD_EN = 0; return(result); }

/*******************************************************************/ /*写指令数据到LCD */ void lcd_wcmd(uchar cmd)

{ while(lcd_busy()); LCD_RS = 0; LCD_RW = 0; LCD_EN = 0; _nop_(); _nop_(); P0 = cmd; delayNOP(); LCD_EN = 1; delayNOP(); LCD_EN = 0; }

/*******************************************************************/ /*写显示数据到LCD */ void lcd_wdat(uchar dat)

{

18

武汉理工大学《能力拓展训练》说明书

while(lcd_busy()); LCD_RS = 1; LCD_RW = 0; LCD_EN = 0; P0 = dat; delayNOP(); LCD_EN = 1; delayNOP(); LCD_EN = 0; }

/*******************************************************************/ /* LCD初始化设定 */ void lcd_init() {

LCD_PSB = 1; //并口方式 LCD_RST = 0; //液晶复位 delay1(3); LCD_RST = 1; delay1(3);

lcd_wcmd(0x34); //扩充指令操作 delay1(5);

lcd_wcmd(0x30); //基本指令操作 delay1(5);

lcd_wcmd(0x0C); //显示开,关光标 delay1(5);

lcd_wcmd(0x01); //清除LCD的显示内容 delay1(5); }

/*********************************************************/ /* 设定显示位置 */ void lcd_pos(uchar X,uchar Y) { uchar pos; if (X==1) {X=0x80;} else if (X==2) {X=0x90;} else if (X==3) {X=0x88;} else if (X==4) {X=0x98;} pos = X+Y ;

lcd_wcmd(pos); //显示地址

19

武汉理工大学《能力拓展训练》说明书

}

/********************************************************* * 闪烁函数 */ void lcdflag(uint z) {

lcd_wcmd(0x08); delay1(z);

lcd_wcmd(0x0c); delay1(z);

lcd_wcmd(0x08); delay1(z);

lcd_wcmd(0x0c); delay1(z);

lcd_wcmd(0x08); delay1(200);

lcd_wcmd(0x0c); delay1(5);

lcd_wcmd(0x01); delay1(5); }

/********************************************************* * 图形显示 */ void photodisplay(uchar *bmp) {

uchar i,j;

lcd_wcmd(0x34); //写数据时,关闭图形显示 for(i=0;i<32;i++) {

lcd_wcmd(0x80+i); //先写入水平坐标值 lcd_wcmd(0x80); //写入垂直坐标值

for(j=0;j<16;j++) //再写入两个8位元的数据 lcd_wdat(*bmp++); delay1(1); }

for(i=0;i<32;i++) {

lcd_wcmd(0x80+i); lcd_wcmd(0x88);

for(j=0;j<16;j++) lcd_wdat(*bmp++); delay1(1); }

lcd_wcmd(0x36); //写完数据,开图形显示 }

20

武汉理工大学《能力拓展训练》说明书

/********************************************************* * 清屏函数 */ void clr_screen() {

lcd_wcmd(0x34); //扩充指令操作 delay1(5);

lcd_wcmd(0x30); //基本指令操作 delay1(5);

lcd_wcmd(0x01); //清屏 delay1(5); }

/********************************************************* * 图像上移函数 */ void picture_move_Up(uchar *bmp1,uchar line) { uchar i,j,m; uchar *bmp11=bmp1,*bmp111=bmp1;//保存地址指针 for(m=0;m<64/line;m++) //每幅图像有64行,每次移动8行 { //移动8次 bmp1=bmp11; lcd_wcmd(0x34); //写数据时,关闭图形显示 for(i=0;i<32;i++) { lcd_wcmd(0x80+i); //先写入水平坐标值 lcd_wcmd(0x80); //写入垂直坐标值 for(j=0;j<16;j++) //再写入两个8位元的数据 lcd_wdat(*bmp1++); delay1(1); } for(i=0;i<32;i++) { lcd_wcmd(0x80+i); lcd_wcmd(0x88); for(j=0;j<16;j++) lcd_wdat(*bmp1++); delay1(1); } lcd_wcmd(0x36); //写完数据,开图形显? while(flag==0) if(flag==6)flag=1;//图像停止 if(flag!=1)return; delay1(1000); bmp11+=16*line; //每次移动8行--16*line字节 }

21

武汉理工大学《能力拓展训练》说明书

for(m=0;m<32/line;m++) //第一幅的第一行在下半屏 { bmp1=bmp11; lcd_wcmd(0x34); //写数据时,关闭图形显示 for(i=0;i<32;i++) { lcd_wcmd(0x80+i); //先写入水平坐标值 lcd_wcmd(0x80); //写入垂直坐标值 for(j=0;j<16;j++) //再写入两个8位元的数据 lcd_wdat(*bmp1++); delay1(1); } for(i=0;i<(32-line*m);i++) { lcd_wcmd(0x80+i); lcd_wcmd(0x88); for(j=0;j<16;j++) lcd_wdat(*bmp1++); delay1(1); } bmp1=bmp111; for(;i<32;i++) { lcd_wcmd(0x80+i); lcd_wcmd(0x88); for(j=0;j<16;j++) lcd_wdat(*bmp1++); delay1(1); } lcd_wcmd(0x36); //写完数据,开图形显? while(flag==0) if(flag==6)flag=1;//图像停止 if(flag!=1)return; delay1(1000); clr_screen(); bmp11+=16*line; //每次移动8行--16*line字节 }

for(m=0;m<32/line;m++) //第一幅的第一行在上半屏 { bmp1=bmp11; lcd_wcmd(0x34); //写数据时,关闭图形显示 for(i=0;i<(32-line*m);i++) { lcd_wcmd(0x80+i);

22

武汉理工大学《能力拓展训练》说明书

lcd_wcmd(0x80); for(j=0;j<16;j++) lcd_wdat(*bmp1++); delay1(1); } bmp1=bmp111; for(;i<32;i++) { lcd_wcmd(0x80+i); lcd_wcmd(0x80); for(j=0;j<16;j++) lcd_wdat(*bmp1++); delay1(1); } for(i=0;i<32;i++) { lcd_wcmd(0x80+i); //先写入水平坐标值 lcd_wcmd(0x88); //写入垂直坐标值 for(j=0;j<16;j++) //再写入两个8位元的数据 lcd_wdat(*bmp1++); delay1(1); } lcd_wcmd(0x36); //写完数据,开图形显? while(flag==0) if(flag==6)flag=1;//图像停止 if(flag!=1)return; delay1(1000); clr_screen(); bmp11+=16*line; //每次移动8行--16*line字节 } }

/********************************************************* * 图像下移函数 */

void picture_move_Down(uchar *bmp1,uchar *bmp3,uchar line) { uchar i,j,m; uchar *bmp11=bmp1,*bmp111=bmp1; uchar *bmp333=bmp3,*bmp33=bmp3;//保存地址指针 for(m=0;m<32/line;m++) { lcd_wcmd(0x34); //写数据时,关闭图形显示 bmp1=bmp11; bmp3=bmp33; for(i=0;i

23

武汉理工大学《能力拓展训练》说明书

{ lcd_wcmd(0x80+i); //先写入水平坐标值 lcd_wcmd(0x80); //写入垂直坐标值 for(j=0;j<16;j++) //再写入两个8位元的数据 lcd_wdat(*bmp3++); delay1(1); } for(;i<32;i++) { lcd_wcmd(0x80+i); //先写入水平坐标值 lcd_wcmd(0x80); //写入垂直坐标值 for(j=0;j<16;j++) //再写入两个8位元的数据 lcd_wdat(*bmp1++); delay1(1); } for(i=0;i<32;i++) { lcd_wcmd(0x80+i); lcd_wcmd(0x88); for(j=0;j<16;j++) lcd_wdat(*bmp1++); delay1(1); } lcd_wcmd(0x36); //写完数据,开图形显? while(flag==0) if(flag==6)flag=2;//图像停止 if(flag!=2)return; delay1(1000); clr_screen(); bmp33-=16*line; }

for(m=0;m<32/line;m++) //第一幅的第一行在下半屏 { lcd_wcmd(0x34); //写数据时,关闭图形显示 bmp1=bmp11; bmp3=bmp33; for(i=0;i<32;i++) { lcd_wcmd(0x80+i); //先写入水平坐标值 lcd_wcmd(0x80); //写入垂直坐标值 for(j=0;j<16;j++) //再写入两个8位元的数据 lcd_wdat(*bmp3++); delay1(1); }

24

武汉理工大学《能力拓展训练》说明书

for(i=0;i

for(m=0;m<64/line;m++) //第一幅的第一行在上半屏 { bmp3=bmp33; lcd_wcmd(0x34); //写数据时,关闭图形显示 for(i=0;i<32;i++) { lcd_wcmd(0x80+i); lcd_wcmd(0x80); for(j=0;j<16;j++) lcd_wdat(*bmp3++); delay1(1); } for(i=0;i<32;i++) { lcd_wcmd(0x80+i); //先写入水平坐标值 lcd_wcmd(0x88); //写入垂直坐标值 for(j=0;j<16;j++) //再写入两个8位元的数据 lcd_wdat(*bmp3++); delay1(1); }

25

武汉理工大学《能力拓展训练》说明书

lcd_wcmd(0x36); //写完数据,开图形显? while(flag==0) if(flag==6)flag=2;//图像停止 if(flag!=2)return; delay1(1000); clr_screen(); bmp33-=16*line; //每次移动8行--16*line字节 } }

/********************************************************* * 图像左移函数 */ void picture_mov_Left(uchar *bmp1,uchar *bmp2) { uchar i,j,m=0,n; uchar *bmp11=bmp1,*bmp22=bmp2; for(n=0;n<16;n++) { lcd_wcmd(0x34); //写数据时,关闭图形显示 bmp1=bmp11+m; //保存图片地址 bmp2=bmp22; for(i=0;i<32;i++) //写上半屏 { lcd_wcmd(0x80+i); //先写入水平坐标值 lcd_wcmd(0x80); //写入垂直坐标值 for(j=m;j<16;j++) //再写入两个8位元的数据 lcd_wdat(*bmp1++); bmp1+=m; for(j=0;j

26

武汉理工大学《能力拓展训练》说明书

lcd_wcmd(0x36); //写完数据,开图形显? while(flag==0) if(flag==6)flag=3;//图像停止 if(flag!=3)return; delay1(1000); clr_screen(); //清屏 m++; } }

/********************************************************* * 图像右移函数 */ void picture_mov_Right(uchar *bmp1,uchar *bmp2) { uchar i,j,m=0,n; uchar *bmp11=bmp1,*bmp22=bmp2; for(n=0;n<16;n++) { lcd_wcmd(0x34); //写数据时,关闭图形显示 bmp1=bmp11+16-m; //保存图片地址 bmp2=bmp22; for(i=0;i<32;i++) //写上半屏 { lcd_wcmd(0x80+i); //先写入水平坐标值 lcd_wcmd(0x80); //写入垂直坐标值 for(j=16-m;j<16;j++) lcd_wdat(*bmp1++); bmp1+=(16-m); for(j=0;j<16-m;j++) //再写入两个8位元的数据 lcd_wdat(*bmp2++); bmp2+=m; delay1(1); } for(i=0;i<32;i++) //写下半屏 { lcd_wcmd(0x80+i); //先写入水平坐标值 lcd_wcmd(0x88); //写入垂直坐标值 for(j=16-m;j<16;j++) lcd_wdat(*bmp1++); bmp1+=(16-m); for(j=0;j<16-m;j++) //再写入两个8位元的数据 lcd_wdat(*bmp2++); bmp2+=m; delay1(1); }

27

武汉理工大学《能力拓展训练》说明书

lcd_wcmd(0x36); //写完数据,开图形显? while(flag==0) if(flag==6)flag=4;//图像停止 if(flag!=4)return; delay1(1000); clr_screen(); //清屏 m++; } }

void init_display() { uchar i; lcd_init(); lcd_pos(1,0); for(i=0;i<16;i++) { lcd_wdat(DIS1[i]); delay1(20); } lcd_pos(2,0); for(i=0;i<16;i++) { lcd_wdat(DIS2[i]); delay1(20); } lcd_pos(3,0); for(i=0;i<16;i++) { lcd_wdat(DIS3[i]); delay1(20); } lcd_pos(4,0); for(i=0;i<16;i++) { lcd_wdat(DIS4[i]); delay1(20); } delay1(1000); lcdflag(time); photodisplay(Photo1); delay1(1000); photodisplay(Photo2);

//初始化LCD //设置显示位置为第一行 //设置显示位置为第二行 //设置显示位置为第三行 //设置显示位置为第四行 //闪烁函数time为闪烁时间 //显示图片1 //显示图片2

28

武汉理工大学《能力拓展训练》说明书

}

delay1(1000);

5、结果分析

5.1仿真电路图

仿真电路图如图5.1.1所示。

C130pFRP1U1X119XTAL1CRYSTAL18XTAL2P0.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/RD393837363534333221222324252627281011121314151617P0.0P0.1P0.2P0.3P0.4P0.5P0.6P0.7P2.0P2.1P2.2P2.3P2.4P2.5P2.61234567891KLCD2AMPIRE128X64+5vC230pFRV1VO9RSTC320uf293031PSENALEEACS1CS2GNDVCCV0RSR/WEDB0DB1DB2DB3DB4DB5DB6DB7RST-Vout1kR180012345678P1.0/T2P1.1/T2EXP1.2P1.3P1.4P1.5P1.6P1.7AT89C52P2.0P2.1V+VOP2.2P2.3P2.4P0.0P0.1P0.2P0.3P0.4P0.5P0.6P0.73U2:A74092UpP3.0DownP3.11VO123456789101112131415161718 5.1.1 仿真电路图

5.2 运行结果及分析

硬件电路运行效果图如下所示:

图5.3.1 图像上移图5.3.2图像下移

29

武汉理工大学《能力拓展训练》说明书

图5.3.3图像左移图5.3.4 图像右移

硬件电路上电后,先显示初始化界面及两幅图像,然后停止显示第二幅图像,

等待下一步操作,即红外的输入。当按下红外遥控器的1、2、3、4(其中一个)后,可看到图像的上、下、左、右移动。在以上过程中改变移动方向时,首先出现图像停止移动,等待一段时间后,图像才响应按下的键。这是由于每次刷屏需要消耗几百毫秒时间,而中断返回后可能仍处于刷新上一次图像的过程,而且每次刷新一幅图像的中间有软件延时过程,同时,由于按键的检测是采用外部中断0服务程序中响应红外遥控的方法,每次红外的解码大约又要消耗个100毫秒左右,这些都可能导致图像的停滞状态的出现。

在之前的调试过程中发现,当每按下一方向按键,图像会停止移动大约1s

左右,当然有时更长,有时短些。这是由于图像的移动需要MPU每时每刻向CGRAM写入数据,然后开显示,图像才会有移动的效果。而当接收到红外数据时,程序进入到外部中断0中断服务程序,因此会出现图像静止。而图像移动方向改变反应过慢,主要是因为每次图像移动函数要执行约8s(上下移动)或16s(左右移动),之后才会回到主函数判断flag值。当我在每次移动完一行或者一列之后,加一句判断flag值是否改变时,可以看到按下按键后,图像移动方向改变的速度变快了,反应更加及时了。

该设计能够实现红外控制其图像的上、下、左、右循环移动,并有图像的静

止及继续移动的功能。

30

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

Top