1、9.2 汇编语言键盘中断模块编程实例(2)键盘编程汇编语言子程序下面给出有关键盘编程的汇编语言子程序。它们是:键盘中断初始化子程序、扫描法读取键值子程序、键值转为定义值子程序。即使不使用中断方式识别按键,三个子程序仍然需要使用。只不过键盘初始化子程序中改为不允许中断进入。扫描法读取键值与键值转为定义值两个子程序在键盘编程中通常需要使用的。KBsub.ASM*-*文件描述:包含3个键盘子程序,分别为: * * (1)键盘初始化子程序(KB_Init) * (2)扫描读取键值子程序(KB_Scan) * (3)键值转为定义值子程序(KB_Def) *-*=以下为子程序源代码=*KB_P EQU P
2、TA ;键盘接在PTA口上KB_D EQU DDRA ;相应的方向寄存器KB_PUE EQU PTAPUE ;相应的上拉电阻允许寄存器*KB_Init:键盘初始化子程序-*功能:初始化键盘中断的引脚,但未开放键盘中断 *入口:无 *出口:无 *堆栈深度:2 *-* KB_Init: PSHA ;保护A LDA #$00 ;复位相应寄存器 STA KB_P LDA #%00001111 ;定义7-4为输入,3-0为输出 STA KB_D LDA #%11110000 ;定义输入引脚有内部上拉电阻 STA KB_PUE BSET 1,INTKBSCR ;屏蔽键盘中断(IMASK=1) LDA #%
3、11110000 ;允许输入引脚的中断可进入 STA INTKBIER BSET 2,INTKBSCR ;清除键盘中断请求(ACKK=1) PULA ;恢复A RTS*KB_Scan:扫描读取键值子程序-*功能:扫描4*4键盘,读取键值-A,无按键,为$FF *入口:无 *出口:A=键值 *堆栈深度:2+2=4 *-* KB_Scan: AIS #-!2 ;开辟临时变量 LDA #%11111110 ;使第一根行线为0(低电平) STA !1,SP LDA #$04 ;将扫描4根行线 STA !2,SPKB_Scan1: LDA KB_P ;取KB_P-A ORA #%00001111 ;KB
4、_P.7-4保留,KB_P.3-0为1 AND $1,SP ;令KB_P.n=0,n=0、1、2、3 STA KB_P NOP NOP LDA KB_P ;看第n行是否有键按下 AND #%11110000 ;KB_P.7-4保留,令低4位=0 CBEQA #$F0,KB_Scan2 ;本行无键按下,转KB_Scan2 LDA KB_P ;本行有键按下 BRA KB_Scan_ExitKB_Scan2: SEC ;C=1 ROL $1,SP ;使下一个行线为0 DBNZ !2,SP,KB_Scan1 ;对行线循环 LDA #$FF ;没有键被按下返回$FFKB_Scan_Exit: AIS #
5、!2 ;释放临时变量 RTS*KB_Def:键值转为定义值子程序-*功能:键值转为键盘定义值 *入口:A=键值 *出口:A=键定义值 *堆栈深度:2+3=5 *-*KB_Def: PSHH ;保护HX PSHX AIS #-!1 ;开辟临时变量 STA !1,SP ;把键值存入(!1,SP) LDHX #KB_Table ;取键盘定义表首地址KB_Def1: LDA ,X CMP #$00 ;与0(定义表结束标志)相比较 BEQ KB_Def3 ;=0,表示即表中无次定义值 CMP $1,SP ;与键值相比较 BNE KB_Def2 ;不等,未找到转KB_Def2 AIX #!1 ;找到 LD
6、A ,X ;取键定义值-A BRA KB_DefR KB_Def2: AIX #!2 ;指向下一个键值 BRA KB_Def1 ;继续判断KB_Def3: LDA #$FF ;无此定义,用FF标志KB_DefR: AIS #!1 ;释放临时变量 PULX ;恢复HX PULH RTS;键盘定义表KB_Table FCB $EE,1,$DE,2,$BE,3,$7E,A FCB $ED,4,$DD,5,$BD,6,$7D,B FCB $EB,7,$DB,8,$BB,9,$7B,C FCB $E7,*,$D7,0,$B7,#,$77,D FCB $009.2.2 键盘中断编程举例下面给出的实例程序的
7、功能是,当按下键盘上任何一个键,产生键盘中断,在键盘中断程序中,通过串行口发送“键值”及“键定义值”。PC机方程序,接收它们,并显示。(1)键盘中断编程汇编主程序实例编号:A03 路径:ASM A03_键盘实验 (Keyboard.asm)*-键盘实验-*文 件 名:Keyboard.asm *硬件连接:PTA.7-4接键盘4根列线,PTA.3-0接键盘4根行线 *程序描述:按下键盘按键,串口发送对应的键值 *目 的:键盘扫描,键盘中断,键值识别,键盘编码 *注 意:如果键盘插在实验板的上排插孔,无须连线,若插在下排 * 插孔,需手工接线 *-嵌入式应用技术基础教程教学实例-*头文件$incl
8、ude GP32ASM.H*两个起始地址RAMstartAddr equ $0040 ;RAM的起始地址FlashStartAddr equ $8000 ;程序开始地址*=*主程序 org FlashStartAddr ;程序起始地址MainInit: ;复位后程序从此开始执行 ;系统初始化 SEI ;关中断 LDHX #$023F TXS JSR GP32Init ;调系统初始化子程序GP32Init JSR SCIInit ;调串行口初始化子程序SCIInit JSR KB_Init ;调键盘初始化子程序 BCLR 1,INTKBSCR ;开放键盘中断(IMASK=0) CLI ;开中断
9、;程序总循环入口,无中断时空操作MainLoop: NOP NOP BRA MainLoop *=以下为子程序存放处=*KB_Int:键盘中断处理程序-*功能:键盘中断程序,把键定义值从串口发送出去 *调用子程序:(1)扫描法读取键值子程序(KB_Scan) * (2)键值转为定义值子程序(KB_Def) *-*KB_Int: SEI ;关总中断 PSHH ;保护H BSET 1,INTKBSCR ;禁止键盘中断 JSR KB_Scan ;扫描键盘,读取键值-A JSR SCISend1 ;发送键值 JSR KB_Def ;转成键定义值-A JSR SCISend1 ;发送键定义值 JSR K
10、B_Init BCLR 1,INTKBSCR ;开放键盘中断(IMASKK=0) PULH ;恢复H CLI ;开总中断 RTI*外部子程序存放处$include GP32init.asm$include SCIInit.asm$include H08SCI.asm$include KBsub.asm*中断向量 ORG $FFE0 ;键盘中断矢量 DW KB_Int ORG $FFFE ;复位矢量 DW MainInit(2)键盘中断编程的PC机方的VB界面与程序图9-4 键盘中断编程的PC机方的VB界面图9-4为针对上述MCU程序的PC机方的VB界面。通过它可以清楚地知道定义值与键值的对应关
11、系,若显示不对,可以修改键值转为定义值子程序中的键值表。实例编号:A03 路径:ASMA03_键盘实验VB_KB程序描述:把接收到的数据显示在接收窗口中-Option Explicit 检查未经声明的变量Dim RecvData() As Byte 接收数据数组Private Sub Form_Load() 清空有关文本框 Txthex.Text = Txtchr.Text = 串行口初始化 Call SCIinit(MSComm1, 1, 9600,N,8,1) 开放串行中断 MSComm1.RThreshold = 1End SubPublic Sub MSComm1_OnComm() 串
12、行接收中断 Dim i As Integer Dim S1 As String, S2 As String MSComm1.RThreshold = 0 关闭串行中断 RecvData = MSComm1.Input S1 = Hex(RecvData(0) S2 = Chr(RecvData(1) Txthex.Text = S2 Txtchr.Text = S1 MSComm1.RThreshold = 1 开放串行中断End SubPrivate Sub CmdCLR_Click() 单击清空按钮 Txthex.Text = Txtchr.Text = End SubPrivate Su
13、b CmdEXIT_Click() 单击退出按钮 If MSComm1.PortOpen = True Then MSComm1.PortOpen = False EndEnd SubPrivate Sub CmdEXIT_Click() 单击退出按钮 If MSComm1.PortOpen = True Then MSComm1.PortOpen = False EndEnd Sub9.3 08C语言键盘中断模块编程实例本节给出与汇编程序相对应的08C语言程序。PC机部分的VB程序相同。9.3.1 按键识别与键盘定义函数H08KB.C/*-*文件描述:本文件包含了H08C键盘中断子函数,分别
14、为: * *(1)KB_Init:键盘初始化函数 * void KB_Init(void) *(2)KB_Scan:扫描读取键值函数 * unsigned char KB_Scan(void) *(3)KB_Def:键值转为定义值函数 * unsigned char KB_Def(unsigned char KB_valve) *-*/*以下为子程序源代码*/*头文件*/#include GP32C.H#include KB.h/*KB_Init:键盘初始化函数-*功 能:初始化键盘中断的引脚,但未开放键盘中断 *参 数:无 *返 回:无 *-*/ void KB_Init(void) KB_
15、P=0x00; /复位KB_P KB_D=0b00001111; /定定义7-4为输入,3-0为输出 KB_PUE=0b11110000; /定义输入引脚有内部上拉电阻 INTKBSCR|= (1IntBit);/屏蔽键盘中断(IMASKk=1) INTKBIER=0b11110000; /允许输入引脚的中断可进入 INTKBSCR|= (1*p ,若无按键, * *p为0xff *参 数:无 *返 回:扫描到的键值 *-*/ unsigned char KB_Scan(void) unsigned char line,i,tmp; line=0b11111110; /使第一根行线为0(低电平
16、) for(i=1;itmp tmp|=0b00001111; /KB_P.7-4保留,KB_P.3-0为1 KB_P=tmp&line; /令KB_P.n=0,n=0、1、2、3 asm(NOP); /等待,消除按键抖动 asm(NOP); tmp=KB_P; tmp&=0b11110000; /看第n行是否有键按下 if(tmp!=0xf0) /本行有键按下 tmp=KB_P; break; else /本行无键按下,扫描下一行 line=(line1)|0x01; if(i=5) tmp=0xff; return(tmp); /*KB_Def:键值转为定义值函数-*功 能:键值转为定义值
17、 *参 数:键值 *返 回:键定义值 *-*/键盘定义表const unsigned char KB_Table= 0xEE,1,0xDE,2,0xBE,3,0x7E,A, 0xED,4,0xDD,5,0xBD,6,0x7D,B, 0xEB,7,0xDB,8,0xBB,9,0x7B,C, 0xE7,*,0xD7,0,0xB7,#,0x77,D, 0x00;unsigned char KB_Def(unsigned char KB_valve) unsigned char KeyPress; unsigned char i; unsigned char j; i=0; while(1) j=KB
18、_Tablei; /与0(定义表结束标志)相比较 if (j=0) /=0,即表中无次定义值 KeyPress=0xff; break; /返回0xff else /与键值相比较 if (j=KB_valve) /找到 KeyPress=KB_Tablei+1;break; /取键定义值 else i+=2; /指向下一个键值,继续判断 ; return KeyPress; 9.3.2 键盘中断编程08C语言举例(1)键盘中断编程实例的08C主函数实例编号:C03 路径:C C03_C03_键盘实验 /*-键盘实验-*工 程 名:Keyboard.prj *硬件连接:PTA.7-4接键盘4根列
19、线,PTA.3-0接键盘4根行线 *程序描述:按下键盘按键,串口发送对应的键值 *目 的:键盘扫描,键盘中断,键值识别,键盘编码 *注 意:如果键盘插在实验板上排插孔,无须连线,若插在下 * 排插孔,需手工接线 *-嵌入式应用技术基础教程教学实例-*/*头文件*/#include GP32C.H#include KB.h /键盘中断头文件/*主程序*/void main() asm(SEI); /关总中断 KB_Init(); INTKBSCR&= (1IntBit); /打开键盘中断(IMASKk=1) asm(CLI); /开总中断 /无中断时空操作 while(1); (2)键盘中断编程
20、实例的08C中断矢量表文件vectors08.c/*-*文件名:vectors08.c *功 能:用于定义中断矢量表 *-*/ /*头文件*/#include GP32C.H #include KB.h #include SCI.h /*键盘中断处理函数-*/#pragma interrupt_handler isrKBIvoid isrKBI(void) unsigned char KB_valve; asm(SEI); /关总中断 INTKBSCR|= (1IntBit); /屏蔽键盘中断(IMASKK=1) KB_valve=KB_Scan(); /扫描键值 SCISend1(KB_va
21、lve); KB_valve=KB_Def(KB_valve); /键值转化为定义值 SCISend1(KB_valve); KB_Init(); /重新初始化键盘 INTKBSCR&= (1IntBit); /打开键盘中断(IMASKK=0) asm(CLI); /开总中断/未定义的中断处理函数,本函数不能删除#pragma interrupt_handler isrDummy void isrDummy(void) /中断矢量表,需定义中断函数,可修改下表中的相应项目#pragma abs_address:0xffdc /中断向量表起始地址void (* const _vectab)(vo
22、id) = isrDummy,/Timebase isrDummy,/ADC isrKBI, /KBI isrDummy,/SCI TC/TE isrDummy, /SCI RF/IDLE isrDummy,/SCI PE/FE/NF/OR isrDummy,/SPI TE isrDummy,/SPI MOD/OVR/RF isrDummy,/TIM2 OVR isrDummy,/TIM2 channel 1 isrDummy,/TIM2 channel 0 isrDummy,/TIM1 OVR isrDummy,/TIM1 channel 1 isrDummy,/TIM1 channel 0 isrDummy,/CGM isrDummy,/IRQ isrDummy/SWI /RESET也是中断,定义在 crt08.o中 ;#pragma end_abs_address