單片機 模糊控制 算法 c語言


  1 #include "reg52.h"
  2 //------------------------------------------------------------------------------------
  3 // 定義差距輸入常量
  4 #define GAP_ZERO     0x00
  5 #define GAP_VSMALL   0x01
  6 #define GAP_SMALL    0x02
  7 #define GAP_MEDIUM   0x03
  8 #define GAP_BIG      0x04
  9 // 定義控制輸出常量
 10 #define TURN_ZERO    0x80
 11 #define TURN_VSMALL  0x81
 12 #define TURN_SMALL   0x82
 13 #define TURN_MEDIUM  0x83
 14 #define TURN_BIG     0x84
 15 //-------------定義常量----------------------------------------------------------------
 16 #define MU_MAX 0XFF            //模糊度的最大值為0XFF代表面1
 17 #define RULE_TOT 10            //規則數個數
 18 #define MF_TOT 5               //成員函數的個數
 19 #define IO_NUM 0x07
 20 #define LABEL_NUM 0x70
 21 #define DEFAULT_VALUE 0x00
 22 //----------------定義數據庫-----------------------------------------------------------
 23 unsigned char code output_memf[MF_TOT]={0, 15, 35, 60, 102};// OUTPUT TURNING NUMBER:
 24                                                             // ZERO, VSMALL, SMALL, MEDIUM, BIG
 25                                                             // 輸入功能函數以點斜式方式存儲. 第一維成員函數標號第二維是點斜式數據
 26 unsigned char code input_memf[MF_TOT][4]={                  //距離功能函數
 27                                             { 0x00, 0x00, 0x00, 0x0d }, // VSLOW
 28                                             { 0x00, 0x0d, 0x14, 0x0d }, // SLOW
 29                                             { 0x1e, 0x0d, 0x32, 0x0d }, // MEDIUM
 30                                             { 0x3C, 0x0d, 0x50, 0x0d }, // FAST
 31                                             { 0x50, 0x09, 0x6e, 0x00 }  // VFAST
 32                                           };
 33 //-----------定義模糊系統規則-----------------------------------------------------------
 34 unsigned char code rules[RULE_TOT]={ 
 35                                         // if...  then...
 36                                         GAP_ZERO,TURN_ZERO,
 37                                         GAP_VSMALL,TURN_VSMALL,
 38                                         GAP_SMALL,TURN_SMALL,
 39                                         GAP_MEDIUM,TURN_MEDIUM,
 40                                         GAP_BIG,TURN_BIG
 41                                    };
 42 //-----------定義各變量-----------------------------------------------------------------
 43 unsigned char outputs[MF_TOT],fuzzy_out;  //模糊輸出mu值
 44 //-----------子程序函數頭申明-----------------------------------------------------------
 45 void fuzzy_engine(uchar);
 46 uchar compute_memval(uchar,uchar);
 47 void defuzzify(void);
 48 /***************************************************************************************************************/
 49 uchar compute_memval(uchar input,uchar label)
 50  {
 51     int data temp;
 52     if (input < input_memf[label][0])
 53     {                                 // 如果輸入不在曲線下u值為0
 54          return 0;
 55     }
 56     else
 57     {
 58         if (input < input_memf[label][2])
 59         {
 60              temp=input;              // 用點斜式計算mu
 61              temp-=input_memf[label][0];
 62              if (!input_memf[label][1])
 63              {
 64                 temp=MU_MAX;
 65              }
 66              else
 67              {
 68                 temp*=input_memf[label][1];
 69              }
 70              if (temp < 0x100)
 71              {                     // 如果結果不超過1
 72                 return temp;       // 返回計算結果
 73              }
 74              else
 75              {
 76                 return MU_MAX;     // 確保mu值在范圍內
 77              }
 78         }
 79         else
 80         {                           // 輸入落在第二條斜線上
 81             temp=input;               // 用點斜式方法計算 mu
 82             temp-=input_memf[label][2];
 83             temp*=input_memf[label][3];
 84             temp=MU_MAX-temp;
 85             if (temp < 0)
 86             {                      // 確保結果不小於0
 87                   return 0;
 88             }
 89             else
 90             {
 91                   return temp;        // mu為正 – 返回結果
 92             }
 93         }
 94     }
 95     return 0;
 96 }
 97 /*******************************************************************************
 98 Function: defuzzify
 99 Description: 計算模糊輸出的重心並調用函數把它
100              轉換成可被系統使用的輸出量
101 Parameters: 無.
102 Returns: 無.
103 Side Effects: outputs[][] 數組被清零.
104 *******************************************************************************/
105 void defuzzify(void)
106 {
107     unsigned long numerator, denominator;
108     unsigned char j;
109     numerator=0;                         // 恢復總數值
110     denominator=0;
111     for (j=0; j<MF_TOT; j++)
112     {                                // 計算總和值
113         numerator+=(outputs[j]*output_memf[j]);
114         denominator+=outputs[j];
115         outputs[j]=0;                        // 清零輸出作為參考使用
116         if (denominator)
117         {                                     // 確保分母是0的情況不發生
118             fuzzy_out=numerator/denominator;  // 確定 COG
119         }
120         else
121         {
122             fuzzy_out=DEFAULT_VALUE;         // 沒有規則被觸發
123         }
124     }
125 }
126 /*******************************************************************************
127 Function: fuzzy_engine
128 Description: 實施規則基中的規則
129 Parameters: 無
130 Returns: 無.
131 Side Effects: 無
132 ********************************************************************************/
133 unsigned char bdata clause_val;                        // 保存當前的分支進行快速訪問
134 sbit clause_type = clause_val^7;                       // 表示分支是否是條件分支或者是結果分支
135 void fuzzy_engine(uchar input)
136 {
137     bit then;                                       // 當正在分析結果時置位
138     unsigned char if_val,                           // 保存當前規則中條件分支中的值
139                   clause,                           // 規則基中當前的分支
140                       mu,                           // 保存當前分支中的值
141                  label=0;                           // 被條件使用的成員函數
142                   then=0;                           // 設第一個分支是條件分支
143            if_val=MU_MAX;                           // max out mu for the first rule
144     for (clause=0; clause<RULE_TOT; clause++)
145     {                                               // 遍歷每條規則
146         clause_val=rules[clause];                   // 讀入當前的分支
147         if (!clause_type)
148         {                                           // 當前的分支是不是條件分支
149             if (then)
150             {                                       // 是否正在分析結果...
151                 then=0;
152                 if_val=MU_MAX;                      // 復位mu
153             }
154             mu=compute_memval(input, label);        // 得到條件分支的值
155             if_val=mu;
156             label++;
157         }
158         else
159         {                                       // 當前分支是結果
160             then=1;            // 置位標志位,如果當前規則的mu比參考的值要大,保存這個值作為新的模糊輸出
161             if (outputs[clause_val&0x07] < if_val)
162             {
163                 outputs[clause_val&0x07]=if_val;
164             }
165         }
166     }
167     defuzzify(); // 用COG方法計算模糊輸出和反模糊輸出
168  }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM