51单片机汇编语言学习记录6
实验一:在七段数码管组的计时仿真实验基础上扩展的键盘输入显示实验
实验电路如下:
由上图可见,实验电路图基本是上次作业电路图的扩展,不同之处在于添加了键盘模块,同时数码管的段选信号改为通过一个74HC595的串并转换单元给出(需要注意的是引脚的接口略有调整)。其中74HC595的工作方式如下:每一个字节的段选信号通过P2.1端串行输出到74HC595,输出方式为按字节位由高到低的顺序一位一位输出,每输出一位,P2.0端给595的SH_CP端一个电平信号的上升沿,从而将这一位数据送入595的移位寄存器中,这样循环8次,送完一个字节的段选信号后通过P2.2端给595的ST_CP端一个电平信号的上升沿,595就将这个字节的段选信号并行输出到数码管组的段选端口,从而实现了串行输入并行输出地转换(思考:这样做有什么意义?),实现方法参见教材189页例程。
4x4键盘的行线和列线接到单片机的P1口,列线通过一个与门(图中左下角)接到单片机的P3.2,要求使用线反转法在中断中实现键盘扫描:首先、将行线置低、列线置高,与门输出为高,任意键按下会将对应的列线拉低,这时与门输出为低,从而在P3.2引脚产生了一个电平下降沿,从而触发单片机INT0中断;在中断处理子程序中调用键盘扫描子程序,先扫描出被拉低的列线,记下列值;然后将行线置高,列线置低,扫描被拉低的行线,记下行值,根据行值和列值求出所按键键值。
读出键值后,将该键值显示在数码管组的最右一位,原先显示的数字左移,如下图,是数码管的初始状态,显示全零:
实验二、双字节数输入及乘法实验
实验电路如下:
图中6260060为十六进制数1234与5678的乘积。说明如下,在上一个设计的基础上,将两个数码管组显示的内容(亦即从键盘顺序输入的数)作为两个双字节的十六进制数,通过一个接地的开关(开关另一端连接到单片机的P3.3口)产生一次INT1中断,在INT1中断处理程序中调用双字节数乘法子程序(课上讲过),实现数码管所显示的两个数的乘,同时将积显示到数码管上。
;*****-******单片机综合作业1*************
;************2019-6-20 DXZ *************
LINENUM DATA 30H ;行数
COLUNMNUM DATA 31H ;列数
KEYNUM DATA 32H ;存放当前按键值
SHOWNUM0 DATA 33H ;第1-2次按键显示值
SHOWNUM1 DATA 34H ;第3-4次按键显示值
SHOWNUM2 DATA 35H ;第5-6次按键显示值
SHOWNUM3 DATA 36H ;第7-8次按键显示值
KEYSTATE BIT 00H ;按键标志位
SCLK_595 BIT P2.0 ;595串行输入数据时钟
SDATA_595 BIT P2.1 ;595数据线
RCK_595 BIT P2.2 ;595并行输出数据时钟
ORG 0000H
LJMP MAIN
ORG 0003H
LJMP EXIPT0
ORG 0030H
MAIN:
MOV SP, #70H ;设置堆栈指针
SETB EX0 ;外部中断0初始化
SETB IT0
SETB EA
START: MOV LINENUM, #00H ;行列赋初值0
MOV COLUNMNUM, #00H
MOV SHOWNUM0, #00H ;显示按键数赋初值0
MOV SHOWNUM1, #00H
MOV SHOWNUM2, #00H
MOV SHOWNUM3, #00H
MOV P1, #0F0H ;扫描条件初始化
CYCLE: MOV A, SHOWNUM0 ;送低四位至数码管1
ANL A, #0FH ;取低四位
MOV DPTR, #TABLED
MOVC A, @A+DPTR
LCALL USE_595 ;查表显示(送段码)
MOV P2, #80H ;循环扫描显示
LCALL DELAY ;两位数码管显示间的延时
CLR P2.7 ;消隐
MOV A, SHOWNUM0 ;送高四位至数码管2
ANL A, #0F0H ;取高四位
SWAP A ;高低位互换
MOV DPTR, #TABLED ;查表显示(送show0高位段码)
MOVC A, @A+DPTR
LCALL USE_595
MOV P2, #90H ;送位码
LCALL DELAY
CLR P2.7 ;消隐
MOV A, SHOWNUM1 ;显示数码管3-4位
ANL A, #0FH
MOV DPTR, #TABLED
MOVC A, @A+DPTR
LCALL USE_595
MOV P2, #0A0H
LCALL DELAY
CLR P2.7 ;消隐
MOV A, SHOWNUM1
ANL A, #0F0H
SWAP A
MOV DPTR, #TABLED
MOVC A, @A+DPTR
LCALL USE_595
MOV P2, #0B0H
LCALL DELAY
CLR P2.7 ;消隐
MOV A, SHOWNUM2 ;显示数码管5-6位
ANL A, #0FH
MOV DPTR, #TABLED
MOVC A, @A+DPTR
LCALL USE_595
MOV P2, #0C0H
LCALL DELAY
CLR P2.7 ;消隐
MOV A, SHOWNUM2
ANL A, #0F0H
SWAP A
MOV DPTR, #TABLED
MOVC A, @A+DPTR
LCALL USE_595
MOV P2, #0D0H
LCALL DELAY
CLR P2.7 ;消隐
MOV A, SHOWNUM3 ;显示数码管7-8位
ANL A, #0FH
MOV DPTR, #TABLED
MOVC A, @A+DPTR
LCALL USE_595
MOV P2, #0E0H
LCALL DELAY
CLR P2.7 ;消隐
MOV A, SHOWNUM3
ANL A, #0F0H
SWAP A
MOV DPTR, #TABLED
MOVC A, @A+DPTR
LCALL USE_595
MOV P2, #0F0H
LCALL DELAY
CLR P2.7 ;消隐
LJMP CYCLE
USE_595: ;595发送子函数
MOV R4, #08H
CIRCLE:RLC A
CLR SCLK_595 ;sclk上升沿串行送入数据
MOV SDATA_595, C
SETB SCLK_595
NOP
NOP
DJNZ R4, CIRCLE
CLR RCK_595 ;rclk上升沿并行送出数据
NOP
NOP
SETB RCK_595
RET
RLC4: ;左移4位补0
CLR C
RLC A
CLR C
RLC A
CLR C
RLC A
CLR C
RLC A
RET
DELAY:
MOV R5, 100
DJNZ R5, $
RET
EXIPT0:
CLR EA ;关中断,防治处理过程中又来中断
PUSH PSW
PUSH ACC
MOV R7, #4 ;行列扫描次数定初值
MOV R6, #4
MOV A, P1
ANL A, #0F0H
COLSCAN: JNB ACC.4, OVERTURN
INC COLUNMNUM ;扫描列,不是则列加一,是则跳转扫描行
RR A
DJNZ R7, COLSCAN
OVERTURN: MOV P1, #0FH
MOV A, P1
LINESCAN: JNB ACC.0, CALKEYNUM ;扫描行,是则跳转计算键值,否则加一继续扫
INC LINENUM
RR A
DJNZ R6, LINESCAN
CALKEYNUM:MOV A, LINENUM ;计算键值
RL A
RL A
ADD A, COLUNMNUM
MOV KEYNUM, A
MOV COLUNMNUM, #00H
MOV LINENUM, #00H
MOV P1, #0F0H
MOV A, SHOWNUM3 ;数码管显示位左移一位
LCALL RLC4 ;按键显示值整体左移四位补0
MOV B, A
MOV A, SHOWNUM2
ANL A, #0F0H
SWAP A
ORL A, B
MOV SHOWNUM3, A
MOV A, SHOWNUM2
LCALL RLC4
MOV B, A
MOV A, SHOWNUM1
ANL A, #0F0H
SWAP A
ORL A, B
MOV SHOWNUM2, A
MOV A, SHOWNUM1
LCALL RLC4
MOV B, A
MOV A, SHOWNUM0
ANL A, #0F0H
SWAP A
ORL A, B
MOV SHOWNUM1, A
MOV A, SHOWNUM0
LCALL RLC4
MOV B, A
MOV A, KEYNUM ;键值送入show0低四位
ORL A, B
MOV SHOWNUM0, A
POP ACC ;恢复现场
POP PSW
SETB EA
RETI
TABLED: ;段码表
DB 3FH, 06H, 5BH, 4FH, 66H, 6DH, 7DH, 07H
DB 7FH, 6FH, 77H, 7CH, 39H, 5EH, 79H, 71H
END
实验二、双字节数输入及乘法实验
```c
代码如下:
;*****-******单片机综合作业2双字节乘法结果显示*************
;*********************2019-6-24 DXZ ***********************
LINENUM DATA 30H ;行数
COLUNMNUM DATA 31H ;列数
KEYNUM DATA 32H ;存放当前按键值
SHOWNUM0 DATA 33H ;第1-2次按键显示值/乘积低位显示值
SHOWNUM1 DATA 34H ;第3-4次按键显示值/乘积低位显示值
SHOWNUM2 DATA 35H ;第5-6次按键显示值/乘积次高位显示值
SHOWNUM3 DATA 36H ;第7-8次按键显示值/乘积高位显示值
KEYSTATE BIT 00H ;按键标志位
SCLK_595 BIT P2.0 ;595串行输入数据时钟
SDATA_595 BIT P2.1 ;595数据线
RCK_595 BIT P2.2 ;595并行输出数据时钟
ORG 0000H
LJMP MAIN
ORG 0003H ;外部中断0入口
LJMP EXIPT0 ;外部中断0服务子函数
ORG 0013H ;外部中断1入口
LJMP EXIPT1 ;外部中断1服务子函数
ORG 0030H
MAIN:
MOV SP, #70H ;设置堆栈指针
SETB EX0 ;外部中断0初始化
SETB IT0
SETB EX1 ;外部中断1初始化
SETB IT1
SETB EA ;开总中断
START: MOV LINENUM, #00H ;行列赋初值0
MOV COLUNMNUM, #00H
MOV SHOWNUM0, #00H ;显示按键数赋初值0
MOV SHOWNUM1, #00H
MOV SHOWNUM2, #00H
MOV SHOWNUM3, #00H
MOV P1, #0F0H ;扫描条件初始化
CYCLE: MOV A, SHOWNUM0 ;送低四位至数码管1
ANL A, #0FH ;取低四位
MOV DPTR, #TABLED
MOVC A, @A+DPTR
LCALL USE_595 ;查表显示(送段码)
MOV P2, #80H ;循环扫描显示
LCALL DELAY ;两位数码管显示间的延时
CLR P2.7 ;消隐
MOV A, SHOWNUM0 ;送高四位至数码管2
ANL A, #0F0H ;取高四位
SWAP A ;高低位互换
MOV DPTR, #TABLED ;查表显示(送show0高位段码)
MOVC A, @A+DPTR
LCALL USE_595
MOV P2, #90H ;送位码
LCALL DELAY
CLR P2.7 ;消隐
MOV A, SHOWNUM1 ;显示数码管3-4位
ANL A, #0FH
MOV DPTR, #TABLED
MOVC A, @A+DPTR
LCALL USE_595
MOV P2, #0A0H
LCALL DELAY
CLR P2.7 ;消隐
MOV A, SHOWNUM1
ANL A, #0F0H
SWAP A
MOV DPTR, #TABLED
MOVC A, @A+DPTR
LCALL USE_595
MOV P2, #0B0H
LCALL DELAY
CLR P2.7 ;消隐
MOV A, SHOWNUM2 ;显示数码管5-6位
ANL A, #0FH
MOV DPTR, #TABLED
MOVC A, @A+DPTR
LCALL USE_595
MOV P2, #0C0H
LCALL DELAY
CLR P2.7 ;消隐
MOV A, SHOWNUM2
ANL A, #0F0H
SWAP A
MOV DPTR, #TABLED
MOVC A, @A+DPTR
LCALL USE_595
MOV P2, #0D0H
LCALL DELAY
CLR P2.7 ;消隐
MOV A, SHOWNUM3 ;显示数码管7-8位
ANL A, #0FH
MOV DPTR, #TABLED
MOVC A, @A+DPTR
LCALL USE_595
MOV P2, #0E0H
LCALL DELAY
CLR P2.7 ;消隐
MOV A, SHOWNUM3
ANL A, #0F0H
SWAP A
MOV DPTR, #TABLED
MOVC A, @A+DPTR
LCALL USE_595
MOV P2, #0F0H
LCALL DELAY
CLR P2.7 ;消隐
LJMP CYCLE
USE_595: ;595发送子函数
MOV R4, #08H
CIRCLE:RLC A
CLR SCLK_595 ;sclk上升沿串行送入数据
MOV SDATA_595, C
SETB SCLK_595
NOP
NOP
DJNZ R4, CIRCLE
CLR RCK_595 ;rclk上升沿并行送出数据
NOP
NOP
SETB RCK_595
RET
RLC4: ;左移4位补0
CLR C
RLC A
CLR C
RLC A
CLR C
RLC A
CLR C
RLC A
RET
DELAY: ;动态数码管扫描延时(大约200uS)
MOV R5, 100
DJNZ R5, $
RET
EXIPT0: ;外部中断0处理子函数
CLR EA ;关中断,防治处理过程中又来中断
PUSH PSW ;保护现场
PUSH ACC
MOV R7, #4 ;行列扫描次数定初值
MOV R6, #4
MOV A, P1
ANL A, #0F0H
COLSCAN: JNB ACC.4, OVERTURN
INC COLUNMNUM ;扫描列,不是则列加一,是则跳转扫描行
RR A
DJNZ R7, COLSCAN
OVERTURN: MOV P1, #0FH
MOV A, P1
LINESCAN: JNB ACC.0, CALKEYNUM ;扫描行,是则跳转计算键值,否则加一继续扫
INC LINENUM
RR A
DJNZ R6, LINESCAN
CALKEYNUM:MOV A, LINENUM ;计算键值
RL A
RL A
ADD A, COLUNMNUM
MOV KEYNUM, A
MOV COLUNMNUM, #00H
MOV LINENUM, #00H
MOV P1, #0F0H
MOV A, SHOWNUM3 ;数码管显示位左移一位
LCALL RLC4 ;按键显示值整体左移四位补0
MOV B, A
MOV A, SHOWNUM2
ANL A, #0F0H
SWAP A
ORL A, B
MOV SHOWNUM3, A
MOV A, SHOWNUM2
LCALL RLC4
MOV B, A
MOV A, SHOWNUM1
ANL A, #0F0H
SWAP A
ORL A, B
MOV SHOWNUM2, A
MOV A, SHOWNUM1
LCALL RLC4
MOV B, A
MOV A, SHOWNUM0
ANL A, #0F0H
SWAP A
ORL A, B
MOV SHOWNUM1, A
MOV A, SHOWNUM0
LCALL RLC4
MOV B, A
MOV A, KEYNUM ;键值送入show0低四位
ORL A, B
MOV SHOWNUM0, A
POP ACC ;恢复现场
POP PSW
SETB EA
RETI
EXIPT1: ;外部中断1服务子函数,乘法调用
PUSH PSW ;保护现场
PUSH ACC
SETB RS1 ;更改工作寄存器组
SETB RS0
CLR C
MOV A, SHOWNUM0 ;乘数A1
MOV B, SHOWNUM2 ;乘数B1
MUL AB
MOV R0, A ;乘积低位放R0
MOV R1, B ;乘积次低位放R1
MOV A, SHOWNUM1 ;乘数A2
MOV B, SHOWNUM2
MUL AB
ADD A, R1
MOV R1, A
MOV A, B
ADDC A, #00H
MOV R2, A ;乘积次高位放R2
MOV A, SHOWNUM0
MOV B, SHOWNUM3 ;乘数B2
MUL AB
ADD A, R1
MOV R1, A
MOV A, B
ADDC A, R2
MOV R2, A
CLR A
ADDC A, #00H
MOV R3, A ;乘积高位放R3
MOV A, SHOWNUM1
MOV B, SHOWNUM3
MUL AB
ADD A, R2
MOV R2, A
MOV A, B
ADDC A, R3
MOV R3, A
MOV SHOWNUM0, R0 ;乘积低位
MOV SHOWNUM1, R1 ;乘积次低位
MOV SHOWNUM2, R2 ;乘积次高位
MOV SHOWNUM3, R3 ;乘积高位
POP ACC ;恢复现场
POP PSW
RETI ;返回
TABLED: ;段码表
DB 3FH, 06H, 5BH, 4FH, 66H, 6DH, 7DH, 07H
DB 7FH, 6FH, 77H, 7CH, 39H, 5EH, 79H, 71H
END