Want to see what people are talking about? See the latest forum posts.
*/
*/

View \FUZZY11A.ASM

Fuzzy logic interference engine for hc11

Submitted By: WEBMASTER
Rating: Not rated (Rate It)


*       Fuzzy Logic Inferrence Engine
*
*** Data structures and variables
*
        ORG     $0000                ;Beginning of HC11 RAM
CURRENT_INS RMB 8                ;Storage for 8 8-bit inputs
FUZ_OUTS        RMB     32      ;Storage for fuzzy outputs
COG_OUTS        RMB     4        ;Defuzzified outputs
LOWEST_IF RMB   1    ;Holds min grade of IF parts
SUM_OF_FUZ RMB  2  ;11-bit sum of fuzzy outs
SUM_OF_PROD RMB 3                ;19-bit sum of products
COGDEX  RMB       1            ;Current out # for COG loop 0->4
SUMDEX  RMB       1            ;Index for sum loop 8->0

        ORG     $B600                Beginning of HC11 EEPROM
IN_MF_PTRS FDB  IN0MF          ;Addr of MF data for input 0
        FDB     IN1MF                ;Addr of MF data for input 1
        FDB     IN2MF                ;Addr of MF data for input 2
        FDB     IN3MF                ;Addr of MF data for input 3
        FDB     IN4MF                ;Addr of MF data for input 4
        FDB     IN5MF                ;Addr of MF data for input 5
        FDB     IN6MF                ;Addr of MF data for input 6
        FDB     IN7MF                ;Addr of MF data for input 7
*
* Input membership functions are defined by four 8-bit values per
* input label. Up to 8 labels per input so max size of MF data
* structure is 8*8*4=256 bytes. Unused labels take no space.
* Membership functions are trapezoids with the base greater than or
* equal to the top. Values are entered into this program as the
* X coordinates of 4 points but are stored as 2 points and 2 slopes.
*
***** MACRO Definition for input membership functions
*
INMF    MACR        ;For input membership functions
        FCB     0                        ;First inflection point
        IFNE 1-0                              ;Check for divide by zero
         FCB    ($FF+((1-0)/3))/(1-0) ;If not, calc slope
        ENDC
        IFEQ 1-0                              ;Check for divide by zero
         FCB    $00                     ;Indicates vertical slope
        ENDC
        FCB     2                        ;Third inflection point
        IFNE 3-2                              ;Check for divide by zero
         FCB    ($FF+((3-2)/3))/(3-2) ;If not, calc slope
        ENDC
        IFEQ 3-2                              ;Check for divide by zero
         FCB    $00                     ;Indicates vertical slope
        ENDC
        ENDM
*       
*****
INPUT_MFS EQU   *       ;Input membership functions

IN0MF   EQU        *                       ;(0) ROTATION
        INMF    0,0,0,8*4            ; (0) STOPPED
        INMF    0,8*4,$FF,$FF        ;      (1) NOT_STOPPED

IN1MF   EQU        *                       ;(1) EXAMPLE1
        INMF    $20,$40,$60,$A0      ;      (0) TEST1

IN2MF   EQU        *                       ;(2) TEMPERATURE
        INMF    2*0,2*0,2*40,2*50      ;       (0) COLD
        INMF    2*40,2*50,2*60,2*70  ;      (1) COOL
        INMF    2*60,2*70,2*80,2*90  ;      (2) WARM
        INMF    2*80,2*90,2*95,2*110 ;      (3) HOT
        INMF    2*90,2*110,$FF,$FF   ;      (4) VERY_HOT

IN3MF   EQU        *                       ;(3) DAYS_SINCE_RAIN
        INMF    $00,$00,$00,$08        ; (0) NONE
        INMF    $00,$10,$10,$18        ; (1) SHORT
        INMF    $10,$20,$28,$40        ; (2) MEDIUM
        INMF    $30,$40,$50,$60        ; (3) LONG
        INMF    $50,$70,$FF,$FF        ; (4) VERY_LONG

IN4MF   EQU        *              ;Not used
IN5MF   EQU        *              ;Not used
IN6MF   EQU        *              ;Not used
IN7MF   EQU        *              ;Not used

SGLTN_POS EQU   *    ;Output singleton positions
OUT0MF  EQU       *            ;(0) WATERING_TIME
        FCB     $00      ;(0) CUT_OFF
        FCB     $10      ;(1) DECREASE_GREATLY
        FCB     $40      ;(2) DECREASE
        FCB     $80      ;(3) NORMAL
        FCB     $B0      ;(4) INCREASE
        FCB     $F0      ;(5) INCREASE_GREATLY
        FCB     0,0    ;Unused; Must fill 8 per output
OUT1MF  FCB       0,0,0,0,0,0,0,0        ;Not used
OUT2MF  FCB       0,0,0,0,0,0,0,0        ;Not used
OUT3MF  FCB       0,0,0,0,0,0,0,0        ;Not used
*
* Each If part is of the form 00AA AXXX where AAA is a label (0-7)
* and XXX is an input (0-7). If parts are connected by ANDs. A rule
* may have any number of if parts (usually 2-8). Then parts are of
* the form 100Y YCCC where the MSB set indicates a then part, YY is
* the output number (0-3), and CCC is the output label (singleton
* 0-7). A rule may have any number of then parts (usually 1 or 2).
* A $FF indicates the end of a series of rules (number not limited).

*       FCB    INx + 8*LABa        ;If input XXX is label AAA
*       FCB    $80+8*OUTy+LABc     ;Then output YY is label CCC

RULE_START EQU  *  ;Start of first rule
* Example rule: If TEMPERATURE is VERY_HOT and DAYS_SINCE_RAIN is LONG
* Then WATERING_TIME is INCREASE_GREATLY
RULE_1  FCB       2+(8*4),3+(8*3),$80+(8*0)+5
END_OF_RULE FCB $FF

***** Fuzzy Inferrence Engine Starts Here
*
        ORG     $B66B
INFER_TOP LDX   #FUZ_OUTS  ;Point at first fuzzy output
        LDAA    #32  ;32 fuzzy outputs
CLR_OUTS        CLR     0,X    ;Clear a fuzzy output
        INX               ;Point at next
        DECA            ;Loop index
        BNE     CLR_OUTS          ;Continue till all fuzzy outs 0
        LDY     #RULE_START  ;Point to start of 1st rule
RULE_TOP        LDAA    #$FF                ;Begin processing rule string
        STAA    LOWEST_IF   ;Will hold grade of min if part
IF_LOOP LDAB     0,Y    ;Get rule byte 00AA AXXX; If X is A
        BMI     THEN_LOOP    ;If MSB=1, exit to then loop
        LDX     #CURRENT_INS ;Point at current input data area
        ANDB    #$07                ;Save only input number
        PSHB            ;Will need input # again
        ABX               ;Point to specific input data
        LDAA    0,X  ;Get current input data
        LDX     #IN_MF_PTRS  ;Point at offsets for input MFs
        PULB            ;Recover input number 0000 0XXX
        ABX               ;Point at pointer for this input #
        LDX     0,X    ;Get pointer into MF data area
        LDAB    0,Y  ;Get rule if part 00AA AXXX
        ANDB    #$38                ;00AA A000 is 8 times AAA
        LSRB            ;000A AA00 4 times AAA
        ABX               ;X points at MF points & slopes
        CMPA    0,X  ;Compare input data to MF pt1
        BHS     NOT_SEG0          ;Branch if not segment zero
        CLRB            ;In seg 0 grade is zero
        BRA     HAVE_GRADE   ;Have grade of membership
NOT_SEG0        CMPA    2,X  ;Compare input data to MF pt2
        BHI     IS_SEG2            ;Branch if segment two
        LDAB    1,X  ;Slope1 -> B
        BEQ     JAM_FF              ;If vert slope, jam $FF
        SUBA    0,X  ;Input value - pt1 -> A
        MUL               ;Grade in B if D < $100
        CPD     #$100                ;Check for overflow
        BLO     HAVE_GRADE   ;If < $100 grade OK in B
JAM_FF  LDAB      #$FF    ;Else limit B to $FF
        BRA     HAVE_GRADE   ;Have grade of membership
IS_SEG2 LDAB     3,X    ;Slope2 -> B
        SUBA    2,X  ;Input value - pt2 -> A
        MUL               ;Grade in B if D < $100
        CPD     #$100                ;Check for overflow
        BLO     B_OK  ;If < $100 value in B OK
        LDAB    #$FF                ;Else limit B to $FF
B_OK    LDAA        #$FF        ;Grade should be $FF - (B)
        SBA               ;Grade of membership in B
HAVE_GRADE CMPB LOWEST_IF        ;Is grade lowest so far ?
        BHS     NOT_LOWR          ;Branch if not lower
        STAB    LOWEST_IF   ;If lower, replace lowest if
        BNE     NOT_LOWR          ;Skip ahead if not zero
FIND_THEN INY         ;Adv rule pointer to then part
        LDAB    0,Y  ;Get next rule byte
        BPL     FIND_THEN    ;MSB set means its a then part
