本节给出点阵字符型LCD的一个编程实例。

在MT-IDE实验板上,LCD的数据线7~14脚(DB0~DB7)分别与MCU的PTB0~PTB7连接,LCD的控制线RS、R/ 、E(4、5、6脚)分别与MCU的PTC0、PTC1、PTC2连接,图9-8给出LCD的硬件连接方式。LCD的1、2、3脚为供电电源与亮度调节引脚。MT-IDE实验箱的扩展板的上还留有一排插孔,当LCD接在下排插孔时,LCD控制线与数据线与MCU的连接可以自行定义并通过上部接线孔接线。
9.4.1 LCD汇编编程工程实例
以下给出GP32对LCD的编程实例,程序同样可以应用到其他MCU上,只需要修改相应的寄存器定义头文件即可。表9-4列出了该例程的所有程序文件,下面逐一给出与LCD相关的程序。
(1) LCD初始化、显示通用子函数
下面给出以GP32为例有关LCD初始化和LCD显示的通用子函数。它们是:LCD初始化子函数、LCD显示子函数。LCD初始化子函数用来对LCD做一些初始设置,LCD显示子函数用来将LCD缓冲区中的数据显示在LCD屏幕上。将它们应用到CCM3118、S08系列、S12系列中时只需要修改相应的头文件和宏定义中LCD寄存器的地址即可。

