单片机原理实验
ORL P2,#0FFH;关闭矩阵键盘 ORL P1,#0C0H
MOV A,P1 ;读独立按键
ANL A,#0C0H ;接独立键盘的位保留 XRL A,#0C0H ;求反转正逻辑 ADD A,R7
MOV R7,A
???? ;键状态变化判断、延时去抖、键前沿提取等 RET
3. 模块化程序设计方法――系统状态及其转移分析方法
单片机应用系统和程序构架与系统所要实现的功能有关,模块化程序设计方法仍是常用的方法。程序员首先要分析系统的功能,将系统分解为几个不同的工作状态,并用代码表示系统的工作状态,保存状态代码的内部RAM单元称为状态字(不妨记态字为STA),处在不同工作状态时,系统执行不同的程序模块,实现不同的功能;其次要分析实现这些功能的控制量有哪些,包括按键、开关量(或逻辑信号)和模拟量(或模拟量)等,找出系统的工作状态发生变化的条件,即控制量满足什么条件时工作状态将发生什么变化,得出系统的状态转移表。在此基础上,利用“JMP @A+DPTR”指令,根据工作状态字STA的不同取值进行间接长转移(或称为散转),从而实现系统工作状态的转移,完成工作任务的调度。下面举简例说明之。
在实验板上设计一个系统,实现以下功能:①上电时4位数码管显示“8952”1秒,指示灯全亮。②紧接着显示“学号”(低4位),同时LD1灯亮表示当前显示内容为“学号”,此时按键K0~11无效,SW1和SW2键有效。③若按SW2键一次,LD2亮表示此时可以利用数码显示和按键K0~9进行赋值,K0~9键代表“0~9”数值键,每按1次数值键后,原4位显示数值在显示器上左移1位,新输入的数值从右边进入,输入数值的位数不限,但从显示器左边移出的数值不保留;若再按“SW2”键一次,显示器上显示的数值保存,重新显示“学号”,LD1亮。④在显示“学号”,LD1亮的情况下,若按下SW1键一次,系统显示最后输入的4位数值供查询,LD3亮表示查询,此时不能对显示数值进行修改,5秒后自动重新显示“学号”,LD1亮;若在自动重新显示“学号”之前,按住SW1键不抬起,将暂停5秒计时,按键松开后恢复计时,从而推迟重新显示“学号”。
对上述的系统功能进行分析,“功能①”规定了系统上电后1秒内的行为,这此功能可归为上电复位初始化内容;分析其它功能,可将系统分解为3个工作状态:第1种状态为待机状态,(STA)=0,显示“学号”、LD1亮;第2种状态为赋值状态,(STA)=1,显示输入的值、LD2亮;第3种状态为查询状态,显示最后输入的4位数值、LD3亮。在待机状态下,系统只响应SW1和SW2的键前沿,若按SW2键1次则系统转入赋值状态,若按SW1键1次则系统转入查询状态;在赋值状态下,系统响应K0~9和SW2的键前沿,若按K0~9中的任一键则进行赋值,若按SW2键则系统转回待机状态;在查询状态下,系统只响应SW1的键状态,若按SW1键不松开则暂停5秒计时,推迟返回待机状态。由上面的分析可得到系统的状态转移表,如表4.1所示。
20
单片机原理实验 表4.1:状态转移表举例
状态 显示及执行任务 可响应的控制量及其作用 状态转移及其条件 有SW1键则转入查询状态 有SW2键则转入赋值状态 待机状态 显示“学号”(低SW1和SW2键前沿,用于(STA)=0 4位)、LD1亮。 控制状态转移。 赋值状态 显示当前的输入(STA)=1 值、LD2亮。 K0~9和SW2的键前沿,分有SW2键则返回待机状态 别用于赋值和状态转移。 计时到则返回待机状态 查询状态 最后输入的4位SW1的键状态,用于控制5(STA)=2 数值、LD3亮。 秒计时器工作。 根据状态转移表,可以容易得到系统程序流程图,如图4.3所示,部分主程序清单如下:
;====变量及常数定义段==== INCLUDE \ ;=============== ORG 0000H LJMP MAIN
ORG 000BH
;转T0中断服务子程序 ;添加初始化模块
LJMP T0SER ORG 0030H
MAIN: INCLUDE \MLOOP: JNB TF0,$ CLR TF0
MOV TH0,#0F0H MOV TL0,#60H LCALL RDKEY LCALL DISP MOV A,STA ANL A,#03H RL A
MOV DPTR,#MTAB JMP @A+DPTR
;4mS到? ;清定时标志 ;4mS定时重设
;调用读键状态及去抖处理 ;调用数码管动态显示
;根据状态值散转相应模块
;添加变量等定义模块
复位入口 初始化 4mS到? Y 清定时标志,4mS定时重设;读键状态及去抖处理;数码管动态显示 N ??(如其它控制量读取等) 根据状态值散转相应模块 STA=0 待机模块 STA=1 STA=2 赋值模块 查询模块 MTAB: AJMP WORK0 ;转移到待机模块 AJMP WORK1 ;转移到赋值模块
AJMP WORK2 AJMP WORK0
;转移到查询模块 ;冗余
;====待机模块==== WORK0: ???? AJMP MLOOP
21
图4.3:系统程序流图 单片机原理实验
;====赋值模块==== WORK1: ???? AJMP MLOOP ;====查询模块==== WORK2: ????
AJMP MLOOP
;====其它非通用子程序====
????;详见赋值模块细化的DSBUPT ;====T0中断服务子程序==== T0SER: RETI
;====通用子程序段====
INCLUDE \添加读键状态及去抖处理子程序 INCLUDE \添加数码管动态扫描显示子程序
END
由图4.3及上述主程序清单可见,一般情况下,采用模块化方法设计程序时,程序有以下三个特点。其一是,每个模块只有唯一的入口和唯一的出口。其二是执行各模块只有2种方法,或用调用指令调用子程序模块,完成特定任务后返回调用处;或根据状态值,用间接长转移指令散转至相应工作模块,各工作模块执行后用无条件转移指令回到程序主循环的起点MLOOP处。其三是不能使用无条件转移指令由一个工作模块直接转入另一模块;工作模块间的转移是只能通过修改状态值,在下一次主循环中自动转入所需模块,详见以下对“赋值模块”的细化和相应程序清单。
在本系统中,有2个数据是必须保存的,其一是“学号”的低4位,其二是键盘输入的4位数值,这2个数据都是双字节的压缩DCB码。为此,在内部RAM中开辟4个字节单元用于存储这2个数据,其中
在本系统中,由于系统比“实验三”复杂,需要定义更多的变量,如键状态字2字节KEY1和KEY2、键前沿字2字节EKEY1和EKEY2、14个键状态位、14个键前沿位等,因此可将变量及常数的定义独立为1个模块“VARDFN.ASM”。
上面,我们从系统的角度分析了系统的状态,得到了状态转移表和模块化的主程序流图,也对系统的所有变量、数据格式进行定义,在此基础上可进一步细化各工作模块。在3个工作模块中“赋值模块”相对最复杂,下面此模块为例来讨论模块的细化问题。由表4.1的状态转移表可得“赋值模块”的流程图,如图4.4所示,程序清单如下。
WORK1: MOV R0,#SNUM0
;数据2送显缓
22
ACALL DSBUDT
单片机原理实验 MOV DSB4,#02H ;LD2亮 ;下次主循环返回WORK0模块 ;查询\键 ;查询\键 Y ;查询\键 无SW2键? Y (A)=0 (STA)=0 N JNB ESW2,WK11 MOV STA,#00H SJMP WK13 WK11: CLR A JB EK0,WK12 INC A JB EK1,WK12 ???? INC A 数据2送显缓、LD2点亮 有K0键? N (A)=(A)+1 JNB EK9,WK13 WK12: XCH A,SNUM1 ;键值从数据2的右边移入 SWAP A MOV R7,A ANL A,#0F0H ORL SNUM1,A MOV A,R7 ANL A,#0FH XCH A,SNUM0 ANL A,#0FH SWAP A ORL SNUM0,A WK13: AJMP MLOOP ;====将双字节压缩BCD码(R0)(R0+1)送显缓==== DSBUDT: MOV A,@R0 ANL A,#0FH
Y 有K1键? N ???? (A)=(A)+1 有K9键? Y N 键值(A)从数据2的右边移入 MOV DSB2,A MOV A,@R0 ANL A,#0F0H SWAP A
MOV DSB3,A INC R0 MOV A,@R0 ANL A,#0FH MOV DSB0,A MOV A,@R0 ANL A,#0F0H SWAP A MOV DSB1,A
23
回到主循环的起点MLOOP处 图4.4:赋值模块流图 单片机原理实验
RET
从状态表4.1中可看出,在3个工作状态中都规定了数码显示器的显示信息,只要将等显示的压缩BCD码送给显示缓冲单元DSB3~0,即可实现显示内容更新,因此3个工作状态都有显示内容更新的操作,这些操作都是相似的,可由子程序DSBUPT(DISPLAY BUFFER UPDATE)完成,该子程序将(R0)为首地址的双字节压缩BCD码送往显示缓冲单元。
四、 实验内容
1. 矩阵键盘和独立按键读键状态及去抖处理程序设计
参照图3.6和图4.2,将“实验原理2”的“读矩阵、独立按键子程序(延时去抖)”中用“??”表示的扫描第1、2行按键等和键状态判断、延时去抖、键前沿提取等部分程序行写完整。
建立工作文件夹“E:\\学号\\实验四”,启动“WAVE 3.2”软件,点击“新建文件”快捷按钮,在打开的文件窗口中编辑读矩阵、独立按键子程序(延时去抖),编辑完成后,在工作文件夹中,以文件名“RDKEY.ASM”保存文件。 2. 程序移植
将“实验三”中建立的5位LED数码管动态显示子程序DISP.ASM复制到当前工作文件夹。
点击“新建文件”快捷按钮,在打开的文件窗口中编辑变量及常数定义子程序,编辑时可将实验三主程序MAIN.ASM的变量定义段的有关内容复制粘贴到当前编辑窗口中,删去与本项目无关的行,添加本项目新增的各变量的定义,并对各变量在内部RAM中的分配作统一规划。编辑完成后,在工作文件夹中,以文件名“VARDFN.ASM”保存文件。
将“实验三”中建立的初始化子程序INITIAL.ASM复制到当前工作文件夹,用“打开文件”快捷按钮打开该文件,修改初始化模块。堆栈设置、内部RAM清0不变,增加变量
在做程序移植时,移植过来的程序行若与本项目无关务必要删除干净,尤其是变量及常数定义子程序,该程序均由伪指令构成,没有删除干净可能不会影响程序的编译与运行,但会大大降低程序的可读性。
3. 系统程序设计与调试
将待机模块和查询模块细化,画出各自的流程图,写出程序清单;将赋值模块流程图中“????”部分画完整,并写出相应的程序行。
点击“新建文件”快捷按钮,在打开的文件窗口中编辑系统程序,编辑完成后,在工作文件夹中,以文件名“MAIN.ASM”保存文件。
在工作文件夹中,以“PROJECT”文件名创建工程项目,将MAIN.ASM添加到模块文件中,编译项目直至通过。将编译通过的目标程序下载到实验板中,取下下载器,通电试运行。若目标程序运行不能达到预期效果,用实验一、所述方法进行模拟仿真,查找算法、程序错误,再编译、下载、运行目标程序直至达到预期效果,完成调试。
24