📄 keyboard12.s43
字号:
;------------------------------------------------------------------------------
;文件名称:
; keyBoard12_a.s43
;文件说明:
; 接收行列扫描键盘的输入,并把显示键值到LED
;
;------------------------------------------------------------------------------
#include "msp430x44x.h"
;------------------------------------------------------------------------------
; 定义数据
;------------------------------------------------------------------------------
LED_Buf equ 200H ;LED显示数据缓存,共六个字节
LED_CTRL equ 206H ;LED显示位控制
KEY_Pressed equ 207H ;按键是否按下
KEY_Val equ 208H ;键值
KEY_Flag equ 209H ;键值是否可以读取
;------------------------------------------------------------------------------
ORG 08000h ; 设置程序起始位置
;------------------------------------------------------------------------------
RESET mov.w #0600h,SP ; 初始化堆栈
main:
push.w R10
mov.w #0x5A80,&WDTCTL ;关看门狗
call #init_Keyboard ;初始化键盘
call #init_LED ;初始化LED
call #init_BT ;初始化Basic Timer
eint ;开中断
MainLoop call #key_Event ;检测键盘
cmp.b #0x1,&KEY_Flag ;如果有键值可读取
jne T_EXIT
clr.b R10
Fill_LED cmp.b #0x5,R10 ;LED_Buf的数据移动
jc Fill_5
mov.b R10,R14
and.w #0xFF,R14 ;R14 是LED_Buf的下标指针
mov.w #LED_Buf,R15
mov.b R10,R12
and.w #0xFF,R12
add.w R12,R15
mov.b 0x1(R15),LED_Buf(R14)
inc.b R10
jmp Fill_LED
Fill_5 push.b R14
mov.b #0x05,R14
mov.b &KEY_Val,LED_Buf(R14)
pop.b R14
T_CLR clr.b &KEY_Flag ;清除键值标识
T_EXIT jmp MainLoop
;------------------------------------------------------------------------------
; 初始化Basic Timer
;------------------------------------------------------------------------------
init_BT:
mov.b #0x16,&BTCTL
bis.b #0x80,&IE2
ret
;-------------------------------------------------------------------------------
; Basic timer的中断函数
;-------------------------------------------------------------------------------
BT_Interrupt:
push.w R13 ;保存寄存器
push.w R12 ;
push.w R15 ;
push.w R14 ;
call #led_Display ;LED显示
pop.w R14 ;
pop.w R15 ;寄存器值出栈
pop.w R12
pop.w R13
reti
;------------------------------------------------------------------------------
; 移位操作
;------------------------------------------------------------------------------
Shift_L:
tst.b R14
jeq EXIT_S
SHIFT rla.w R12 ;左移
dec.b R14
jne SHIFT
EXIT_S ret
;------------------------------------------------------------------------------
; 硬件乘法器操作
;------------------------------------------------------------------------------
H_Mul:
push.w SR
dint
nop
mov.w R12,&MPY
mov.w R14,&OP2
mov.w &RESLO,R12 ; 把结果放到R12,R13返回
mov.w &RESHI,R13 ;
reti
;------------------------------------------------------------------------------
; 初始化LED
;------------------------------------------------------------------------------
init_LED:
mov.b #0xFF,&P3DIR ; 设置P3输出模式
clr.b &P3OUT ;
bis.b #0x3,&P4DIR ;
and.b #0xFC,&P4OUT ;
clr.b &LED_CTRL ;
clr.b R14 ;
T4 cmp.b #0x6,R14 ;
jc EXIT_I ;
mov.b R14,R15 ; 初始化LED数据显示缓冲区
and.w #0xFF,R15 ;
clr.b LED_Buf(R15) ;
inc.b R14 ;
jmp T4 ;
EXIT_I ret
;------------------------------------------------------------------------------
; LED显示数据
;------------------------------------------------------------------------------
led_Display:
mov.w #0x1,R15 ;
mov.b &LED_CTRL,R14 ; 设定LED控制位
and.w #0xFF,R14 ;
mov.b LED_Buf(R14),R14 ; 获取LED_Buf的内容
and.w #0xFF,R14 ;
mov.b NUM_LED(R14),&P3OUT ; 设定LED显示段码
bis.b #0x2,&P4OUT ;
bic.b #0x2,&P4OUT ;
mov.b R15,R12 ;
mov.b &LED_CTRL,R14 ;
call #Shift_L ; 改变控制位
inv.b R12 ;
mov.b R12,&P3OUT ;
bis.b #0x1,&P4OUT ;
bic.b #0x1,&P4OUT ;
inc.b &LED_CTRL ;
cmp.b #0x6,&LED_CTRL ; 如果LED_Ctrl >5 ,LED_Ctrl=0
jnc EXIT_D ;
clr.b &LED_CTRL ;
EXIT_D ret
;------------------------------------------------------------------------------
; 初始化keyboard
;------------------------------------------------------------------------------
init_Keyboard:
and.b #0x1,&P1DIR ; 设置P1模式
bis.b #0xE,&P1DIR ;
bis.b #0xE,&P1OUT ;
clr.b &KEY_Flag ; 清零 key_Flag
clr.b &KEY_Pressed ; 清零 key_Pressed
ret
;------------------------------------------------------------------------------
; 获取键值
;------------------------------------------------------------------------------
check_Key:
push.w R10 ; 进栈
push.w R11 ;
push.w R8 ;
push.w R9 ;
mov.b #0x8,R8 ;
clr.b R10 ;
T9 cmp.b #0x3,R10 ; 检测行
jc T5 ;
bis.b #0xE,&P1OUT ;
sub.b R8,&P1OUT ;
clrc ;
rrc.b R8 ; 移位
mov.b &P1IN,R14 ;
and.b #0xF0,R14 ;
cmp.b #0xF0,R14 ;
jc T6 ;
mov.b #0x80,R9 ;
clr.b R11 ;
T8 cmp.b #0x4,R11 ; 检测列
jc T6 ;
mov.b &P1IN,R14 ;
and.b R9,R14 ;
tst.b R14 ;
jne T7 ;
mov.b R10,R12 ;
and.w #0xFF,R12 ;
mov.w #0x4,R14 ;
call #H_Mul ;
mov.b R11,R14 ;
and.w #0xFF,R14 ;
add.w R12,R14 ;
mov.b KEY_MAP(R14),&KEY_Val ; 获取键值
jmp T5 ;
T7 clrc ;
rrc.b R9 ;
inc.b R11 ;
jmp T8 ;
T6 inc.b R10 ;
jmp T9 ;
T5 pop.w R9 ; 出栈
pop.w R8 ;
pop.w R11 ;
pop.w R10 ;
ret
delay:
mov.w #0xFF,R14 ;
T10 tst.w R14 ;
jeq EXIT_Delay ;
add.w #0xFFFF,R14 ;
jmp T10 ;
EXIT_Delay ret ;
;------------------------------------------------------------------------------
; 检测键盘是否有按键按下
;------------------------------------------------------------------------------
key_Event:
push.w R10 ;
and.b #0x1,&P1OUT ;
mov.b &P1IN,R10 ;
tst.b &KEY_Pressed ; 测试是否有键按下
jne T11 ;
mov.b R10,R14 ;
and.b #0xF0,R14 ;
cmp.b #0xF0,R14 ;
jc T11 ;
mov.b #0x1,&KEY_Pressed ;
call #delay ; 延时
call #check_Key ; 获取键值
jmp EXIT_K ;
T11 cmp.b #0x1,&KEY_Pressed ;
jne EXIT_K ;
and.b #0xF0,R10 ;
cmp.b #0xF0,R10 ;
jne EXIT_K ;
clr.b &KEY_Pressed ;
mov.b #0x1,&KEY_Flag ; 置位
EXIT_K pop.w R10 ;
ret ;
;------------------------------------------------------------------------------
; LED段码
;------------------------------------------------------------------------------
NUM_LED
db 0xd7 ;0
db 0x14 ;1
db 0xcd ;2
db 0x5d ;3
db 0x1E ;4
db 0x5b ;5
db 0xdb ;6
db 0x15 ;7
db 0xdf ;8
db 0x5f ;9
db 0x9f ;A
db 0xda ;B
db 0xc3 ;C
db 0xcc ;D
db 0xcf ;E
db 0x8b ;F
db 0x00 ;用于清空LED显示
;------------------------------------------------------------------------------
; 行列键盘的键值对应表
;------------------------------------------------------------------------------
KEY_MAP
db 0x01 ; 1
db 0x02 ; 2
db 0x03 ; 3
db 0x0A ; A
db 0x04 ; 4
db 0x05 ; 5
db 0x06 ; 6
db 0x00 ; 0
db 0x07 ; 7
db 0x08 ; 8
db 0x09 ; 9
db 0x0b ; B
;------------------------------------------------------------------------------
; MSP430x44x 中断向量
;------------------------------------------------------------------------------
ORG 0FFFEh ; MSP430 RESET 向量
DW RESET ;
ORG 0FFE0H ; basic Timer中断
DW BT_Interrupt ;
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -