📄 99qda.asm
字号:
;/********************************************************************************
;* 标题: xl系列单片机实验仪演示程序 乘法口诀模拟答题器 *
;* 日期: 2006-1-5 *
;* 版本: 3.0 (试验通过版)可用xl600-xl1000单片机综合试验仪试验 *
;* 邮箱: sxj1974@163.com *
;* 网站: http://www.51c51.com www.8951.com *
;********************************************************************************
;* 描述: *
;* 0#--- 模拟出题控制开关; 0c--- 正确答案提示; *
;* (0-9)--- 有效数字输入; *
;* 开机后,按0#键,随机出题,看到题目后从键盘输入答案 答题正确,蜂鸣器响3声 *
; 继续出下一题,如果不知道答案则按0c键, 提示正确的答案 *
;* 硬件连接:插上1602液晶,喇叭接P3.7 ,矩阵键盘接p1口 *
;********************************************************************************
;* 【版权】 Copyright(C)深圳市学林电子有限公司 www.51c51.com *
;* 【声明】 此程序仅用于学习与参考,引用请注明版权和作者信息! *
;* 【技术支持】请访问http://www.51c51.com/bbs/index.asp 官方论坛 *
;********************************************************************************/
TEMP EQU 40H ;被乘数、乘数、乘积存放单元
HDATA EQU 45H ;输入答案值高位
LDATA EQU 46H ;输入答案值低位
STRING BIT 20H.0 ;写字符串延时标志
TRUER BIT 20H.1 ;数据比较正确标志
KEYDOWN BIT 20H.3 ;键按下标志
BEEP BIT P3.7
LCD_RS EQU P2.0
LCD_RW EQU P2.1
LCD_EN EQU P2.2
;**********************************************************
ORG 0000H
LJMP MAIN
ORG 0030H
;**********************************************************
; 主程序
;**********************************************************
MAIN:
MOV SP,#70H
MOV TEMP+0,#00H ;初始化内存单元
MOV TEMP+1,#00H
MOV TEMP+2,#00H
MOV TEMP+3,#00H
MOV HDATA,#00H
MOV LDATA,#00H
CLR KEYDOWN
ACALL LCD_INIT
SETB STRING
MOV A,#80H ;显示在第一行
MOV DPTR,#CHAR1
ACALL WR_STRING ;显示 WELCOME TO
MOV A,#0C0H ;显示在第二行
ACALL LCD_CMD
MOV DPTR,#CHAR2 ;
ACALL WR_STRING
MOV R5,#20
MAIN1:
ACALL DELAY ;延时
ACALL DELAY
DJNZ R5,MAIN1
CLR STRING
MOV A,#01H ;清除屏幕
ACALL LCD_CMD
MOV A,#80H ;显示在第一行
MOV DPTR,#CHAR3 ;显示字符串3
ACALL WR_STRING
MOV A,#0C0H ;显示在第二行
ACALL LCD_CMD
MOV DPTR,#CHAR4 ;显示字符串4
ACALL WR_STRING
MOV TMOD,#20H ;将T1设置为8位自动重装工作方式。
MOV TH1,#175 ;对T1定时常数进行预置。
MOV TL1,#175
SETB TR1 ;启动T1。
MAIN2:
CALL KEY_SCAN
CJNE A,#0FH,MAIN2 ;F 随机出题键
CALL RUBRIC ;出题
CALL DISP ;显示题目
MAIN3:
CALL KEY_DATA ;键入答案值
CALL DATA_COMP ;数据比较
JB TRUER,MAIN2 ;比较正确后,重新出题
CALL ASK_DISP
JNB TRUER,MAIN3 ;比较不正确,重新答题
JMP MAIN1
;***************************************************************
; 键入数据子程序
;***************************************************************
KEY_DATA:
MOV A,TEMP+1
CJNE A,#30H,K_DATA1 ;乘积高位为0,则跳过输入高位值
JMP K_DATA2
K_DATA1:
CALL KEY_SCAN
JNB KEYDOWN,K_DATA1 ;无键按下返回
CJNE A,#0CH,K_DATA1A ;C 键,输入正确答案
CALL PRODUCT_DISP ;显示正确答案
JMP KEY_END
K_DATA1A:
CLR C
SUBB A,#0AH ;判是否为有效的数字键
JNC K_DATA1 ;为无效键返回
MOV A,R3
ADD A,#30H
MOV HDATA,A ;键入答案高位
MOV A,#0CBH ;显示键入答案高位
ACALL LCD_CMD
MOV A,HDATA
ACALL LCD_WDATA
MOV A,#20H
ACALL LCD_WDATA
K_DATA2:
CALL KEY_SCAN
JNB KEYDOWN,K_DATA2 ;无键按下返回
CJNE A,#0CH,K_DATA2A ;C 键,输入正确答案
CALL PRODUCT_DISP ;显示正确答案
JMP KEY_END
K_DATA2A:
CLR C
SUBB A,#0AH ;判是否为有效的数字键
K_DATA3:
JNC K_DATA2 ;为无效键返回
MOV A,R3
ADD A,#30H
MOV LDATA,A ;键入答案低位
MOV A,#0CCH ;显示键入答案低位
ACALL LCD_CMD
MOV A,LDATA
ACALL LCD_WDATA
KEY_END:
RET
;***************************************************************
; 数据比较子程序
;***************************************************************
DATA_COMP:
MOV A,TEMP+1 ;判乘积的高位是否为0
CJNE A,#30H,COMP1
JMP COMP2 ;高位为0,跳过高位比较
COMP1:
MOV B,HDATA
CJNE A,B,COMP3 ;比较高位
COMP2:
MOV A,TEMP+0
MOV B,LDATA
CJNE A,B,COMP3 ;比较低位
SETB TRUER
CALL BEEP_BL ;比较正确,蜂鸣器响3声
CALL BEEP_BL
CALL BEEP_BL
JMP COMP_END
COMP3:
CLR TRUER ;比较错误
COMP_END:
RET
;***************************************************************
;写指令数据到LCD
;RS=L,RW=L,D0-D7=指令码,E=高脉冲
;***************************************************************
LCD_CMD:
ACALL CHECKBUSY
LCD_CMD_NC:
CLR LCD_RS
CLR LCD_RW
MOV P0,A
SETB LCD_EN
NOP
NOP
NOP
NOP
CLR LCD_EN
RET
;***************************************************************
;写显示数据到LCD
;RS=H,RW=L,D0-D7=数据,E=高脉冲
;***************************************************************
LCD_WDATA:
ACALL CHECKBUSY
SETB LCD_RS
CLR LCD_RW
MOV P0,A
SETB LCD_EN
NOP
NOP
NOP
NOP
CLR LCD_EN
RET
;***************************************************************
;检测LCD控制器忙状态
;读数据
;RS=L,RW=H,E=H,输出:D0-D7=数据
;***************************************************************
CHECKBUSY:
PUSH ACC
MOV P0,#0FFH
CLR LCD_RS
SETB LCD_RW
SETB LCD_EN
BUSYLOOP:
NOP
JB P0.7,BUSYLOOP
CLR LCD_EN
POP ACC
RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -