微机控制技术·第13章·常用软件设计 第十三章常用软件设计 131与软件结构相关的散转、查表程序设计 查表程序设计 单片机应用系统中,査表程序是一种常用程序,它广泛使用于LED显示器控制,打印机打印以及数 据补偿、计算、转换等功能程序中。 查表,就是根据变量x在表格中査找y,使y=f(x)。 x有各种结构,如有时ⅹ可取小于n(n为定值)的自然数子集:有时,ⅹ取值范围较大,并且不会取 到该范围中的所有值,即对某些ⅹ,f(x)无定义,例如x为不定长的字符串或x为某些ASCI字符等。 y也有各种结构,如有时y可取定字长的数,但不是所有该字长的数都有对应的x;有时y可取小于 m(m为定值)的自然数子集 对于表格本身,也有许多不同的结构。以存放顺序分,有有序表与无序表,以存放地点分,有的表 格存放在程序存储器中(用MOⅤC指令访问),有的表格存放在数据存储器中(用MOX指令访问)。表 格的存放内容也各有不同,有的只存放y值,有的只存放x值;有的表格中还包括含有几个子表;表格中 的每一项的长度也各有不同,有的是定长,有的为不定长。其它还有多维表格等情况。下面介绍几种常见 类型查表程序和这些表格的构成方法。 (一)x可取小于等于n的自然数的全体,y为定字长 由于x取值为自然数0,1,2,3,…,n有序等差排列,而y又为定字长,故可以简化表格,在表中 只存放y的值 例1设有一个巡回检测报警装置,需对16路输入值进行比较,当每一路输入值超过该路的报警值时, 实现报警。下面根据这一要求,编制一个查表程序。 ⅹ为路数,查表时x按0,1,2,…,15(n=15)取数,yi为报警值,二字节数,依xi顺序列成表格放 在TABl中。进入查表程序前,路数xi放在R2中,查表后的最大值放在R3、R4中 查表程序如下 MOV A, R2 路数ⅹ→R2 ADD A, R2 ;R2·2→A 保存路数ⅹ值 ADDA,#AB(rel):加上表首偏移量 MOVC A,@A+PC;查第一字节 XCH A, R3 第一字节→R3 ADDA,#TAB(rel)+1:加上表首偏移量 MOVC A,@A+PC 查第二字节 R4, A 第二字节入R4 TAB:DW05F0H,OE89H,0A695H,1BAAH:报警值表 D9BH,7F93H,0378H,26D7H DW2710H,9B3FH,1A66H,22B3H DW 1174H, 16EFH, 3aB4H9, OCAOH 上述査表程序使用 MOVC A,@A+PC,因此,表格偏移不得超过255个字节。当表 格偏移大于255个字节时,使用 MOVCA,@A十DPIR查表指令 例2在一个温度测量装置中,测量的电压与温度为非线性关系,需对它进行线性化处理。如测得值
微机控制技术·第 13 章·常用软件设计 1 第十三章 常用软件设计 13.1 与软件结构相关的散转、查表程序设计 一、查表程序设计 单片机应用系统中,查表程序是一种常用程序,它广泛使用于 LED 显示器控制,打印机打印以及数 据补偿、计算、转换等功能程序中。 查表,就是根据变量 x 在表格中查找 y,使 y=f(x)。 x 有各种结构,如有时 x 可取小于 n(n 为定值)的自然数子集;有时,x 取值范围较大,并且不会取 到该范围中的所有值,即对某些 x,f(x)无定义,例如 x 为不定长的字符串或 x 为某些 ASCII 字符等。 y 也有各种结构,如有时 y 可取定字长的数,但不是所有该字长的数都有对应的 x;有时 y 可取小于 m(m 为定值)的自然数子集。 对于表格本身,也有许多不同的结构。以存放顺序分,有有序表与无序表,以存放地点 分,有的表 格存放在程序存储器中(用 MOVC 指令访问),有的表格存放在数据存储器中(用 MOVX 指令访问)。表 格的存放内容也各有不同,有的只存放 y 值,有的只存放 x 值;有的表格中还包括含有几个子表;表格中 的每一项的长度也各有不同,有的是定长,有的为不定长。其它还有多维表格等情况。下面介绍几种常见 类型查表程序和这些表格的构成方法。 (一)x 可取小于等于 n 的自然数的全体,y 为定字长。 由于 xi 取值为自然数 0,l,2,3,…,n 有序等差排列,而 yi 又为定字长,故可以简化表格,在表中 只存放 yi 的值。 例 1 设有一个巡回检测报警装置,需对 16 路输入值进行比较,当每一路输入值超过该路的报警值时, 实现报警。下面根据这一要求,编制一个查表程序。 x 为路数,查表时 xi 按 0,1,2,…,15(n=15)取数,yi 为报警值,二字节数,依 xi 顺序列成表格放 在 TABl 中。进入查表程序前,路数 xi 放在 R2 中,查表后的最大值放在 R3、R4 中。 查表程序如下: TB1: MOV A,R2 ;路数 xi→R2 ADD A,R2 ;R2·2→A MOV R3,A ;保存路数 xi 值 ADD A,#TAB(rel) ;加上表首偏移量 MOVC A,@A+PC ;查第一字节 XCH A,R3 ;第一字节→R3 ADD A,#TAB(rel)+1 ;加上表首偏移量 MOVC A,@A+PC ;查第二字节 MOV R4,A ;第二字节入 R4 RET TAB: DW 05F0H,0E89H,0A695H,1BAAH;报警值表 DW 0D9BH,7F93H,0378H,26D7H DW 2710H,9B3FH,1A66H,22B3H DW 1174H,16EFH,3aB4H9,0CA0H 上述查表程序使用 MOVC A,@A+PC,因此,表格偏移不得超过 255 个字节。当表 格偏移大于 255 个字节时,使用 MOVC A,@A 十 DPTR 查表指令。 例 2 在一个温度测量装置中,测量的电压与温度为非线性关系,需对它进行线性化处理。如测得值
微机控制技术·第13章·常用软件设计 为10位二进制数(占两个字节),采用表格方法实现线性化处理时,可将所测出不同温度下的输入值(共 有1024个数)数据构成一个表,表中存放温度值为y,电压值为ⅹ(为了减少测量数据,也可用插值法求 出其它数据)。设测量输入值放在R2、R3中,采用以下程序可以把它转换成线性温度值,然后再放回到 R2、R3中。表TAB2可放在64k程序存储器中任何地方 LTB2: MOV DPTR, #TAB2 MOV A, R3 CLR C RLC A XCH A, R2 RLC A XCH R2, A MOV DPL, A MOV A, DPH ADDC A, R2 DPH, A CLR A MOVc A,@A+DPTR MOV R2, A CLR A INC DPTR MOVc A, @A+DPTR MOV R3, A RET TAB2:DW…:温度数值麦 散转程序设计 散转程序是一种并行分支程序。它是根据某种输入或运算结果,分别转向各个处理程序。在MCS-5 单片机中,散转指令为JMP@A+DPIR。它按照程序运行时决定的地址执行间接转移指令。该指令把累 加器的8位无符号内容与16位数据指针的内容相加后装入程序计数器,实现程序的转移。A的内容不同 散转的入口地址不同。 下面介绍几种不同的散转程序 (一)使用转移指令表的散转程序 在不少场合下,需要根据某一单元的内容是0,1,2,…,n时分别转向分支处理程序0,1 n。可直接使用散转指令JMP@A+DPIR。由于A可容纳的字节数只有256个,在DPIR为首地址的256 个程序存储单元一般不可能容纳n个分支处理程序。因此,可只将这个区域中作为n个分支处理程序的转 移指令表。采用AJMP转移指令需占用二个字节,而采用LJMP转移指令需占空间为三个字节。 例5根据R2的内容,转向各个处理程序 (R2)=0,转向PRG0 (R2)=1,转向PRGl (R2)=n,转向PRGn 程序清单 J MPI MOV DPTR,#BJ1;转移指令表(转移指令入口地址) MOV A, R2 给每个转移指令空出二个字节车间
微机控制技术·第 13 章·常用软件设计 2 为 10 位二进制数(占两个字节),采用表格方法实现线性化处理时,可将所测出不同温度下的输入值(共 有 1024 个数)数据构成一个表,表中存放温度值为 yi,电压值为 x(为了减少测量数据,也可用插值法求 出其它数据)。设测量输入值放在 R2、R3 中,采用以下程序可以把它转换成线性温度值,然后再放回到 R2、R3 中。表 TAB2 可放在 64k 程序存储器中任何地方。 LTB2: MOV DPTR,#TAB2 MOV A,R3 CLR C RLC A MOV R3,A XCH A,R2 RLC A XCH R2,A ADD A,DPL MOV DPL,A MOV A,DPH ADDC A,R2 MOV DPH,A CLR A MOVC A,@A+DPTR MOV R2,A CLR A INC DPTR MOVC A,@A+DPTR MOV R3,A RET TAB2: DW … ;温度数值麦 二、散转程序设计 散转程序是一种并行分支程序。它是根据某种输入或运算结果,分别转向各个处理程序。在 MCS-51 单片机中,散转指令为 JMP @A+DPTR。它按照程序运行时决定的地址执行间接转移指令。该指令把累 加器的 8 位无符号内容与 16 位数据指针的内容相加后装入程序计数器,实现程序的转移。A 的内容不同, 散转的入口地址不同。 下面介绍几种不同的散转程序 (一)使用转移指令表的散转程序 在不少场合下,需要根据某一单元的内容是 0,1,2,…,n 时分别转向分支处理程序 0,1,2,…, n。可直接使用散转指令 JMP @A+DPTR。由于 A 可容纳的字节数只有 256 个,在 DPTR 为首地址的 256 个程序存储单元一般不可能容纳 n 个分支处理程序。因此,可只将这个区域中作为 n 个分支处理程序的转 移指令表。采用 AJMP 转移指令需占用二个字节,而采用 LJMP 转移指令需占空间为三个字节。 例 5 根据 R2 的内容,转向各个处理程序 (R2)=0,转向 PRG0 (R2)=1,转向 PRGl …… (R2)=n,转向 PRGn 程序清单 JMPl: MOV DPTR,#TBJ1 ;转移指令表(转移指令入口地址) MOV A,R2 ;给每个转移指令空出二个字节车间 ADD A,R2
微机控制技术·第13章·常用软件设计 NADD INC DPH ;R2·2>256时表空间增加一面 NADD JMP @A+DPTR TBJI: AJMP PRGO AJMP PRGI AJMP PRG2 AJMP PRGn PRGO PRGI PRG2 PRGn 这个散转程序由于在分支转移指令表中使用AJMP指令,其寻址范围为2k字节,如果n个散转分支 程序长度超过k字节时,可改用64k寻址的LJMP指令。这时,上述程序中应给每个转移指令空出三个 字节空间 对于散转分支程序超过256个时,即n>255,一个字节存放不下,这时,可用两个字节,并利用对 DPIR进行加法运算的方法,直接修改DPIR:然后再用JMP@A+DPTR实现散转。 子程序调用时的参数传递方法 在MCS-51应用程序中,完成子程序调用的指令为 ACALL和 LCALL,子程序返回指令为RET 在功能上子程序与中断服务程序有相似之处。但中断请求是随机的,转向中断处理的时刻与主程序无 接关系,故一定要有现场保护与现场恢复,而对于子程序来说,它的调用安排是由主程序设定,故现场 不一定要加以保护,可按实际情况灵活处理 子程序调用时有个参数传递问题,即在子程序调用时,主程序应先把有关参数放到某些约定的位置, 子程序在运行时,可以从约定位置得到有关参数,同样,子程序起运行结束前,也应把运算结果送到约定 位置。在返回主程序后,主程序从约定的位置上得到所需要的结果。 子程序调用时,可采用以下几种常用的参数传递方法。 1.用工作寄存器或累加器传递参数 这种方法是将输入参数或结果参数放在工作寄存器或累加器中。使用这种方法程序简单,运算速度也 高。是最常使用的参数传递方法,其缺点是传递参数不能太多 2.用指针寄存器来传递参数 由于数据一般存放在存储器中,故可用指针来指示数据的位置,这样可大大节省传递数据的工作量, 并可实现变长度运算。如果参数在内部RAM中,可用R0、R1作指针;参数在外部RAM或程序存储器中, 可用DPIR作指针。可变长度运算时,可用一个寄存器来指出数据长度,也可在数据中设置结東标记
微机控制技术·第 13 章·常用软件设计 3 JNC NADD INC DPH ; R2·2>256 时表空间增加一面 NADD: JMP @A+DPTR TBJ1: AJMP PRG0 AJMP PRGl AJMP PRG2 …… AJMP PRGn PRG0: …… …… PRG1: …… …… PRG2: …… …… …… PRGn: …… …… 这个散转程序由于在分支转移指令表中使用 AJMP 指令,其寻址范围为 2k 字节,如果 n 个散转分支 程序长度超过 2k 字节时,可改用 64k 寻址的 LJMP 指令。这时,上述程序中应给每个转移指令空出三个 字节空间。 对于散转分支程序超过 256 个时,即 n>255,一个字节存放不下,这时,可用两个字节,并利用对 DPTR 进行加法运算的方法,直接修改 DPTR;然后再用 JMP @A+DPTR 实现散转。 三、子程序调用时的参数传递方法 在 MCS-51 应用程序中,完成子程序调用的指令为 ACALL 和 LCALL,子程序返回指令为 RET。 在功能上子程序与中断服务程序有相似之处。但中断请求是随机的,转向中断处理的时刻与主程序无 直接关系,故一定要有现场保护与现场恢复,而对于子程序来说,它的调用安排是由主程序设定,故现场 不一定要加以保护,可按实际情况灵活处理。 子程序调用时有个参数传递问题,即在子程序调用时,主程序应先把有关参数放到某些约定的位置, 子程序在运行时,可以从约定位置得到有关参数,同样,子程序起运行结束前,也应把运算结果送到约定 位置。在返回主程序后,主程序从约定的位置上得到所需要的结果。 子程序调用时,可采用以下几种常用的参数传递方法。 1.用工作寄存器或累加器传递参数 这种方法是将输入参数或结果参数放在工作寄存器或累加器中。使用这种方法程序简单,运算速度也 高。是最常使用的参数传递方法,其缺点是传递参数不能太多。 2.用指针寄存器来传递参数 由于数据一般存放在存储器中,故可用指针来指示数据的位置,这样可大大节省传递数据的工作量, 并可实现变长度运算。如果参数在内部 RAM 中,可用 R0、R1 作指针;参数在外部 RAM 或程序存储器中, 可用 DPTR 作指针。可变长度运算时,可用一个寄存器来指出数据长度,也可在数据中设置结束标记