LCD初始化、显示子函数头文件:LCD.h
//[LCD.h]LCD驱动头文件-----------------------------------
//寄存器及相关位定义
LCDdata = PTB //LCD显示数据或指令传送口
LCDdataD = DDRB //LCD数据口方向寄存器
LCDctrl = PTC //LCD控制信号传送口
LCDctrlD = DDRC //LCD控制口方向寄存器
RS = 0 //LCD寄存器选择信号(PTC0)
RW = 1 //LCD读写信号(PTC1)
E = 2 //LCD使能信号(PTC2)
LCD初始化、显示子函数:LCD.s
//[LCD.s]LCD驱动----------------------------------------*
//本文件包含: *
// (1)LCDshow:在LCD(HD44780)显示屏上显示数据 *
// (2)LCDinit:初始化LCD(HD44780) *
// (3)LCDcommand:执行A中的LCD命令 *
//硬件连接: *
// 在MT-IDE实验板上,有与LCD连接的两排插孔: *
// (1)LCD若接上排插孔: *
// LCD的数据线(DB0-7),控制线RS,R/W,E分别与MCU的 *
// PTB0-7,PTC0-2连接 *
// (2)LCD若接下排插孔: *
// 可自行定义LCD与MCU的连接 *
//------------------------------------------------------*
.include "LCD.h" //该头文件包含寄存器及相关位定义
//LCDshow:在LCD(HD44780)显示屏上显示数据----------------*
//功能:在LCD(HD44780)显示屏上显示HX所指向的32个数据 *
//入口:HX = 待显示数据的首地址 *
//出口:无 *
//堆栈深度:2 + 1 + 1 + 9 = 13 *
//内部调用:LCDinit,LCDcommand *
//------------------------------------------------------*
LCDshow::
PSHA //保护A
AIS #-1 //开辟1个字节的临时变量
//1. LCD初始化
JSR LCDinit
//2. 显示第1行16个字符
//2.1设置显示首地址
BCLR #RS,LCDctrl //RS,R/W = 00(写的是指令)
BCLR #RW,LCDctrl
LDA #%10000000 //后7位为DD RAM地址($00)
JSR LCDcommand
//2.2写16个数据到DD RAM
LDA #16 //[SP+1]初始 = 16(1行显示个数)
STA 1,SP
BSET #RS,LCDctrl //RS,R/W = 10(写的是数据)
BCLR #RW,LCDctrl
LCDshow_1:
LDA ,X //取待显示的数据
JSR LCDcommand //向DD RAM写入数据
AIX #1 //指向下一个待显示的数据
DBNZ 1,SP,LCDshow_1 //若16个数据没写完则继续
//3. 显示第2行16个字符
//3.1设置显示首地址
BCLR #RS,LCDctrl //RS,R/W = 00(写的是指令)
BCLR #RW,LCDctrl
LDA #%11000000 //后7位为DD RAM地址($40)
JSR LCDcommand
//3.2写16个数据到DD RAM
LDA #16 //[SP+1]初始 = 16(1行显示个数)
STA 1,SP
BSET #RS,LCDctrl //RS,R/W = 10(写的是数据)
BCLR #RW,LCDctrl
LCDshow_2:
LDA ,X //取待显示的数据
JSR LCDcommand //向DD RAM写入数据
AIX #1 //指向下一个待显示的数据
DBNZ 1,SP,LCDshow_2 //若16个数据没写完则继续
AIS #1 //释放临时变量
PULA //恢复A
RTS
//LCDinit:初始化LCD(HD44780)----------------------------*
//功能:初始化LCD(HD44780),设置显示方式,输入方式,并清屏 *
//入口:无 *
//出口:无 *
//堆栈深度:2 + 3 + 4 = 9 *
//内部调用:LCDcommand *
//------------------------------------------------------*
LCDinit::
PSHH //保护H
PSHX //保护X
PSHA //保护A
LDA #%11111111 //定义数据口(PTB0-7)为输出
STA LCDdataD
LDA LCDctrlD //定义控制口(PTC0-2)为输出
ORA #%00000111
STA LCDctrlD
//设置指令
BCLR #RS,LCDctrl //RS,R/W = 00
BCLR #RW,LCDctrl
//1. 功能设置
LDA #%00111000
//||||||||____ 可设任意值(0/1)
//||||||______ F = 0,5*7点阵模式
//|||||_______ N = 1,2行显示
//||||________ DL = 1,8位数据总线
//|||_________ 固定为001
JSR LCDcommand
//2. 显示开关控制
LDA #%00001000
//||||||||____ B = 0,不闪烁
//|||||||_____ C = 0,关光标显示
//||||||______ D = 0,关显示
//|||||_______ 固定为00001
JSR LCDcommand
//3.清屏
LDA #%00000001 //清DD RAM内容,光标回原位,清AC
JSR LCDcommand
LDHX #$0200 //等待清屏完毕,时间 > 1.6ms
JSR DelayHX
//4.输入方式设置
LDA #%00000110
//||||||||____ 显示不移动,光标左移(A = 1)
//|||||||_____ 数据读写操作后,AC自动增1
//||||||______ 固定为000001
JSR LCDcommand
//5.光标或画面移位设置
LDA #%00010100
//||||||||____ 可设任意值(0/1)
//||||||______ 光标右移一个字符位,AC自动加1
//||||________ 固定为0001
JSR LCDcommand
//6. 显示开关控制
LDA #%00001100
//||||||||____ B = 0,不闪烁
//|||||||_____ C = 0,关光标显示
//||||||______ D = 1,开显示
//|||||_______ 固定为00001
JSR LCDcommand
PULA //恢复HX、A
PULX
PULH
RTS
//LCDcommand:执行A中的LCD命令---------------------------*
//功能:执行A中的LCD命令,并延时 *
//入口:A:存放指令或数据 *
//出口:无 *
//堆栈深度:2 + 2 = 4 *
//------------------------------------------------------*
LCDcommand::
PSHX //保护X
PSHH //保护H
//1.等待 > 40us
LDHX #$10
JSR DelayHX
//2.数据送到LCD的数据线上
STA LCDdata
//3.给出E信号的下降沿,使数据写入LCD
BSET #E,LCDctrl
NOP
NOP
NOP
BCLR #E,LCDctrl
//4.等待 > 40us
LDHX #$10
JSR DelayHX
PULH //恢复H
PULX //恢复X
RTS
(2) LCD汇编编程主函数
//------------------------------------------------------*
//工 程 名:LCD.prj *
//硬件连接: *
// (1)LCD的DB0-7,RS,R/W,E与MCU的通用I/O口引脚连接 *
// (见"LCD.s"文件) *
// (2)MCU的串口与PC方的串口相连 *
//工程描述: *
// (1)初始显示: *
// "Wait Receiving.." *
// "Soochow 2007.06" *
// (2)MCU接收PC发来的32个字符,并送LCD显示 *
//--------清华2007版《嵌入式技术基础与实践》实例--------*
//总头文件
.include "Includes.h"
//主程序
.area flash(abs)
.org FlashStartAddr
MainInit:: //复位后从此处执行(见Vectors08.s文件末尾处)
SEI //关总中断
//1. 堆栈初始化为RAM最高端
LDHX #RAMendAddr + 1 //HX = #RAMEndAddr + 1
TXS //HX - 1 -> SP
//2. 芯片初始化
JSR MCUinit //初学时跳过此处
//3. 模块初始化
JSR SCIinit //串行口初始化
//LCD初始显示
LDHX #DisPlayInit
JSR LCDshow
//总循环
MainLoop:
//从PC方串行接收32个数据
LDHX #LCDbuf32
LDA #32
JSR SCIreN
BCS MainLoop //C = 1,MCU未收到数据
//否则,MCU收到数据
//把LCDBuf32为首址32个字符送LCD显示
LDHX #LCDbuf32
JSR LCDshow
JMP MainLoop
//定义LCD初始显示的32个字符
DisPlayInit:
.ASCII "Wait Receiving.."
.ASCII "Soochow 2007.06"
//包含本工程的其他文件-----------------------------------
.include "MCUinit.s" //芯片初始化
.include "GeneralFun.s" //该文件包含延时子程序
.include "SCI.s" //串行通信
.include "LCD.s" //LCD驱动
//包含中断处理子程序与中断向量表文件"Vectors08.s"--------
//注意:这个包含语句的存放位置必须放在最后
.include "Vectors08.s" //中断处理子程序与中断向量表
9.4.2 LCD 08C编程实例
以下给出GP32对LCD的08C编程实例的文件组织情况,如表9-5所示,由于其具体内容和汇编编程很类似,这时不做具体介绍,具体内容参见附带教学资料的例程。

练习题
【基础题】
1.简述LCD的主要特点及分类。
2.简述字符型液晶显示控制器HD44780的编程结构。
3.简述扫描法LED显示的编程原理。
【综合题】
4.编程:PC机发送一个字节数(0-255),在LCD上显示出来。
5.编程:按下键盘上任何一个键,LCD第一行显示“KeyValue:xx”,第二行显示“Definition:yy”。(xx是键值,yy是键定义值)。
6.编程:在LCD上显示日期及时间。
7.编程:PC机发送一个字节数(0-255),在4连排LED上显示出来。
8.设计4连排LED驱动电路,数据口用74HC164芯片,片选口用MC1413芯片。


