📄 ex3-10.asm
字号:
;--------------程序信息-----------------
;文件名 : ex3-10.asm
;版本 : 1.0
;作者 :
;修改时间 :
;--------------程序说明------------------
;CHAP 3.10 电子万年历实例
;-----------常量和变量声明---------------
KEYIN EQU P1; 预定义宏变量,键盘输入口
E EQU P3.0; LCD使能端
RW EQU P3.1; LCD读写端
RS EQU P3.3; LCD 数据命令选择端
LCDP EQU P2; LCD 数据端口
SETF BIT 21H; SET标识位
ALARMF BIT 22H; ALARM标识位
BF EQU LCDP.7; LCD忙标志位
LINEF BIT 00H; 换行标志位
;--------------预定义--------------------
ORG 0000H
LJMP START
;------------中断入口地址分配------------
;ORG 0003H
;LJMP INT0PRG
;ORG 000BH
;LJMP INT1PRG
;ORG 0013H;
;LJMP
;ORG 0030H
START:
MOV A,#00H; A,R1,R2寄存器清零
MOV R0,A;
MOV R1,A;
CLR SETF; 标识位清除
CLR ALARMF;
INIT: LCALL LCDINIT; LCD初始化
LCALL RTCINIT; 实时时钟初始化
;--------------初始化子程序--------------
MOV SP,60H;
;--------------主程序--------------------
MAIN:
LCALL KEYBOARD; 扫描键盘,获取键值
MOV A,R0;
CJNE A,#0CH,MAINEND; 判断是否SET键按下
LCALL LCDSETDISP; 显示SET的预先显示字符
MOV R1,00H; 键入字符计数
MOV R2,40H; 单片机内部存储地址
SETPRG:LCALL KEYBOARD; 扫描键盘
SETB SETF;
MOV A,R0; 读出键值
MOV 40H,A;
MOV DPTR,#LCDPOSDB; LCD内部DDRAM地址
MOV A,R1;
MOVC A,@A+DPTR; 获取当前键入值显示地址
MOV LCDP,A; 写地址命令
LCALL WINSTR;
MOV DPTR,#NUM; 根据键值读取相应显示字符编码
MOVC A,@A+DPTR;
MOV LCDP,A; 写入显示数字
LCALL WDATA;
INC R1; 计数器增一
INC R2;
MOV A,R1;
CJNE R1,#0EH,SETPRG; 判断输入是否完备
CJNE A,#0DH,MAINEND; 判断是否ALARM键按下
LCALL LCDALARMDISP; ALARM键按下的处理程序与SET键基本一致,不再解释
MOV R1,00H;
MOV R2,50H;
ALARMPRG:LCALL KEYBOARD; 扫描键盘
SETB ALARMF;
MOV A,R0;
MOV 50H,A;
MOV DPTR,#ALARMPOSDB;
MOV A,R1;
MOVC A,@A+DPTR;
MOV LCDP,A;
LCALL WINSTR;
MOV DPTR,#NUM;
MOVC A,@A+DPTR;
MOV LCDP,A;
LCALL WDATA;
INC R1;
INC R2;
MOV A,R1;
CJNE R1,#06H,ALARMPRG;
MAINEND:
LCALL RTCREAD;
LCALL DISPLAY;
LJMP MAIN
;----------------子程序------------------
;---------------------------------
; 万年历补充和更改子程序部分
;---------------------------------
DISPLAY: ;显示更新子程序,RTCREAD 将秒,分,时,送30H, 31H, 32H
;星期,日,月,年送33H, 34H, 35H, 36H
MOV A,32H; 转化RTC读出数据为可显示的分位数据
DA A; 十六进制转化为BCD编码
MOV R4,A;
ANL A,#0FH; 获取时钟"时"单位的个位
MOV 4AH,A; 将个位存入更新函数个位刷新读取地址
MOV A,R4;
SWAP A;
ANL A,#0FH; 获取时钟"时"单位的十位
MOV 49H,A;
;同样从RTCREAD获取的时间信息中,依次转换存入相应单元
MOV DPTR,#LCDPOSDB;
MOV R1,00H; LCD更新显示部分
MOV R2,40H; 计数器初始化
DISPLOOP:
MOV A,R1;
MOVC A,@A+DPTR; 读取LCD显示DDRAM地址
MOV LCDP,A; 写入地址命令
LCALL WINSTR;
MOV A,40H;
ADD A,#30H; ASCII码转化
MOV LCDP,A; 写入显示数据
LCALL WDATA;
INC R1; 计数器增一
INC R2;
MOV A,R1;
CJNE A,#0EH,DISPLOOP;判断是否时间更新完全
RET;
LCDINIT:
MOV LCDP,#01H; 液晶开显示
CALL WINSTR;
MOV LCDP,#06H; 清屏
CALL WINSTR;
MOV LCDP,#38H; 设置行地址
CALL WINSTR;
MOV LCDP,#80H;
CALL WINSTR;
MOV LCDP,#0FH; 设置光标格式
CALL WINSTR;
SETB LINEF;
RET;
ISBF: ;LCD内部DDRAM读写忙判断子程序
ISBF1:CLR RS; 设定RS,RW读写和数据命令方式
SETB RW;
CLR E;
CALL DELAYLCD; 时序等待延时
SETB E; LCD使能
JB BF,ISBF1; 忙标志位判断
CLR RW;
RET;
;写入命令时序子程序
WINSTR:CLR RS ;设定RS,RW读写和数据命令方式
CLR RW
CLR E
ACALL DELAYLCD ;时序等待延时
SETB E ;LCD使能
RET
WDATA:CLR RW ;写入数据令时序子程序
SETB RS; 设定RS,RW读写和数据命令方式
CLR E;
CALL DELAYLCD; 时序等待延时
SETB E; LCD使能
CLR RS;
RET;
RADDR: CLR RS; 读数据时序子程序
SETB RW; 设定RS,RW读写和数据命令方式
CLR E;
CALL DELAYLCD; 时序延时
SETB E; LCD使能
CLR RW;
RET;
CHGLINE: JB LINEF,CHG1; LCD行末换行子程序
JMP CHG2; 如果是第二行末尾,则跳到第一行首,否则,跳到第一行首
CHG1: MOV LCDP,#0C0H; 跳到第一行首
CALL WINSTR; 写入命令字
CLR LINEF; 清除标志位
JMP CHGEND;
CHG2: MOV LCDP,#80H; 跳到第二行首
CALL WINSTR; 写入命令字
SETB LINEF; 设置标志位
CHGEND:
RET;
NEXTC: CALL RADDR; 字符顺序写入子程序
MOV A,LCDP;
ANL A,#7FH;;0111 1111;
CJNE A,#0FH,NEXTC1; 判断是否行尾,是,则跳转到下一行
CLR LINEF; 是,则清除标志位
MOV LCDP,#0C0H;
CALL WINSTR;
JMP NEXTCEND;
NEXTC1: CJNE A,#4FH,NEXTC0; 判断是第一行未或者第二行尾
SETB LINEF; 设置标志位
MOV LCDP,#080H; 写入命令
CALL WINSTR; 写入命令时序字
JMP NEXTCEND;
NEXTC0: ;INC A;
ADD A,#80H;
MOV LCDP,A;
CALL WINSTR;
NEXTCEND:
RET;
RTCINIT:
RET;
RTCREAD:
RET;
LCDALARMDISP:
RET;
;---------------KEY SUB-------------------
KEYBOARD:
MOV R0,#00H;
ROW: MOV KEYIN,#0FH;
ROW00:JNB KEYIN.0,ROW0;
ROW01:JNB KEYIN.1,ROW1;
ROW02:JNB KEYIN.2,ROW2;
ROW03:JNB KEYIN.3,ROW3;
;JMP ROW00;
JMP KEYBOARDEND;
ROW0: CALL DELAY;
JB KEYIN.0,ROW01;
MOV R0,#00H;
JMP COL;
ROW1: CALL DELAY;
JB KEYIN.1,ROW02;
MOV R0,#01H;
JMP COL;
ROW2: CALL DELAY;
JB KEYIN.2,ROW03;
MOV R0,#03H;
JMP COL;
ROW3: CALL DELAY;
JB KEYIN.3,ROW00;
MOV R0,#02H;
JMP COL;
COL: MOV KEYIN,#0F0H;
COL00:JNB KEYIN.4,COL0;
COL01:JNB KEYIN.5,COL1;
COL02:JNB KEYIN.6,COL2;
COL03:JNB KEYIN.7,COL3;
;JMP COL00;
JMP KEYBOARDEND;
COL0: CALL DELAY;
JB KEYIN.4,COL01;
MOV A,#00H;
ORL A,R0;
MOV R0,A;
JMP KEY;
COL1: CALL DELAY;
JB KEYIN.5,COL02;
MOV A,#10H;
ORL A,R0;
MOV R0,A;
JMP KEY;
COL2: CALL DELAY;
JB KEYIN.6,COL03;
MOV A,#20H;
ORL A,R0;
MOV R0,A;
JMP KEY;
COL3: CALL DELAY;
JB KEYIN.7,COL00;
MOV A,#30H;
ORL A,R0;
MOV R0,A;
JMP KEY;
KEY: MOV A,R0;R0 H BIT COL WEIGH 4 ,R0 L BIT ROW WEIGHT 1;
SWAP A; 00010001
ANL A,#0FH; 0000 0001
RL A;
RL A; 0000 0100
ADD A,R0; 0001 0101
ANL A,#0FH; 0000 0101
MOV R0,A; ;KEYVALUE;
MOV KEYIN,#0FFH;
KEYBOARDEND:
RET;
READKEY: MOV DPTR,#KEYVA;
MOV A,R0;
MOVC A,@A+DPTR;
MOV R0,A;
RET;
LCDSETDISP:
RET;
;--------------中断子程序----------------
;---------------延时子程序---------------
DELAY: MOV R6,#40H;
DELAY0: MOV R7,#248H;
DJNZ R7,$;
DJNZ R6,DELAY0;
RET;
DELAYLCD: MOV R7,#02H;
DELAYLCD1: MOV R6,#255;
DELAYLCD2: DJNZ R6,DELAYLCD2
DJNZ R7,DELAYLCD1
RET
LCDDATEDB: DB "Date: . . ";LCD显示字符表
LCDTIMEDB: DB "Time: : : "
LCDALERMDB: DB " Alarm ";
LCDPOSDB: DB 06H,07H,08H,09H,0BH,0CH,0EH,0FH; LCD显示DDRAM地址
ALARMPOSDB: DB 36H,37H,39H,3AH,3CH,3DH;
NUM: DB "0123456789"; 数字显示代码
KEYVA: DB 0EH,0AH,03H,07H ;KEYBOARD VALUE;
DB 0FH,0BH,04H,08H
DB 0DH,00H,02H,06H
DB 0CH,09H,01H,05H
END
;---------------注意事项-----------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -