;/******************************************************************************** ;* 标题: xl系列单片机实验仪演示程序 矩阵键盘12864液晶显示键值 (带字库) * ;* 文件: lcd128JZ.asm * ;* 日期: 2006-1-5 * ;* 版本: 3.0 (试验通过版)可用xl600-xl1000单片机综合试验仪试验 * ;* 作者: 部分程序参考网上修改而成,本站最终改编测试,特别对原作致敬! * ;* 邮箱: sxj1974@163.com * ;* 网站: http://www.51c51.com www.8951.com * ;******************************************************************************** ;* 描述: * ;* 矩阵键盘12864液晶显示键值 (带字库) * ;* 矩阵键盘定义: * ;* P1.0-P1.3为列线,P1.4-P1.7为行线 * ;* 喇叭接P3.7口 矩阵键盘P1口,12864LCD * ;******************************************************************************** ;* 【版权】 Copyright(C)深圳市学林电子有限公司 www.51c51.com * ;* 【声明】 此程序仅用于学习与参考,引用请注明版权和作者信息! * ;* 【技术支持】请访问http://www.51c51.com/bbs/ 官方论坛 * ;********************************************************************************/ X EQU 26H ;LCD 地址变量 BEEP EQU P3.7 RELAY EQU P1.3 RSEQUP2.0 RWEQUP2.1 EN EQUP2.2 PSBEQUP2.3 RSTEQUP2.5 ;================================================== ORG 0000H JMP MAIN ;================================================== MAIN: ORG 0080H MOV SP,#40H MOV A,#00H MOV R0,#20H LOOP0: MOV @R0,A ;20H-26H清零 INC R0 CJNE R0,#27H,LOOP0
SETBRST NOP SETBPSB ;8位数据,并口
CALL SET_LCD ;初始化TS12864A-3 CALL MENU1 CALL MENU2 CALL MENU3 CALL MENU4 LOOP1: MOV P1,#0F0H MOV A,P1 CJNE A,#0F0H,LOOP2 ;有键按下转LOOP2 JMP LOOP1 LOOP2: CALL KEY_IN CALL KEY_CONV CALL BEEP_BL JMP LOOP1 ;============================================= ; LCD 初始化设置 ;=============================================- SET_LCD: CLR EN MOV A,#34H ;34H--扩充指令操作 CALL WCOM CALL DELAY1 MOV A,#30H ;30H--基本指令操作 CALL WCOM CALL DELAY1 MOV A,#0CH ;开显示,关光标, CALL WCOM CALL DELAY1 MOV A,#01H ;清除 LCM 显示屏 CALL WCOM CALL DELAY1 RET ;=================================================== ;在 LCM 各行显示信息字符 ;=================================================== LCD_SHOW: CJNE A,#1,LINE2 ;判断是否为第一行 LINE1: MOV A,#80H ;设置 LCD 的第一行地址 CALL WCOM ;写入命令 CALL CLR_LINE ;清除该行字符数据 MOV A,#80H ;设置 LCD 的第一行地址 CALL WCOM ;写入命令 JMP FILL LINE2: CJNE A,#2,LINE3 ;判断是否为第二行 MOV A,#090H ;设置 LCD 的第二行地址 CALL WCOM ;写入命令 CALL CLR_LINE ;清除该行字符数据 MOV A,#090H ;设置 LCD 的第二行地址 CALL WCOM JMP FILL LINE3: CJNE A,#3,LINE4 ;判断是否为第三行 MOV A,#088H ;设置 LCD 的第三行地址 CALL WCOM ;写入命令 CALL CLR_LINE ;清除该行字符数据 MOV A,#088H ;设置 LCD 的第三行地址 CALL WCOM JMP FILL LINE4: CJNE A,#4,LINE5 ;判断是否为第四行 MOV A,#098H ;设置 LCD 的第四行地址 CALL WCOM ;写入命令 CALL CLR_LINE ;清除该行字符数据 MOV A,#098H ;设置 LCD 的第四行地址 CALL WCOM FILL: CLR A ;填入字符 MOVC A,@A+DPTR ;由消息区取出字符 CJNE A,#0,LC1 ;判断是否为结束码 LINE5: RET LC1: CALL WDATA ;写入数据 INC DPTR ;指针加1 JMP FILL ;继续填入字符 RET ;================================================= ;清除该行 LCM 的字符 ;================================================= CLR_LINE: MOV R0,#16 ; CL1: MOV A,#' ' CALL WDATA DJNZ R0,CL1 RET ;================================================== ;LCM 显示工作菜单信息 ;================================================== MENU1: MOV DPTR,#MENU1A MOV A,#1 ;在第一行显示信息 CALL LCD_SHOW RET MENU1A: DB "学林电子有限公司",0 MENU2: MOV DPTR,#MENU2A MOV A,#2 ;在第二行显示信息 CALL LCD_SHOW RET MENU2A: DB "矩阵键盘值读取器",0 MENU3: MOV DPTR,#MENU3A MOV A,#3 ;在第三行显示信息 CALL LCD_SHOW RET MENU3A: DB "键值编码:- - H",0 MENU4: MOV DPTR,#MENU4A MOV A,#4 ;在第四行显示信息 CALL LCD_SHOW RET MENU4A: DB " www.51c51.com ",0 ;============================================== ; 写指令使能子程序 ;RS=L,RW=L,D0-D7=指令码,E=高脉冲 ;============================================== WCOM: MOV P0,A CLR RS CLR RW SETB EN CALL DELAY0 CLR EN RET ;============================================= ;写数据使能子程序 ;RS=H,RW=L,D0-D7=数据,E=高脉冲 ;============================================= WDATA: MOV P0,A SETB RS CLR RW SETB EN CALL DELAY0 CLR EN RET
DELAY0: MOV R7,#250 ;延时500微秒 DJNZ R7,$ RET ;=============================================== ;在 LCM 第三行、第四行显示字符 ;A=ASC DATA, B=LINE X POS ;=============================================== LCDP3: ;在LCD的第三行显示字符 PUSH ACC ; MOV A,B ;设置显示地址 ADD A,#088H ;设置LCD的第三行地址 CALL WCOM ;写入命令 POP ACC ;由堆栈取出A CALL WDATA ;写入数据 RET
;LCDP4: ;在LCD的第四行显示字符 PUSH ACC ; MOV A,B ;设置显示地址 ADD A,#098H ;设置LCD的第四行地址 CALL WCOM ;写入命令 POP ACC ;由堆栈取出A CALL WDATA ;写入数据 RET ;======================================================== ;矩阵键盘键值读取子程序 ;(A)=键值 ;======================================================== KEY_IN: MOV P1,#0F0H ;置列线为0,行线为1 MOV A,P1 ANL A,#0F0H MOV B,A MOV P1,#0FH ;置列线为1,行线为0 MOV A,P1 ANL A,#0FH ORL A,B ;高四位与低四位重新组合 CJNE A,#0FFH,KEY_IN1 ;0FFH为末按键 RET KEY_IN1: MOV B,A MOV DPTR,#KEYTABLE MOV R3,#0FFH KEY_IN2: INC R3 MOV A,R3 MOVC A,@A+DPTR CJNE A,B,KEY_IN3 MOV A,R3 ;找到,取顺序码 MOV R5,#08H ;延时 CALL DELAY RET KEY_IN3: CJNE A,#0FFH,KEY_IN2 ;末完,继续查 RET ;0FFH为结束码 ;=============================================== ;编码转换为 ASCII 码并显示 ;=============================================== KEY_CONV: MOV 22H,A MOV X,#5 ;设置显示起始位置 MOV A,22H ANL A,#0F0H ;取出高四位二进制数 SWAP A ;高四位与低四位互换 PUSH ACC ;压入堆栈 CLR C ;C=0 SUBB A,#0AH ;减10 POP ACC ;弹出堆栈 JC ASCII0 ;该数小于10,转ASCII0 ADD A,#07H ;大于10的数加上37H ASCII0: ADD A,#30H ;小于10的数加上30H MOV B,X CALL LCDP3
MOV A,22H ANL A,#0FH ;取出低四位二进制数 PUSH ACC CLR C SUBB A,#0AH ;减10 POP ACC JC ASCII1 ;该数小于10,转ASCII0 ADD A,#07H ;大于10的数加上37H ASCII1: ADD A,#30H ;小于10的数加上30H INC X MOV B,X CALL LCDP3 RET ;=================================================== ;蜂鸣器响一声子程序 ;=================================================== BEEP_BL: MOV R6,#100 BL1: CALL DEX1 CPL BEEP DJNZ R6,BL1 MOV R5,#25 CALL DELAY RET DEX1: MOV R7,#180 DEX2: NOP DJNZ R7,DEX2 RET DELAY: ;延时R5×10MS MOV R6,#50 D1: MOV R7,#100 DJNZ R7,$ DJNZ R6,D1 DJNZ R5,DELAY RET ;====================================================== ;延时5MS ;====================================================== DELAY1: MOV R6,#25 DL2: MOV R7,#100 DJNZ R7,$ DJNZ R6,DL2 RET ;====================================================== ;键值顺序码 ;====================================================== KEYTABLE:
DB 0eeH ,077H,0B7H,0D7H, 07bh,0bbh,0dbh ,07dh,0bdh,0ddh, 0e7h,0ebh,0edh, 07eh,0beh,0deh, 0ffh ;----------------------------------------------------- END
|