英锐恩单片机论坛,Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流

标题: PIC单片机运算子程序(2) [打印本页]

作者: winnie    时间: 2009-5-5 17:32
标题: PIC单片机运算子程序(2)
4.2  3字节浮点数转换为定点整数
子程序的转换结果将采用补码表示。其转换数值范围:-32768~32767,入口条件和出口条件如下:
入口条件:ACCBHI、ACCBLO、EXPB
出口条件:ACCBHI、ACCBLO
    以下为子程序的清单。由于程序所需调用的子程序和所需通用寄存器单元地址和定点数转换为浮点数子程序相同,在此省略。使用时,将前面介绍的子程序拷入此处即可。
FtoD    CLRF         SIGN            ;清结果符号寄存器
    MOVF         ACCBHI,0
    BTFSS         ACCBHI,7    ;被转换数是否为负?
    GOTO         D1
    BSF             SIGN,7        ;是,SIGN.7置1
    CALL         NEG_B        ;被转换数取补
D1    BTFSS         EXPB,7        ;被转换数为正,再判阶码为负否?
    GOTO         D2
    CLRF         ACCBHI        ;为负,被转换数小于1,无法用定点数表示
    CLRF         ACCBLO
    RETLW         0
D2    MOVLW         .16            ;被转换数阶码减16(十进制数)
    SUBWF         EXPB,0
    BTFSS         STATUS,C    ;阶码小于16?
    GOTO         D3
        MOVLW         0XFF            ;阶码大于等于16,置ACCB为最大,返回
    MOVWF         ACCBHI
    MOVWF         ACCBLO
    RETLW         01
D3    CALL         FTOW3        ;调用子程序将浮点数转换为定点数
    BTFSC         SIGN,7        ;定点数为负?
    CALL         NEG_B        ;是,取补
    RETLW         0            ;否,返回
;****************************************
FTOW3    MOVLW         .15            ;EXPB=15(十进制数)?
    SUBWF         EXPB,0
    BTFSC         STATUS,Z
    RETLW         0            ;是,返回
    BCF             STATUS,C    ;否,ACCB继续右移,EXPB加1
    RRF             ACCBHI
    RRF             ACCBLO
    INCF         EXPB
    GOTO         FTOW3        ;重新判断EXPB=15?
【校验举例1】 19531(十进制)
化为十六进制数:4C4B0FH
结果:4C4BH
【校验举例2】 2622(十进制)
化为十六进制数:51F00CH
结果:0A3EH
【例程】
MAIN        MOVLW        0X4B        ;被转换数4C4BH送ACCB
    MOVWF        ACCBLO
    MOVLW        0X4C
    MOVWF        ACCBHI
    MOVLW        0X0F
    MOVWF        EXPB
        CALL        FtoD            ;调用定点数至浮点数转换子程序
    END
5  码制转换程序设计
5.1   双字节定点数至5位BCD码转换程序
    入口条件:ACCBHI、ACCBLO
    出口条件:ACCCHI低半字节、ACCCLO、ACCDHI
以下为双字节定点数至5位BCD码转换程序清单。
    LIST            p=16f877
    INCLUDE        p16f877.inc
    ACCBLO         EQU     23        ;存放被转换的双字节整数低8位
    ACCBHI         EQU     24        ;存放被转换的双字节整数高8位
    ACCCLO         EQU     26        ;存放5位BCD码
    ACCCHI         EQU     27
    ACCDLO         EQU     28
    ACCDHI         EQU     29
    TEMP         EQU     2A        ;临时寄存器
    SIGN         EQU     2B        ;被转换数符号寄存器
    ORG            0X0000
START    GOTO        MAIN
    ORG            0X0100
;**********双字节数至BCD码子程序************
BtoBCD    CLRF        SIGN            ;初始化符号寄存器
    BTFSS        ACCBHI,7    ;被转换数为负?
    GOTO        LOOP1        ;否,转BtoBCD
    BSF            SIGN,7        ;是,存符号
    CALL        NEG_B        ;ACCB取补
LOOP1    BCF             STATUS,C    ;清进位位
    MOVLW         .16            ;移位计数器赋初值
    MOVWF         COUNT
    CLRF         ACCCHI        ;初始化出口寄存器
    CLRF         ACCCLO
    CLRF         ACCDHI
LOOP16    RLF             ACCBLO        ;ACCB左移一位至出口寄存器
    RLF             ACCBHI
    RLF             ACCDHI
    RLF             ACCCLO
    RLF             ACCCHI
    DECFSZ         COUNT         ;移位计数器=0?
    GOTO         ADJDEC        ;否,转ADJDEC
    RETLW         0            ;是,返回
ADJDEC    MOVLW         ACCDHI        ;指针指向ACCDHI
    MOVWF         FSR
    CALL         ADJBCD        ;调用BCD码校正子程序
    MOVLW         ACCCLO        ;指针指向ACCCLO
    MOVWF         FSR
    CALL         ADJBCD        ;调用BCD码校正子程序   
    MOVLW         ACCCHI        ;指针指向ACCCHI
    MOVWF         FSR
    CALL         ADJBCD        ;调用BCD码校正子程序
    GOTO         LOOP16        ;ACCB重新左移
;************* BCD码校正子程序**************
ADJBCD     MOVLW         00X03        ;LSD+3>7?
    ADDWF         INDF,0
    MOVWF         TEMP
    BTFSC         TEMP,3
    MOVWF         INDF         ;是,LSD=LSD+3
    MOVLW         0X30            ;否,MSD+3>7?
    ADDWF         INDF,0
    MOVWF         TEMP
    BTFSC         TEMP,7
    MOVWF         INDF            ;是,MSD=MSD+3
    RETLW         0            ;返回
【校验举例1】 -23808(十进制)
化为十六进制数:A300
结果:023808(BCD),SIGN=80
【校验举例2】 12306(十进制)
化为十六进制数: 3012
结果:012306(BCD),SIGN=00
【例程】
MAIN        MOVLW        0X00            ;双字节整数送ACCB
    MOVWF        ACCBLO
    MOVLW        0XA3
    MOVWF        ACCBHI
    CALL        BtoBCD        ;调子程序,将二进制数转换成BCD码
    END

5.2  3字节浮点数至5位压缩BCD码转换程序

图2.6  浮点数至5位压缩BCD码转换程序
程序通过3个步骤将一个3字节浮点数转换成5位压缩BCD码(压缩BCD码是指将两个BCD码分别存放在一个8位字节的高半字节和低半字节中)。首先,判断浮点数的符号,如果是负数,存符号位,并将之取补。其次,调用浮点数乘法或除法子程序,对浮点数进行连续的乘以10或除以10的操作,把浮点的阶码控制在+12≤EXPB<+16之间,即使得浮点数转换成定点数后,数值在4095(FFFH)和32767(7FFFH)之间。再次,调用浮点数至定点数子程序,将浮点数转换成双字节定点数。最后,调用定点数至BCD码子程序,将双字节无符号数转换成5位压缩BCD码,从而完成浮点数至压缩BCD码的转换。此外,乘以10或除以10的次数可以用来确定小数点的位置。在子程序中,乘以10或除以10的次数分别存在C_MUL和C_DIV单元中,但二者不可能同时大于0(二者不可能同时小于0,但可以同时等于0)。其中,当C_MUL>0时(此时,C_DIV必然等于0),表示小数点从BCD码的最后往前移动C_MUL位;当C_DIV>0时(此时,C_MUL必为0),表示小数点由BCD码的最后往后移动C_DIV位。转换后的BCD码的符号存于FPOL单元的第7位。
在该子程序中要调用大量的子程序,如浮点数乘法子程序、浮点数除法子程序、浮点数至定点数转换子程序和定点数至BCD码转换子程序等。在此由于篇幅的原因都予以省略,需要这些子程序的读者,请参阅前面相关章节。
浮点数至压缩BCD码转换程序的入口条件和出口条件如下:
入口条件:ACCBHI、ACCBLO、EXPB
出口条件:5位压缩BCD码存于ACCCHI低半字节、ACCCLO和ACCDHI中,符号保存于FPOL寄存器的第7位,小数点位置存于C_MUL和C_DIV中。
以下为本子程序的程序清单。

    LIST            p=16f877
    INCLUDE        p16f877.inc

    ACCALO         EQU     20        ;临时寄存器
    ACCAHI         EQU     21
    EXPA        EQU     22        ;临时寄存器
    ACCBLO         EQU     23        ;存放被转换浮点数尾数
    ACCBHI         EQU     24
    EXPB         EQU     25        ;存放被转换浮点数阶码
    ACCCLO         EQU     26        ;临时寄存器
    ACCCHI         EQU     27        ;临时寄存器
    ACCDLO         EQU     28        ;临时寄存器
    ACCDHI         EQU     29        ;临时寄存器
    TEMP         EQU     2A        ;临时寄存器
    TEMP1         EQU     30        ;临时寄存器
    TIMES         EQU     31        ;临时寄存器
    SIGN         EQU     2B        ;临时寄存器
    COUNT         EQU     2F        ;临时寄存器
    C_MUL         EQU     2C        ;存放小数点位置
    C_DIV         EQU     2D        ;存放小数点位置
    FPOL         EQU     2E        ;存放被转换数的符号
    ORG            0X0000
START    GOTO        MAIN
    ORG            0X0100
;*************浮点数到BCD码子程序****************
FtoBCD    CLRF         C_MUL        ;清小数点位数寄存器
    CLRF         C_DIV
    CLRF         ACCAHI        ;求取结果符号,存于FPOL.7
    CALL         S_SIGN
    MOVF         SIGN ,0
    MOVWF        FPOL
    MOVLW         50            ;ACCA赋初值,ACCA=10(十进制)
    MOVWF         ACCAHI
    CLRF         ACCALO
    MOVLW         04
    MOVWF         EXPA
MUl5    BTFSS        EXPB,7        ;阶码EXPB<0?
    GOTO        MUl2        ;否,转MU12
MUl1    CALL         F_mpy        ;是,ACCA×10
    INCF         C_MUL        ;小数点左移寄存器加1
    GOTO         MUl5        ;重新判断阶码是否小于零
MUl2    MOVLW         .12            ;阶码EXPB<12?
    SUBWF         EXPB,0
    BTFSC         STATUS,C
    GOTO         MUl4        ;否,转MU14
MUl3    CALL         F_mpy        ;是,ACCA×10
    INCF         C_MUL        ;小数点左移寄存器加1
    GOTO         MUL2        ;重判阶码值
MUl4    MOVLW         .16            ;阶码EXPB>16?
    SUBWF         EXPB,0
    BTFSS        STATUS,C
    GOTO         NEXT        ;否,表示阶码12≤EXPB<16,求取BCD码值
DIV1    CALL         FDIV            ;是,EXPB÷10
    INCF         C_DIV        ;小数点右移寄存器加1
    GOTO         MUl4        ;重新判断阶码值
NEXT    CALL         FTOW3        ;调子程序,将浮点数转换为定点数
    CALL         BtoBCD        ;调双字节数到BCD码子程序,求BCD码
    MOVF         ACCCHI        ;ACCCHI=0?
    BTFSS         STATUS,Z
    RETLW         0            ;否,返回
    MOVLW         04            ;是,结果左移4次,保证ACCCHI不为零
    MOVWF         TIMES
    BCF             STATUS,C
MUl6    RLF             ACCDHI
    RLF            ACCCLO
    RLF             ACCCHI
    DECFSZ         TIMES
    GOTO         MUl6
    MOVF         C_DIV        ;C_DIV=0?
    BTFSC         STATUS,Z
    GOTO         TEMUL        ;是,转判断C_MUL
    DECF         C_DIV        ;否,小数点右移寄存器减1
    RETLW         0
TEMUL    INCF         C_MUL        ;小数点左移寄存器加1
    RETLW         0   
【校验举例1】 -5.8125(十进制)
化为浮点数:A30003
结果:058120(BCD),C_MUL=4,C_DIV=0,FPOL=A3
【校验举例2】 0.00048881(十进制)
化为浮点数:4012F6
结果:048870(BCD),C_MUL=08,C_DIV=0,FPOL=40
【例程】
MAIN    MOVLW        0X00            ;将被转换数的尾数赋给ACCB
    MOVWF        ACCBLO
    MOVLW        0XA3
    MOVWF        ACCBHI
    MOVLW        0X03            ;将被转换数的阶码赋给EXPB
    MOVWF        EXPB
    CALL        FtoBCD        ;调用子程序开始转换
    END
6  定点数开方子程序
    从数值计算方法可知,方程G(X)=0可以由牛顿迭代法来求解。牛顿迭代法的一个重要应用就是开平方,就是通过对以下方程求解得到M的平方根:

函数G(X)在X0点用一阶泰勒级数展开可得:

如果Y是方程G(X)=0的根,那么G(Y)=0,即:

忽略高阶项,而只取前两项,就可以得到根Y的近似值,即

把此方程写成离散形式的迭代方程为:


又因为: ,所以 ,代入迭代方程可得:

这里M的平方根初值取M/2。如果在此之前知道M的平方根的范围,则可以取一个比M/2更好的初值开始迭代,可以减少迭代的次数。
如果被开方数是定点数格式,代入的迭代初值也是定点数格式,并且用定点除法(定点数的除2操作可以由右移一位得到)和定点加法进行迭代运算,则就是定点数开方。
定点数开方只能得到结果的整数部分,如代入FFFFH和FF10H的开方结果都是一样的,为FFH。如果想要得到比较精确的结果,可以先对被开方数乘以一个系数,待得到结果后,再除以相应的系数。如果被开方数太大,则不能使用此法,若想得到比较精确的结果,可以采用后面介绍的“浮点数开方”。
以下为定点数开方的程序清单(其中包含校验程序部分)。该程序中包含定点数加法程序和定点数除法程序。

    LIST            p=16f877
    INCLUDE        p16f877.inc
;****************************************
;此子程序是求16位二进制数平方根的子程序,需要调用16/16位除法子程序和
;加法子程序,虽然前面有了,但标号有些不同,为了易于阅读和理解,也把它列在后面。
;入口条件:16位二进制数存放在NUMHI和NUMLO单元中。
;出口条件:8位二进制数存放在SQRTLO单元中。
;迭代次数由LUPCNT的地址值决定。
;用指令CALL        SQRT实现定点数开方程序调用
;****************************************
     ACCALO        EQU        0X20
    ACCAHI        EQU        ACCALO+1
    EXPA        EQU        ACCALO+2
    ACCBLO        EQU        ACCALO+3
    ACCBHI        EQU        ACCALO+4
    EXPB        EQU        ACCALO+5   
    ACCCLO        EQU        ACCALO+6
    ACCCHI        EQU        ACCALO+7
    ACCDLO        EQU        ACCALO+8
    ACCDHI        EQU        ACCALO+9
    TEMP        EQU        ACCDHI+1
    SIGN            EQU        ACCDHI+2
    SQRTLO        EQU        ACCALO
    SQRTHI        EQU        ACCAHI
    NUMLO        EQU        ACCDHI+4
    NUMHI        EQU        ACCDHI+5
    COUNT    EQU    ACCDHI+6    ;此方法定义的数据块为连续层断,只要
                ;将第一行改变,就可以将数据整块搬动到
                ;新的地方,为调试带来方便,是比较推
                ;崇的一种寄存器定义方法
    LUPCNT    EQU    .10   
;****************************************
        ORG            0X00
        GOTO        MAIN
        ORG            0X10
