1602LCD液晶显示秒表
[源程序:]
;------------------------------------------------------------------
;ME300系列单片机开发系统演示程序-1602LCD显示秒表
;------------------------------------------------------------------
;功能描述:
;1602LCD显示秒表
;K3---控制按键
;第一次按下时,开始计时,第二次按下时,暂停计时。
;第三次按下时,累计计时,第四次按下时,暂停计时。
;K4---清零按键:
;在任何状态下,按一下K4,均可清零。
;可同时显示:时、分、秒、毫秒(带有两位ms级显示)
;------------------------------------------------------------------
TLOWEQU00H;10ms定时初值
THIGHEQU0DCH
HOUREQU30H;时存放单元
MINEQU31H;分存放单元
SECEQU32H;秒存放单元
SEC0EQU33H;10MS计数值存放单元
KEY_SEQU34H;为键当前的端口状况
KEY_VEQU35H;为键上次的端口状况
KEY_CEQU36H;键计数单元
LCD_XEQU37H;LCD地址变量
BEEPEQUP3.7;蜂鸣器控制端口
LCD_RSEQUP2.0;LCD控制端口
LCD_RWEQUP2.1
LCD_ENEQUP2.2
;----------------------------------------------------
;ME300B、ME300A+的独立键端口定义
;----------------------------------------------------
K1EQUP1.4
K2EQUP1.5
K3EQUP1.6;功能键
K4EQUP1.7;复位键
;----------------------------------------------------
;ME300A的独立键端口定义
;----------------------------------------------------
;K1EQUP3.2
;K2EQUP3.3
;K3EQUP3.4;功能键
;K4EQUP3.5;复位键
;----------------------------------------------------
;你可根据使用开发板的型号来选择独立键端口定义
;----------------------------------------------------
ORG0000H
JMPMAIN
ORG0BH
JMPT0_INT
ORG0030H
;----------------------------------------------------
MAIN:
MOVSP,#60H;设堆栈初值
MOVKEY_V,#01H;设初值
CALLINIT_LCD;初始化LCD
CALLSET_LCD1;第一行显示信息
MOVR5,#30
CALLMENU;第二行滚动显示网址
MAIN1:CALLDELAY100;停留3S。
DJNZR5,MAIN1
;JMP$
CALLINIT_LCD;初始化LCD
CALLSET_LCD1;第一行显示信息
CALLSET_LCD2;第二行显示信息
CALLINIT;初始化变量
CALLINIT_TIMER;初始化定时器
LOOP:
CALLCONV;时间数据处理
JBK4,LOOP1;判清零键是否按下
CALLBEEP_BL;蜂鸣器响一声
JNBK4,$;等待K4键释放
JMPMAIN;软件复位
LOOP1:
CALLSKEY;判是否有键按下
JZLOOP;无键按下转LOOP
MOVKEY_V,KEY_S;交换数据
CALLP_KEY;功能键处理
JMPLOOP
;-------------------------------------------------------
;判是否有键按下子程序
;有键按下,A中内容不为零
;无键按下,A中内容则为零
;-------------------------------------------------------
SKEY:
CLRA
MOVKEY_S,A
MOVC,K3
RLCA
ORLKEY_S,A
MOVA,KEY_S
XRLA,KEY_V
RET
;--------------------------------------------------------
;功能键处理子程序
;根据K3键按下的次数来执行相应的功能
;--------------------------------------------------------
P_KEY:
MOVA,KEY_V
JBACC.0,P_KEY4;
INCKEY_C;键按下次数加1
MOVA,KEY_C
CJNEA,#01H,P_KEY1;K3键是否第一次按下?
SETBTR0;启动中断
MOVDPTR,#MADJ;显示执行信息
MOVA,#1;LCD第一行显示信息字符串
CALLLCD_PRINT
CALLBEEP_BL;蜂鸣器响一声
RET
P_KEY1:
MOVA,KEY_C
CJNEA,#02H,P_KEY2;K3键是否第二次按下?
CLRTR0;停止中断
MOVDPTR,#MADJ1;显示执行信息
MOVA,#1;LCD第一行显示信息字符串
CALLLCD_PRINT
CALLBEEP_BL;蜂鸣器响一声
RET
P_KEY2:
MOVA,KEY_C
CJNEA,#03H,P_KEY3;K3键是否第三次按下?
SETBTR0;启动中断
MOVDPTR,#MADJ2;显示执行信息
MOVA,#1;LCD第一行显示信息字符串
CALLLCD_PRINT
CALLBEEP_BL;蜂鸣器响一声
RET
P_KEY3:
MOVA,KEY_C
CJNEA,#04H,P_KEY4;K3键是否第四次按下?
CLRTR0;关闭中断
MOVDPTR,#MADJ3;显示执行信息
MOVA,#1;LCD第一行显示信息字符串
CALLLCD_PRINT
CALLBEEP_BL
P_KEY4:
RET
;--------------------------------------------------------
;设置LCD初始化显示
;--------------------------------------------------------
SET_LCD1:
MOVDPTR,#LMESS1;指针指到显示信息1
MOVA,#1;显示在第一行
CALLLCD_PRINT
RET
SET_LCD2:
MOVDPTR,#LMESS2;指针指到显示信息2
MOVA,#2;显示在第二行
CALLLCD_PRINT
RET
LMESS1:
DB"STOPWATCH0",0;LCD第一行显示
LMESS2:
DB"TIME",0;LCD第二行显示
;--------------------------------------------------------
;LCD初始化子程序
;8位数据传送方式,双行显示,字形5*7点阵。
;开显示,不显示光标。
;--------------------------------------------------------
INIT_LCD:
CALLDELAY5MS;延时15MS
CALLDELAY5MS
CALLDELAY5MS
MOVA,#38H;双行显示,字形5*7点阵,8位数据。
CALLWCOM_NC;不检测忙信号
CALLDELAY5MS
MOVA,#38H;双行显示,字形5*7点阵
CALLWCOM_NC;不检测忙信号
CALLDELAY5MS
MOVA,#38H;双行显示,字形5*7点阵
CALLWCOM_NC;不检测忙信号
CALLDELAY5MS
MOVA,#38H;双行显示,字形5*7点阵
CALLWCOM;检测忙信号
CALLDELAY5MS
MOVA,#0CH;开显示,不显示光标,光标不闪烁。
CALLWCOM
CALLDELAY5MS
MOVA,#01H;清除LCD显示屏
CALLWCOM
CALLDELAY5MS
RET
;--------------------------------------------------------
;初始化控制变量
;--------------------------------------------------------
INIT:
CLRA
MOVKEY_C,A
MOVSEC0,A
MOVSEC,A
MOVMIN,A
MOVHOUR,A
MOVKEY_S,A
MOVKEY_V,A
SETBBEEP
CLRTR0
RET
;--------------------------------------------------------
;初始化定时器子程序
;设置定时器0工作模式为模式1
;启用定时器0产生中断
;--------------------------------------------------------
INIT_TIMER:
MOVTMOD,#01H
MOVIE,#82H
MOVTL0,#TLOW
MOVTH0,#THIGH
RET
;--------------------------------------------------------
;定时器0计时中断服务子程序
;定时器0,方式1
;10ms中断一次
;--------------------------------------------------------
T0_INT:
PUSHACC
MOVTL0,#TLOW
MOVTH0,#THIGH
INCSEC0
MOVA,SEC0;10MS计数值加1
CJNEA,#100,TT
MOVSEC0,#0
INCSEC;秒加1
MOVA,SEC
CJNEA,#60,TT
INCMIN;分加1
MOVSEC,#0
MOVA,MIN
CJNEA,#60,TT
INCHOUR;时加1
MOVMIN,#0
MOVA,HOUR
CJNEA,#24,TT
MOVSEC0,#0
MOVSEC,#0;秒、分、时单元清零
MOVMIN,#0
MOVHOUR,#0
TT:POPACC
RETI
;--------------------------------------------------------
;时间数据转换为ASCII码并显示
;--------------------------------------------------------
CONV:
MOVA,HOUR;加载小时数据
MOVLCD_X,#5;设置位置
CALLSHOW_DIG2;显示数据
INCLCD_X;
MOVA,#':';显示“:”
MOVB,LCD_X;
CALLLCDP2;
MOVA,MIN;加载分钟数据
INCLCD_X;设置位置
CALLSHOW_DIG2;显示数据
INCLCD_X;
MOVA,#':';显示“:”
MOVB,LCD_X;
CALLLCDP2;
MOVA,SEC;加载秒数数据
INCLCD_X;设置位置
CALLSHOW_DIG2;显示数据
INCLCD_X;
MOVA,#':';显示“:”
MOVB,LCD_X;
CALLLCDP2;
MOVA,SEC0;加载秒数数据
INCLCD_X;设置位置
CALLSHOW_DIG2
RET
;--------------------------------------------------------
;在LCD1602的第二行显示数字
;--------------------------------------------------------
SHOW_DIG2:
MOVB,#10;设置被除数
DIVAB;结果A存商数,B存余数
ADDA,#30H;A为十位数,转换为字符
PUSHB;B放入堆栈暂存
MOVB,LCD_X;设置LCD显示的位置
CALLLCDP2;由LCD显示出来
POPB;
MOVA,B;B为个位数
ADDA,#30H;转换为字符
INCLCD_X;LCD显示位置加1
MOVB,LCD_X;设置LCD显示的位置
CALLLCDP2;由LCD显示出来
RET
;--------------------------------------------------------
;在LCD的第二行显示字符
;--------------------------------------------------------
LCDP2:
PUSHACC;入栈保护
MOVA,B;设置显示地址
ADDA,#0C0H;设置LCD的第二行地址
CALLWCOM;写入命令
POPACC;由堆栈取出A
CALLWDATA;写入数据
RET
;--------------------------------------------------------
;在LCD的第一行或第二行显示字符
;--------------------------------------------------------
LCD_PRINT:
CJNEA,#1,LINE2;判断是否为第一行
LINE1:MOVA,#80H;设置LCD的第一行地址
CALLWCOM;写入命令
CALLCLR_LINE;清除该行字符数据
MOVA,#80H;设置LCD的第一行地址
CALLWCOM;写入命令
JMPFILL
LINE2:MOVA,#0C0H;设置LCD的第二行地址
CALLWCOM;写入命令
CALLCLR_LINE;清除该行字符数据
MOVA,#0C0H;设置LCD的第二行地址
CALLWCOM
FILL:CLRA;填入字符
MOVCA,@A+DPTR;由信息区取出字符
CJNEA,#0,LC1;判断是否为结束码
RET
LC1:CALLWDATA;写入数据
INCDPTR;指针加1
JMPFILL;继续填入字符
RET
;--------------------------------------------------------
;清除LCD指定行的字符
;“空白”的ASCII代码为20H。
;--------------------------------------------------------
CLR_LINE:
MOVR0,#24
CL1:MOVA,#20H;''
CALLWDATA
DJNZR0,CL1
RET
;--------------------------------------------------------
;写控制指令子程序
;写控制指令到LCD
;传入参数:ACC(要写入的指令)
;RS=L,RW=L,E=高脉冲,D0-D7=指令码。
;--------------------------------------------------------
WCOM:
ACALLCHECKBUSY
WCOM_NC:
MOVP0,A;写入指令
CLRLCD_EN
NOP
NOP
CLRLCD_RS
CLRLCD_RW
SETBLCD_EN
ACALLDEL_250
CLRLCD_EN
RET
;--------------------------------------------------------
;写数据子程序
;写显示数据到LCD
;传入参数:ACC(要写入的数据)
;RS=H,RW=L,E=高脉冲,D0-D7=数据码。
;--------------------------------------------------------
WDATA:
ACALLCHECKBUSY
MOVP0,A;写入数据
CLRLCD_EN
NOP
NOP
SETBLCD_RS
CLRLCD_RW
SETBLCD_EN
CALLDEL_250
CLRLCD_EN
RET
DEL_250:
MOVR7,#125;延时250微秒
DJNZR7,$
RET
;--------------------------------------------------------
;检测LCD控制器忙碌状态
;正常读写操作之前必须检测LCD控制器状态
;BUSYFLAG(P0.7)=1时,忙,不能接收MCU送来的指令和数据。
;BUSYFLAG(P0.7)=0时,闲,能够接收MCU送来的指令和数据。
;读数据时
;RS=L,RW=H,E=H,输出:D0-D7=数据
;--------------------------------------------------------
CHECKBUSY:
PUSHACC
MOVP0,#0FFH;置P0口为输入状态
CLRLCD_EN
NOP
NOP
SETBLCD_RW
CLRLCD_RS
SETBLCD_EN
BUSYLOOP:
NOP
JBP0.7,BUSYLOOP
CLRLCD_EN
POPACC
RET
;--------------------------------------------------------
;蜂鸣器响一声子程序
;驱动交流蜂鸣器
;--------------------------------------------------------
BEEP_BL:
MOVR6,#150
BL1:CALLBL2
CPLBEEP
DJNZR6,BL1
CALLDELAY5MS
CALLDELAY5MS
CALLDELAY5MS
RET
BL2:MOVR7,#180
BL3:NOP
DJNZR7,BL3
RET
;--------------------------------------------------------
;延时5MS子程序
;--------------------------------------------------------
DELAY5MS:
MOVR6,#25
DEL1:MOVR7,#100
DJNZR7,$
DJNZR6,DEL1
RET
;--------------------------------------------------------
MADJ:DB"BEGINCOUNT1",0
MADJ1:DB"PAUSECOUNT2",0
MADJ2:DB"BEGINCOUNT3",0
MADJ3:DB"PAUSECOUNT4",0
;--------------------------------------------------------
;第二行滚动显示网址子程序
;--------------------------------------------------------
MENU:
MOVA,#06H;移动光标(光标加1)
CALLWCOM
CALLDELAY5MS
MOVA,#0C0H;设置LCD的第二行地址
CALLWCOM;写入命令
CALLCLR_LINE;清除该行字符数据
MOVA,#0C0H;设置LCD的第二行地址
CALLWCOM
MOVDPTR,#CHAR
FILL1:CLRA;填入字符
MOVCA,@A+DPTR;由信息区取出字符
CJNEA,#0,LC2;判断是否为结束码
RET
LC2:CALLWDATA;写入数据
INCDPTR;指针加1
CALLDELAY100
CALLDELAY100
JMPFILL1;继续填入字符
RET
CHAR:
DB"www.willar.com",0
;--------------------------------------------------
;延时100MS子程序
;--------------------------------------------------
DELAY100:
MOVr7,#200
DL1:MOVr6,#250
DL2:DJNZR6,DL2
DJNZR7,DL1
RET
;--------------------------------------------------
END