8086仿真矩阵键盘的Proteus仿真

10 篇文章 1 订阅
10 篇文章 0 订阅

Proteus中要对8086输入信号要使用到16*16矩阵键盘,键盘
键盘输入在查阅资料后发现主要有两种方法,第一种是先将行设为输出,列设为输入,判断按键位于哪一列。将行线全部置为低,输入列的电平数据判断是否有列当前为低电平,如果有延时后继续判断该低电平信号是否存在仍然存在记录该列的序号,如果没有继续检测。如果记录了列的数据之后,将行设为输入,列设为输出,判断是否有行当前为低电平,如果有延时一段时间之后继续检测如果该信号仍然存在记录该行的序号,如果没有继续检测,这样按下一个按键之后分别检测行和列的数据。
还有一种方法是每一行一次输出低电平检测该行的所有列是否有低电平即是否有键被按下,如果有延时后继续判断该低电平信号是否存在如果仍然存在记录输入的列键值,如果没有继续扫描下一行。扫描完成一轮后循环检测继续从第一行开始扫描。因为一次扫描的每一行因此行数是已知的,只需要判断列数。
下面讲给出两种方法的代码和利弊:
第一种方法先读取行再读取列:

DATAS SEGMENT
    ;此处输入数据段代码  
    IOYO equ 0E000h;对应的端口地址
    MY8255_A equ IOYO+00H*4
    MY8255_B equ IOYO+01H*4
    MY8255_C equ IOYO+02H*4
    MY8255_MODE equ IOYO+03H*4 
    LED db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h
    	db 7fh,6fh,77h,7ch,39h,5eh,79h,71h,00h
	Current_led db 10h
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
    dw 50 dup(?)
    top label byte
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
	mov ax,stacks
	mov ss,ax
	mov sp,offset top
    MOV AX,DATAS
    MOV DS,AX
    ;此处输入代码段代码
    ;写入控制字
Restart:
    mov al,10000001B;A口和B口都为输出,C口的高位为列输出,C口的低位为行写入
    mov dx,MY8255_MODE
    out dx,al
    call disp
    ;列全为低找第几行
Waitkey_row:
	mov al,00h
	mov dx,MY8255_C
	out dx,al;先让列都为低
	in al,dx;读取列中的数据
	and al,0fh;只有低四位有效
	cmp al,0fh
	jnc waitkey_row;没有改变,继续检测
	;检测到列存在低电平,进行延时
	mov cx,0f00h
	loop $	
	mov al,00h
	out dx,al
	in al,dx
	and al,0fh
	cmp al,0fh
	jnc waitkey_row;两次读入都有数据
	mov dl,0;dl用来存储行数据
	mov cx,4
Find_row:
	shr al,1
	jnc record_row;进位标志位0说明就在当前行
	inc dl
	loop Find_row
Record_row:
	mov bl,dl
	mov al,10001000B;A口和B口都为输出,C口的高位为列输入,C口的低位为行输出
	mov dx,MY8255_MODE
	out dx,al
Waitkey_line:
	mov al,00h
	mov dx,MY8255_C
	out dx,al
	in al,dx
	and al,0f0h
	cmp al,0f0h
	jnc waitkey_line
	mov cx,0f00h
	loop $
	mov al,00h
	out dx,al
	in al,dx
	and al,0f0h
	cmp al,0f0h
	jnc waitkey_line
	mov cl,4;al在高四位因此要移动到第四位
	shr al,cl
	mov dl,00h
	mov cx,4
Find_line:
	shr al,1
	jnc Record_line
	inc dl
	loop find_line
Record_line:
	mov al,bl;行的数据保存在bl中,列的数据保存在dl中
	shl al,1
	shl al,1
	add al,dl
	mov current_led,al
	call disp	
	jmp restart
	
Disp proc near;数码管显示部分
	mov bl,current_led
	mov bh,00h
	mov al,LED[bx]
	mov dx,MY8255_A
	out dx,al
	ret
Disp endp

Exit:
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

第二种方法按行进行扫描:

DATAS SEGMENT
    ;此处输入数据段代码  
    IOYO equ 0E000h;对应的端口地址
    MY8255_A equ IOYO+00H*4
    MY8255_B equ IOYO+01H*4
    MY8255_C equ IOYO+02H*4
    MY8255_MODE equ IOYO+03H*4 
    LED db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h
    	db 7fh,6fh,77h,7ch,39h,5eh,79h,71h,00h
	Current_led db 10h
    Row_disp db 0feh,0fdh,0fbh,0f7h
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
    dw 50 dup(?)
    top label byte
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
	mov ax,stacks
	mov ss,ax
	mov sp,offset top
    MOV AX,DATAS
    MOV DS,AX
    ;此处输入代码段代码
    ;写入控制字
	mov al,10001000B;A为输出信号,C的高位为输入信号列,低位为输出信号行
	mov dx,MY8255_mode
	out dx,al
	call disp
	mov bh,00h;从第零行开始扫描
	mov bl,00h
Restart:
	call disp
Detect_row:
	mov dx,MY8255_C
	mov al,row_disp[bx]
	out dx,al
	in al,dx
	and al,0f0h
	cmp al,0f0h
	jnc next_line;无输入直接转到下一行
	mov cx,5000h
	loop $
	in al,dx
	and al,0f0h
	cmp al,0f0h
	jnc next_line
	mov dl,0;用于记录该行中列的数据
	mov cx,4
Find_line:
	shl al,1
	jnc record_line;无进位说明是列
	inc dl
	loop Find_line
Record_line:
	mov al,bl;行的数据保存在bl中,列的数据保存在dl中
	shl al,1
	shl al,1
	mov dh,03h
	sub dh,dl
	add al,dh
	mov current_led,al
	call disp
	;记录之后继续扫描下一行
Next_line:
	call delay
	add bl,01h
	and bl,0fbh
	jmp restart

Disp proc near;数码管显示部分
	mov bl,current_led
	mov bh,00h
	mov al,LED[bx]
	mov dx,MY8255_A
	out dx,al
	ret
Disp endp

delay proc near;软件延时程序
	push cx
	push ax
	mov cx,011h
D1:
	mov ax,00ffh
D2:
	dec ax
	jnz d2
	loop d1
	pop ax
	pop cx
	ret
delay endp	

Exit:
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

完整电路图:
电路图
两种方法的比较,使用的第一种方法经常会出现串行的情况,明明输入的5,5被点亮之后1也被点亮了,或是按下的1点亮的5。一开始考虑是不是进位表示没有被清零,按键时间长之后,判断有按键按下,因为进位标志没有被清零会有这种情况,加入了进位标志清零命令后仍然偶尔会出现这种情况。第一种方法还会出现这种情况,就是只按了一次某一个键可是8086确记为多次,因此要将两次检测的间隔试剂设置得比较长。
第二种方法不会出现第一种方法的问题,第二种方法的要调整好两次扫描的间隔时间和两行扫描的间隔时间,不然会出现按键之后没有被检测到的情况。
个人觉得第二种方法的检测更加准确。
如果输入的数据是一组数放在一个数组中,为了防止误按的情况可以检测这一次输入的数据和上一次输入的数据是否相同。
比如这样,数组为seq,这一次的数据放在al中,num为seq中数据的长度:

compare:
	mov bl,num;num表示数据的长度
	dec bl;上一次的数据
	mov dl,seq[bx];上一次的数据存储在dl中,seq的末尾
	cmp dl,al;这一次的数据存储在al中
	je stop1;如果相等退出,不记录这一次的结果
  • 8
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
矩阵键盘是一种常见的输入设备,可通过按键输入不同的字符或指令。MSP430是一种微控制器芯片,具有低功耗和高性能的特点。Proteus是一款电子电路仿真软件,可以对电路进行模拟和调试。 要在Proteus中进行MSP430的矩阵键盘仿真,需要进行以下步骤: 1. 打开Proteus软件,并创建一个新的电路设计。 2. 在电路设计中添加MSP430微控制器芯片模型。可以从Proteus软件自带的元件库中选择合适的模型。 3. 连接MSP430芯片与其他电路元件,如电源、晶振等。 4. 在电路设计中添加矩阵键盘模型。同样可以从Proteus软件的元件库中选择合适的模型。 5. 连接矩阵键盘与MSP430芯片。这包括矩阵键盘的行线和列线与相应的IO口进行连接。 6. 配置MSP430芯片的IO口功能和工作模式。根据实际需求将IO口设置为输入或输出模式,并配置相应的中断或轮询方式。 7. 编写MSP430芯片的程序代码。根据键盘输入的不同按键,编写相应的处理代码和逻辑功能。 8. 在Proteus软件中运行仿真并测试矩阵键盘的输入功能。可以通过监视相应的IO口状态或在仿真窗口中模拟按下矩阵键盘的按键来测试输入功能的正确性。 总之,通过在Proteus软件中使用MSP430芯片模型和矩阵键盘模型,结合适当的电路设计和程序编写,可以进行MSP430矩阵键盘仿真和测试。这有助于在实际应用中更好地理解和调试MSP430芯片与矩阵键盘的工作原理和功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值