;****************************************
INIT        MOVLW        LUPCNT
    MOVWF        COUNT
    MOVF        NUMHI,0
    MOVWF         SQRTHI
    MOVF        NUMLO,0
    MOVWF        SQRTLO
    BCF            STATUS,C
    RRF            SQRTHI,1
    RRF            SQRTLO,1
    RETLW        0
;***************16×16位定点数右移子程序***************
DIV2        BCF            STATUS,C
    RRF            ACCBHI,0
    MOVWF        SQRTHI
    RRF            ACCBLO,0
    MOVWF        SQRTLO
    RETLW        0
;*********16×16位定点数开方子程序**********
SQRT    CALL        INIT
SLOOP    MOVF        NUMLO,0
    MOVWF        ACCBLO
    MOVF        NUMHI,0
    MOVWF        ACCBHI
    CALL        D_DIVS
    CALL        D_ADD
    CALL        DIV2
    DECFSZ        COUNT,1
    GOTO        SLOOP
    RETURN
;***********16×16位定点整数除法子程序*********
D_DIVS    CALL        SETUP
        CLRF        ACCCHI
        CLRF        ACCCLO
DLOOP    BCF            STATUS,C
    RLF            ACCDLO
    RLF            ACCDHI
    RLF            ACCCLO
    RLF            ACCCHI
    MOVF        ACCAHI,0
    SUBWF        ACCCHI,0
    BTFSS        STATUS,Z
    GOTO        NOCHK
    MOVF        ACCALO,0
    SUBWF        ACCCLO,0
NOCHK    BTFSS        STATUS,C
        GOTO         NOGO
    MOVF        ACCALO,0
    SUBWF        ACCCLO,1
    BTFSS        STATUS,C
    DECF        ACCCHI,1
    MOVF        ACCAHI,0
    SUBWF        ACCCHI,1
    BSF            STATUS,C
NOGO    RLF            ACCBLO
    RLF            ACCBHI
    DECFSZ        TEMP
    GOTO        DLOOP
    RETLW        0
;****************************************
SETUP    MOVLW        .16
    MOVWF        TEMP
    MOVF        ACCBHI,0
    MOVWF        ACCDHI
    MOVF        ACCBLO,0
    MOVWF        ACCDLO
    CLRF        ACCBHI
    CLRF        ACCBLO
    RETLW        0
;**********16×16位定点数取补子程序**************
NEG_A    COMF        ACCALO,1
    INCF            ACCALO,1
    BTFSC        STATUS,Z
    DECF        ACCAHI,1
    COMF        ACCAHI,1
    RETLW        0
;*************16×16位定点数加法子程序**************
D_ADD    MOVF        ACCALO,0
    ADDWF        ACCBLO,1
    BTFSC        STATUS,C
    INCF            ACCBHI,1
    MOVF        ACCAHI,0
    ADDWF        ACCBHI,1
    RETLW        0
;****************************************
【校验举例】 被开方数2910H(十六进制)
                  10512(十进制)
    求得平方根:66H(十六进制)
                    102(十进制)
MAIN    NOP
    MOVLW        0X29   
    MOVWF        NUMHI
    MOVL7W        0X10
    MOVWF        NUMLO                ;被开方数赋值
    CALL        SQRT                ;调用开方子程序        
    NOP                                ;开方完毕
    END
7  浮点数开方程序
    如果被开方数是浮点数格式,代入的迭代初值也是浮点数格式,并且用浮点除法(浮点数的除以2操作可以由阶码减1得到)和浮点加法进行迭代运算,就是浮点数开方的基本思路。
以下为浮点数开方的程序清单(其中包含校验程序部分)。该程序中包含浮点数加法程序和浮点数除法程序,这些程序与前面章节列出的程序完全相同,不再列出。

        LIST            P=16f877
        INCLUDE        p16f877.inc