FIND_IF INY                  ;Adv rule pointer to if part
        LDAB    0,Y  ;Get next rule byte
        BPL     RULE_TOP          ;MSB clear means its an if part
        CMPB    #$FF                ;$FF is no more rules marker
        BNE     FIND_IF            ;Continue looking for if or $FF
        BRA     DEFUZ                ;When all rules done, go defuzzify
NOT_LOWR        INY               ;Point to next rule byte
        BRA     IF_LOOP            ;Continue for all if parts
THEN_LOOP LDX   #FUZ_OUTS  ;Point at fuzzy outputs
        ANDB    #$1F                ;Save 8 times out # + label #
        ABX               ;X points at fuzzy output
        LDAA    LOWEST_IF   ;Grade of membership for rule
        CMPA    0,X  ;Compare to fuzzy output
        BLO     NOT_HIER          ;Branch if not higher
        STAA    0,X  ;Grade is higher so update
NOT_HIER        INY               ;Point to next rule byte
        LDAB    0,Y  ;Get rule byte
        BMI     CHK_END            ;If MSB=0 its a new rule
        JMP     RULE_TOP          ;Else process next rule byte
CHK_END CMPB     #$FF  ;Check for end of rules flag
        BNE     THEN_LOOP    ;If not $FF, must be a then part
DEFUZ   LDY        #SGLTN_POS      ;Point at 1st output singleton
        LDX     #FUZ_OUTS    ;Point at 1st fuzzy output
        CLR     COGDEX              ;Loop index will run from 0->4
COG_LOOP        LDAB    #8    ;8 fuzzy outs per COG output
        STAB    SUMDEX            ;Inner loop runs 8->0
        LDD     #$0000              ;Used for quicker clears
        STD     SUM_OF_FUZ   ;Sum of fuzzy outputs
        STD     SUM_OF_PROD+1        ;Low 16-bits of sum of products
        STAA    SUM_OF_PROD ;Upper 8-bits
SUM_LOOP        LDAB    0,X  ;Get a fuzzy output
        CLRA            ;Clear upper 8-bits
        ADDD    SUM_OF_FUZ  ;Add to sum of fuzzy outputs
        STD     SUM_OF_FUZ   ;Update RAM variable
        LDAA    0,X  ;Get fuzzy output again
        LDAB    0,Y  ;Get Output singleton position
        MUL               ;Position times weight
        ADDD    SUM_OF_PROD+1       ;Low 16-bits of sum of products
        STD     SUM_OF_PROD+1        ;Update low 16-bits
        LDAA    SUM_OF_PROD ;Upper 8-bits
        ADCA    #0    ;Add carry from 16-bit add
        STAA    SUM_OF_PROD ;Upper 8-bits of 24-bit sum
        INY               ;Point at next singleton pos.
        INX               ;Point at next fuzzy output
        DEC     SUMDEX              ;Inner loop index
        BNE     SUM_LOOP          ;For all labels this output
        PSHX            ;Save index for now
        CLRA            ;In case divide by zero
        LDX     SUM_OF_FUZ   ;Demominator for divide
        BEQ     SAV_OUT            ;Branch if denominator is 0
        TST     SUM_OF_PROD  ;See if more than 16-bit
        BNE     NUM_BIG            ;If not zero, # is > 16-bits
        LDD     SUM_OF_PROD+1        ;Numerator for divide
        IDIV            ;Result in low 8-bits of X
        XGDX            ;Result now in B
        TBA               ;Move result to A
        BRA     SAV_OUT            ;Go save output
NUM_BIG LDD      SUM_OF_PROD   ;Numerator upper 16 of 24-bit
        TST     SUM_OF_PROD+2        ;Check for rounding error
        BPL     NO_ROUND          ;If MSB clear, don't round
        ADDD    #1    ;Round numerator up 1
NO_ROUND        FDIV            ;D/X -> X, use upper 8 of 16
        XGDX            ;Result now in A
SAV_OUT LDX      #COG_OUTS     ;Point to 1st defuz output
        LDAB    COGDEX            ;Curent output number
        ABX               ;Point to correct output
        STAA    0,X  ;Update defuzzified output
        PULX            ;Recover index
        INCB            ;Increment loop index
        STAB    COGDEX            ;Update
        CMPB    #4    ;Done with all four outs?
        BNE     COG_LOOP          ;If not, continue loop

* Inference engine has completed one pass of all rules.

corner
© 1996-2008 CommunityHeaven LLC. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
North American business development: Nicolai Wadstrom. Publisher: Lars Hagelin.
Resource Listings