51汇编:用两个数码管计数按键次数

前言

不同的架构不同的指令系统,没事别乱学汇编。

我现在学的是51单片机的汇编,运行在Keil5上。希望慢慢熟悉更多的指令,因为更多的指令意味着更多的选择,在实现功能时能更轻松一点。

玩硬件的我又穷又头痛,就这个小任务我写了一天了才做出来。最后的效果可以清楚显示从00到16的值,但是更多的次数就会出错了。

先贴出全部代码,下面再解释

	org 0000h
	sjmp main


main:
	mov dptr,#TAB
	mov r0,#0   
start:
	mov p3,#0fh  


message:
	mov a,p3 
	anl a,#0fh   
	cjne a,#0fh,show
	ljmp message

show:
	mov a,r0
	clr c
	subb a,#10
	jnc normal ;无借位
	mov a,#0
	lcall show_shiwei
	mov a,r0
	ljmp just_show_geiwei
normal:	 
	push acc  ;保存减去10后的a的值
	mov a,#1 
	lcall show_shiwei
	pop acc
just_show_geiwei:
	movc a,@a+dptr  
	mov p2,#0e3h  
	mov p0,a  
	lcall delay 
	INC r0
	ljmp start
	

show_shiwei:
	movc a,@a+dptr
	mov p2,#0e7h
	mov p0,a
	lcall delay
	ret
	
delay:
	mov r3,#200
L1:
	mov r4,#500  
	djnz r4,$
	djnz r3,L1
	ret

TAB: 
	db 	3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh,77h,7ch,39h,5eh,79h,71h     
	
	end
	
  • 标识符确定的模块放的位置很关键。如果是单独的函数,那么需要放在程序底下(END前)或者顶上(ORG 000H下)的一些边缘位置。如果是程序内的循环和条件判断需要特别考虑。这些是一些编程规范(不这么写也许行)
  • 汇编也没有函数的定义,并且对于玩过《7 Billion Humans》的人来说,难度不是很大。毕竟益智类的编程游戏没有函数概念,只有跳转和判断。在汇编中,没有单独的条件判断,其必须由条件跳转来实现---------下面黑框中,向上跳的绿色表示这是一个循环。向下跳的蓝色箭头表示这是一个判断。

在这里插入图片描述

延迟模块,DJNZ跳转语句表示减一不为0跳转
先给寄存器R3送一个数
再给寄存器R4送一个数
接着拿R4减一,再原地跳转
然后拿R3减一,跳到L1标识符处
RET返回

	
delay:
	mov r3,#200
L1:
	mov r4,#500  
	djnz r4,$
	djnz r3,L1
	ret

TAB也是自定义表示符,DB表示从当前PC(程序指针)所指向的地址开始放入数据,放一个PC指针移动一个单元。


TAB: 
	db 	3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh,77h,7ch,39h,5eh,79h,71h     
	

开头的部分分别是
开头两行:确定PC起点,跳到MAIN标识符处
把TAB标识符的地址给DPTR这个16位指针
把0送给R0寄存器,也就是这个寄存器用于计数
然后这个START标识符的意义是每次显示完,再跳回START初始化P3

  • 我单片机独立按键k1=P3.1 k2=P3.0 k3=P3.2 k4=P3.4
  • 不同的单片机或是自己做的或是Proteus仿真的情况不同就可能是另外情况了
	org 0000h
	sjmp main


main:
	mov dptr,#TAB
	mov r0,#0   
start:
	mov p3,#0fh  


这个是程序的核心部分之一。属于等待按键输入模块。
我的按键输入是P3的三个口,所以先把P3传递给累加器A
然后用ANL与操作来屏蔽高4位
CJNE表示两者数值不同就跳转(相当于前者减后者,如果为零就跳转---------如果前者大,那么PSW寄存器的进位位C是1,否则是0)

独立按键是为零就表示闭合了。

拿累加器A的值和00001111比较,如果低4位某个位0,那么一定有键被按下

最后是一个LJMP长跳转,跳回MESSAGE标识符


message:
	mov a,p3 
	anl a,#0fh   
	cjne a,#0fh,show
	ljmp message

下面这个就是如何把R0计数的值显示出来的核心部分了

P3作为按键输入
P0作为数码管显示输出
P2作为数码管片选控制


show:
	mov a,r0  		;把R0计数的值传给A
	clr c   		;清楚进位C
	subb a,#10		;带进位的相减,(A) = (A)- 10
	jnc normal 		;无借位		;如果没有产生进位,表示按键次数超过9

	;有进位,向下执行  表示按键次数不超过9
	mov a,#0						 ;设置十位的值为0
	lcall show_shiwei      		  ;调用显示10位的函数
	mov a,r0   						;个位部分还是正常的,所以要再把R0传过来
	ljmp just_show_geiwei   
normal:	 
	push acc  			;保存减去10后的a的值    把A的值压如栈
	mov a,#1  			;设置十位的值为1
	lcall show_shiwei    ;调用显示10位的函数
	pop acc 		  ;把值取出传给A
just_show_geiwei:
	movc a,@a+dptr  
	mov p2,#0e3h  
	mov p0,a  
	lcall delay 
	INC r0
	ljmp start
	
	;显示十位的共同部分
show_shiwei:
	movc a,@a+dptr ;把TAB的地址和偏移量A表示的表里的值取出,传给A
	mov p2,#0e7h  ;1110 0111选择倒数第二片
	mov p0,a  ;显示
	lcall delay  ;延迟
	ret    ;函数返回
	

猜你喜欢

转载自blog.csdn.net/weixin_41374099/article/details/88804935