;****************************************
;此子程序是16尾数,8位阶码开方程序
;入口条件:浮点数存放在ACCBHI和ACCBLO     EXPB单元中.
;出口条件:结果放在ACCBHI和ACCBLO EXPB单元中.
;迭代次数由LUPCNT的地址值决定
;用CALL  SQRTF指令调用,
;内含浮点除程序,浮点加减程序
;****************************************
        ACCALO         EQU         20H
        ACCAHI         EQU         ACCALO +1
        EXPA         EQU         ACCALO +2
        ACCBLO         EQU         ACCALO +3
        ACCBHI        EQU         ACCALO +4
        EXPB         EQU         ACCALO +5
        ACCCLO         EQU         ACCALO +6
        ACCCHI         EQU         ACCALO +7
        ACCDLO         EQU         ACCALO +8
        ACCDHI         EQU         ACCALO +9
        TEMP         EQU         ACCALO +0A
        TEMP1         EQU         ACCALO +0B
        TIMES         EQU         ACCALO +0C
        SIGN         EQU         ACCALO +0D
        COUNT         EQU         ACCALO +0E
        C_MUL         EQU         ACCALO +0F
    C_DIV         EQU         ACCALO +10
        FPOL         EQU         ACCALO +11        ;符号放置位
        NUMLO        EQU        FPOL+1
        NUMHI        EQU        FPOL+2
        NUMM        EQU        FPOL+4
         LUPCNT        EQU        .10
        CONSTANT     C=0
        CONSTANT     Z=2
        CONSTANT     MODEL16=1
        CONSTANT     FALSE=0
;****************************************
        ORG            0X0000
        NOP
        GOTO        MAIN
        ORG            0X0010
;****************************************
INIT1    DECF        EXPB            ;假设迭代根的初始值为其原值的一半
    MOVF        ACCBHI,W
    MOVWF        ACCAHI
    MOVF        ACCBLO,W
    MOVWF        ACCALO
    MOVF        EXPB,W
    MOVWF        EXPA
    RETLW        0
SQRTF    MOVLW        LUPCNT
    MOVWF        COUNT
    MOVF        ACCBHI,W
    MOVWF        NUMHI
    MOVF        ACCBLO,W
    MOVWF        NUMLO
    MOVF        EXPB,W
    MOVWF        NUMM            ;存储被开方的数
    BTFSC        ACCBHI,7
    GOTO        TIQIAN            ;如果被开方数是个负数,则返回一极小数
    CALL        INIT1
SLOOP1    MOVF        NUMLO,0
        MOVWF        ACCBLO
        MOVF        NUMHI,0
    MOVWF        ACCBHI
    MOVF        NUMM,0
    MOVWF        EXPB
    CALL        FDIV
    CALL        F_add
    CALL        INIT1
    DECFSZ        COUNT,1
    GOTO        SLOOP1
    RETURN
TIQIAN    MOVLW        0X40
    MOVWF        ACCBHI
    CLRF        ACCBLO
    MOVLW        0X80
    MOVWF        EXPB        ;如果被开方数是一个负数,返回一个极小的浮点数
    RETURN        
;***浮点加子程序F_add详细的程序语句请参考前面章节***
;***浮点数除法子程序FDIV详细的程序语句请参考前面章节***
【校验举例】  被开方数55AAH,02H  (浮点数)
    求得平方根:68B6H,01H  (浮点数)
MAIN    NOP
    MOVLW        0X55
    MOVWF        ACCBHI               
    MOVLW        0XAA
    MOVWF        ACCBLO        ;被开方数的尾数55AAH赋值
    MOVLW        0X02
    MOVWF        EXPB        ;被开方数的阶码02H赋值
    CALL        SQRTF        ;调用浮点开方子程序
    NOP                        ;开方完毕,结果在ACCBHI、ACCBLO、EXPB
        END   
