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 }