单片机 模糊控制 算法 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  }

 

posted on 2016-08-11 15:41  cvi670  阅读(5234)  评论(1编辑  收藏  举报

导航