8  小数点显示位置确定子程序
在实际应用中,往往需要将一个浮点数表示的十进制数用数码管显示出来。当用户调用浮点数至BCD码子程序FtoBCD将这个浮点数转换成BCD码后,除了可以得到5位BCD码外,C_MUL和C_DIV寄存器中还有一个值用于确定哪个数码管该显示小数点。例如,设某浮点数调用译码子程序后,得到以下数值:012345(BCD),C_MUL=07,C_DIV=0,那么数码管显示的值应该为:0.0012345,1号数码管除了要显示0外,还要将小数点显示出来。以下子程序将完成这一功能。此外,一般而言,工程应用和实验中,多数要求显示4位有效数字,其显示范围在0.001~9999(符号没显示,如有需要,请读者自己添上)。如果要求显示数据超过9999,则4个LED显示“1111”;如果要求显示数据小于“0.001”,则4个LED显示“0000”(如果实际要求显示多于4位有效数字,则读者可以对本程序作相应的修改,就可以满足要求)。本子程序入口条件和出口条件分别如下:
    入口条件:ACCCHI1、ACCCLO1、ACCDHI1、ZUO、YOU;
    出口条件:DISP1、DISP2、DISP3、DISP4、LEDDOT(DISP1、DISP2、DISP3、DISP4用于存放显示的数字,LEDDOT用于存放小数点的位置)。
    注意,该子程序的入口条件和FtoBCD子程序的出口条件有如下对应关系:
ACCCHI1与ACCCHI对应,ACCCLO1与ACCCLO对应,ACCDHI1与ACCDHI对应,ZUO与C_MUL对应,YOU与C_DIV对应
用户在调用FtoBCD子程序后,可以用下面一段语句与该程序实现接口。
    CALL        FtoBCD
    MOVF        ACCCHI,W
    MOVWF        ACCCHI1
    MOVF        ACCCLO,W
    MOVWF        ACCCLO1
    MOVF        ACCDHI,W
    MOVWF        ACCDHI1
    MOVF        C_MUL,W
    MOVWF        ZUO
    MOVF        C_DIV,W
    MOVWF        YOU
    CALL        TESTDOT
本子程序的程序清单如下:
;**********小数点位置及显示寄存器值确定子程序************
TESTDOT        BANKSEL        LEDDOT
    CLRF        LEDDOT        ;清除小数点位置寄存器   
    MOVF        ZUO,W
    MOVWF        C_MUL1   
    MOVF        YOU,W
    BTFSS        STATUS,Z
    GOTO        CHAOCHU1
    MOVF        ZUO,W
    BTFSC        STATUS,Z
    GOTO        CHAOCHU1     ;C_DIV>0或C_MUL=0,表示浮点数超出显示
;范围上限,转移到过量程处理
    MOVF        ZUO,W
    SUBLW        0X07
    BTFSS        STATUS,C
    GOTO        TAIXIAO        ;C_MUL>7,超出显示范围下限,转移处理(改
;变与C_MUL比较的立即数的大小,可以改变
;下限)
    MOVF        ZUO,W
    SUBLW        0X01
    BTFSC        STATUS,Z
    GOTO        ZHUANG1        ;C_MUL=1,表示小数点左移1位,能够显示前
   ;4位(ACCCHI低半字节中始终有1位),转移处理
    MOVF        ZUO,W        ;同理可以对左移2~7位处理
    SUBLW        0X02
    BTFSC        STATUS,Z
    GOTO        ZHUANG2
    MOVF        ZUO,W
    SUBLW        0X03
    BTFSC        STATUS,Z
    GOTO        ZHUANG3
    MOVF        ZUO,W
    SUBLW        0X04
    BTFSC        STATUS,Z
    GOTO        ZHUANG4
    MOVF        ZUO,W
    SUBLW        0X05
    BTFSC        STATUS,Z
    GOTO        ZHUANG5
    MOVF        ZUO,W
    SUBLW        0X06
    BTFSC        STATUS,Z
    GOTO        ZHUANG6
    MOVF        ZUO,W
    SUBLW        0X07
    BTFSC        STATUS,Z
    GOTO        ZHUANG7
CHAOCHU1    MOVLW        0X01
        MOVWF        DISP1
        MOVWF        DISP2
        MOVWF        DISP3
        MOVWF        DISP4
        MOVLW        0XFF
        MOVWF        LEDDOT        ;不显示小数点
        RETURN                    ;超出上限时,DSP1、 DSP2、 DSP3、 DSP4中赋
;1,显示“1111”
TAIXIAO        MOVLW        0X00
        MOVWF        DISP1
        MOVWF        DISP2
        MOVWF        DISP3
        MOVWF        DISP4
        MOVLW        0X01
        MOVWF        LEDDOT        ;小数点的位置在第一位   
        RETURN                    ;超出下限,显示"0.000"
ZHUANG1        CALL        BIAO        ;C_MUL=1~4时,可调用标准赋值模块对
                                ;DSP1、 DSP2、DSP3、 DSP4赋值
        MOVLW        0X04
        MOVWF        LEDDOT        ;C_MUL=1时,小数点的位置在第4位
        RETURN
ZHUANG2        CALL        BIAO
        MOVLW        0X03
        MOVWF        LEDDOT        ;C_MUL=2时,小数点的位置在第3位
        RETURN
ZHUANG3        CALL        BIAO
        MOVLW        0X02
        MOVWF        LEDDOT        ;C_MUL=3时,小数点的位置在第2位
        RETURN
ZHUANG4        CALL        BIAO
        MOVLW        0X01
        MOVWF        LEDDOT        ;C_MUL=4时,小数点的位置在第1位
        RETURN
ZHUANG5        CLRF        DISP1        ;C_MUL=5时,DSP1=0
        MOVF        ACCCHI1,W     ;DSP2=ACCHI1低字节,DSP3和DSP4分别对
                                   ;应ACCCLO1的高低字节,ACCDHI1不显示(太小),
        MOVWF        DISP2         ;ACCDHI1的低字节一直没有显示
        MOVF        ACCCLO1,0
        MOVWF        C_MUL1
        SWAPF        ACCCLO1
        MOVLW        0X0F
        ANDWF        ACCCLO1,0
        MOVWF        DISP3
        MOVLW        0X0F
        ANDWF        C_MUL1,0
        MOVWF        DISP4
        MOVLW        0X01
        MOVWF        LEDDOT        ;小数点的位置在第1位        
        RETURN
ZHUANG6        CLRF        DISP1        ;C_MUL=6时,DSP1=0
        CLRF        DISP2        ;DSP2=0,DSP3=ACCCHI1的低字节,
                                ; DSP4=ACCCLO1的高字节,ACCCLO1低字
                                ;节和ACCDHI1不显示
        MOVF        ACCCHI1,W
        MOVWF        DISP3
        SWAPF        ACCCLO1
        MOVLW        0X0F
        ANDWF        ACCCLO1,0
        MOVWF        DISP4
        MOVLW        0X01
        MOVWF        LEDDOT        ;小数点的位置在第1位   
        RETURN
ZHUANG7        CLRF        DISP1        ;C_MUL=7时,DSP1=DSP2=DSP3=0,
                                ; DSP4=ACCCHI1低半字节,其它不显示
        CLRF        DISP2
        CLRF        DISP3
        MOVF        ACCCHI1,W
        MOVWF        DISP4
        MOVLW        0X01
        MOVWF        LEDDOT        ;小数点的位置在第1位   
        RETURN
BIAO        MOVF        ACCCHI1,W    ;C_MUL=1~4时的标准赋值模块
        MOVWF        DISP1
        SWAPF        ACCDHI1
        MOVLW        0X0F
        ANDWF        ACCDHI1,0
        MOVWF        DISP4
        MOVF        ACCCLO1,0
        MOVWF        C_MUL1
        SWAPF        ACCCLO1
        MOVLW        0X0F
        ANDWF        ACCCLO1,0
        MOVWF        DISP2
        MOVLW        0X0F
        ANDWF        C_MUL1,0
        MOVWF        DISP3
        RETURN
     执行完该程序后,通过调用适合的子程序,就可以方便地实现小数点位置的浮动显示(即若被显示的数突然从99.99变化到999.9,则程序自动实现小数点位置的调整。)




欢迎光临 英锐恩单片机论坛,Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流 (http://enroobbs.com/) Powered by Discuz! X3.2