模糊控制算法子程序

发布者:Chanhero最新更新时间:2016-01-20 来源: eefocus关键字:模糊控制算法  子程序  单片机 手机看文章 扫描二维码
随时随地手机看文章
程序为模糊控制程序,基于8位单片机,为模糊控制算法程序,实现简单的模糊控制,经实践总结得出,当调整幅度较大时,会出现振荡,系统难以达到稳定,这就需要更高一级的算法控制调整,当调整幅度较小时,系统可以很快达到稳定。
以下为模糊算法源程序:

#include "reg52.h"
//------------------------------------------------------------------------------------
// 定义差距输入常量
#define GAP_ZERO     0x00
#define GAP_VSMALL   0x01
#define GAP_SMALL    0x02
#define GAP_MEDIUM   0x03
#define GAP_BIG      0x04
// 定义控制输出常量
#define TURN_ZERO    0x80
#define TURN_VSMALL  0x81
#define TURN_SMALL   0x82
#define TURN_MEDIUM  0x83
#define TURN_BIG     0x84
//-------------定义常量----------------------------------------------------------------
#define MU_MAX 0XFF                               //模糊度的最大值为0XFF代表面1
#define RULE_TOT 10                               //规则数个数
#define MF_TOT 5                                  //成员函数的个数
#define IO_NUM 0x07
#define LABEL_NUM 0x70
#define DEFAULT_VALUE 0x00
//----------------定义数据库-----------------------------------------------------------
unsigned char code output_memf[MF_TOT]={0, 15, 35, 60, 102};// OUTPUT TURNING NUMBER:
                                                               //ZERO, VSMALL, SMALL, MEDIUM, BIG
unsigned char code input_memf[MF_TOT][4]={
// 输入功能函数以点斜式方式存储. 第一维成员函数标号第二维是点斜式数据
//距离功能函数
{ 0x00, 0x00, 0x00, 0x0d }, // VSLOW
{ 0x00, 0x0d, 0x14, 0x0d }, // SLOW
{ 0x1e, 0x0d, 0x32, 0x0d }, // MEDIUM
{ 0x3C, 0x0d, 0x50, 0x0d }, // FAST
{ 0x50, 0x09, 0x6e, 0x00 }  // VFAST
                                          };
//-----------定义模糊系统规则-----------------------------------------------------------
unsigned char code rules[RULE_TOT]={ 
// if...  then...
GAP_ZERO,TURN_ZERO,
GAP_VSMALL,TURN_VSMALL,
GAP_SMALL,TURN_SMALL,
GAP_MEDIUM,TURN_MEDIUM,
GAP_BIG,TURN_BIG
                                   };
//-----------定义各变量-----------------------------------------------------------------
unsigned char outputs[MF_TOT],fuzzy_out;            //模糊输出mu值
//-----------子程序函数头申明-----------------------------------------------------------
void fuzzy_engine(uchar);
uchar compute_memval(uchar,uchar);
void defuzzify(void);

uchar compute_memval(uchar input,uchar label)
           {
              int data temp;
              if (input < input_memf[label][0])
                                                // 如果输入不在曲线下u值为0
                     return 0;
                                       }
              else
                 {
                    if (input < input_memf[label][2])
                       {
                         temp=input;              // 用点斜式计算mu
                         temp-=input_memf[label][0];
                         if (!input_memf[label][1])
                           {
                             temp=MU_MAX;
                                                       }
                         else
                           {
                             temp*=input_memf[label][1];
                                                                     }
                         if (temp < 0x100)
                                               // 如果结果不超过1
                               return temp;       // 返回计算结果
                                              }
                         else
                            {
                               return MU_MAX;     // 确保mu值在范围内
                                              }
                                                         }
                    else
                                               // 输入落在第二条斜线上
                        temp=input;               // 用点斜式方法计算 mu
                        temp-=input_memf[label][2];
                        temp*=input_memf[label][3];
                        temp=MU_MAX-temp;
                        if (temp < 0)
                                               // 确保结果不小于0
                              return 0;
                                            }
                        else
                           {
                              return temp;        // mu为正 – 返回结果
                                            }
                                                       }
                                                                     }
                              return 0;
                                                                          }

void defuzzify(void)
     {
        unsigned long numerator, denominator;
        unsigned char j;
        numerator=0;                         // 恢复总数值
        denominator=0;
        for (j=0; j                                           // 计算总和值
               numerator+=(outputs[j]*output_memf[j]);
               denominator+=outputs[j];
               outputs[j]=0; // 清零输出作为参考使用                                                              }
               if (denominator)
                                                  // 确保分母是0的情况不发生
                    fuzzy_out=numerator/denominator; // 确定 COG
                                                        }
              else
                  {
                    fuzzy_out=DEFAULT_VALUE; // 没有规则被触发
                                                                 }
                                                                       }
                        }

unsigned char bdata clause_val;                        // 保存当前的分支进行快速访问
sbit clause_type = clause_val^7;                       // 表示分支是否是条件分支或者是结果分支
void fuzzy_engine(uchar input)
     {
       bit then;                                       // 当正在分析结果时置位
       unsigned char if_val,                           // 保存当前规则中条件分支中的值
                     clause,                           // 规则基中当前的分支
                         mu,                           // 保存当前分支中的值
                      label=0;                           // 被条件使用的成员函数
                     then=0;                           // 设第一个分支是条件分支
               if_val=MU_MAX;                          // max out mu for the first rule
      for (clause=0; clause                                                     // 遍历每条规则
            clause_val=rules[clause];                  // 读入当前的分支
            if (!clause_type)
                                                    // 当前的分支是不是条件分支
                 if (then)
                                                    // 是否正在分析结果...
                      then=0;
                      if_val=MU_MAX;                    // 复位mu
                                          }
                 mu=compute_memval(input, label);        // 得到条件分支的值
     if_val=mu;
     label++;
                                                    }
            else
                                                   // 当前分支是结果
                then=1;            // 置位标志位,如果当前规则的mu比参考的值要大,保存这个值作为新的模糊输出
                if (outputs[clause_val&0x07] < if_val)
                 {
                    outputs[clause_val&0x07]=if_val;
                                                                                         }
                                                                                            }
                                                                                                }
          defuzzify(); // 用COG方法计算模糊输出和反模糊输出
                                                                                                       }
//------------------------------------------------------------------------------
 
给出模糊控制的流程图,若想完全理解清楚其控制原理,最好还是要找想关的模糊控制理论书籍,方能理解透彻:
 
1.控制理论框图
 
 
2.控制算法的总流程图,对应模糊控制算法的程序流程图
 
 
 

关键字:模糊控制算法  子程序  单片机 引用地址:模糊控制算法子程序

上一篇:跳转到绝对地址执行
下一篇:凌阳61单片机之定时器

推荐阅读最新更新时间:2024-03-16 14:44

AVR单片机定点运算及数制转换子程序
  AVR单片机问世以来,获得广泛关注。它是一种采用精简指令集、以时钟周期为机器周期的高速单片机。它采用快速寄存器文件(共有32个寄存器 R0~R31,其中R16~R31具有较强通用功能)、快速单周期指令。另外在存储器技术(Flash存储器、EEPROM)、低功耗、系统可靠性、定时 /计数器功能多样化等方面也都具特色。但由于采用精简指令集,它没有一般8位机的DAA指令。因BCD码加减法运算及定点数制转换都要用到DAA功能,故给使用汇编语言研发带来不便。本文重点介绍用软件实现DAA的方法。   计算机采用的十进制操作数一般都为压缩型8421 BCD码,每个BCD码表示1位十进制数。每2位BCD码共存于同一字节单元中,故BCD运算涉及状
[单片机]
【E课堂】对单片机的理解
  single chip microcomputer,单芯片微型计算机。总体来说,他就是一个芯片。但是他是一个特殊的芯片,因为他不是实现单独的逻辑功能。他是将一个整体的计算机系统集成到这个芯片上。这个计算机系统包括运算器,控制器,存储器,输入设备和输出设备。下面就随嵌入式小编一起来了解一下相关内容吧。   其实 单片机 的学习,和计算机的学习差别不是太大。包括运算器,控制器,存储器,以及输入输出设备的学习。   运算器   运算器由运算部件--算术逻辑单元(alu)、累加器、计算器等部件组成。    控制器   学习的难点在于涉及到指令方面的操作。控制器由程序计数器,指令寄存器,指令译码器,时序发生器和操作控制器。  
[嵌入式]
德州仪器宣布其SimpleLink™ MCU平台集成全新的Amazon FreeRTOS
德州仪器(TI)近日宣布,SimpleLink™微控制器(MCU)平台集成全新的亚马逊FreeRTOS,帮助开发商快速而安全地将物联网(IoT)终端连接到云端。亚马逊网络服务(AWS)与德州仪器合作开发了集成的硬件和软件解决方案,使开发人员能够快速建立与AWS物联网服务的连接,立即开始系统开发。如需了解更多信息,敬请访问 www.ti.com/AWSIoT-pr-cn 。 亚马逊近日在拉斯维加斯的AWS re:Invent 2017大会上推出了FreeRTOS,可提供快速方便地部署基于微控制器的连接器件和开发物联网应用所需的工具,使用户无需再为涉及数百万器件的扩展而困扰。连接后,物联网器件应用程序可以利用云服务提供的各项功能
[物联网]
德州仪器宣布其SimpleLink™ <font color='red'>MCU</font>平台集成全新的Amazon FreeRTOS
AT89S52单片机与CF卡的接口电路设计
1 前言 随着计算机应用技术的飞速发展,移动存储设备得到了广泛的应用。其中CF(Compact Flash)卡以其价格低廉、体积小、存储容量大、高速等优点在众多移动存储设备中被广泛地应用于数码相机、PDA和笔记本电脑等当前十分热门的消费类电子产品中。并且CF卡在其他领域中也得到了广泛的应用。本文所述内容就是通过8051单片机对CF卡进行读写。 2.CF卡的操作方式 CF卡的操作方式与计算机的硬盘操作方式类似,其扇区的寻址也有两种方式:物理寻址(CHS)和逻辑寻址(LBA),物理寻址使用柱面、磁头和扇区号表示一个特定的扇区,起始扇区是0道、0头、1区,接下来是2区等等,逻辑寻址将整个CF卡统一寻址。逻辑块寻址和物理寻址的关系为:L
[单片机]
AT89S52<font color='red'>单片机</font>与CF卡的接口电路设计
基于单片机的双积分型A/D电路设计
   0 引言   A/D转换电路是数据采集系统中的重要部分,也是计算机应用系统中一种重要的功能接口。目前市场上有两种常用的A/D转换芯片,一类是逐次逼近式的,如AD1674,其特点是转换速度较高,功率较低。另一类是双积分式的,如ICL7135,其特点是转换精度高、抗干扰能力强。但高位数的A/D转换器价格相对较高。本文介绍的一种基于单片机的高精度、双积分型A/D转换电路,具有电路体积小、成本低、性价比高、结构简单、调试容易和工作可靠等特点,有很好的实际应用价值。    1 双积分式ADC基本原理   双积分式ADC的基本电路如图1所示,运放A 1、R、C用来组成积分器,运放A2作为比较器。电路先对未知的模拟输入电压U1进行固
[单片机]
基于<font color='red'>单片机</font>的双积分型A/D电路设计
单片机如何提高编程效率优化程序
在进行8051单片机应用系统程序设计时,编程都往往少不了要直接操作系统的各个存储器地址空间。 C51程序经过编译之后产生的目标代码具有浮动地址,其绝对地址必须经过BL51连接定位后才能确定。 为了能够在C51程序中直接对任意指定的存储器地址进行操作,可以采用扩展关键字“at”、指针、预定义以及连接定位控制命令。 在这些方法中,本人认为最简单而有效的方法是用“ _at_ ”关键字来对指定变量存储器空间绝对地址来指定。一般格式如下: 数据类型 标识符 _at_ 地址常数 其中: (1).存储器类型: idata、data、xdata等C51能够识别的所有类型,最好不要省略。 (2).数据类型: 可以用int、long、flo
[单片机]
PIC单片机闪烁程序
#INCLUDE P16F877.inc ;芯片型号 org 000h GOTO a1 org 1ch ;************************************************ ; 主程序 ;************************************************ a1 BSF STATUS,RP0 ;选择体1 BCF STATUS,RP1 MOVLW 00H ;设置RD口为输出口 MOVWF TRISD BCF STATUS,RP0 ;选择体0 MOVLW 00H ; MOVWF PORTD ;RD口输出低电平 CALL M001
[单片机]
用51内核网络单片机构成的远程监控系统
引 言 在工业控制、信息家电等应用领域,存在大量的嵌入式设备,而这些设备很多只有串口、CAN总线等简单的网络接口,通信能力有限,有的甚至处于孤立运行状态。如何让这些以单片机为核心的嵌入式系统接入以太网,并通过网络对它们进行远程监控,是当前电子世界中的研究热点。TCP/IP在Intemet和大多数局域网中的成功应用,已经证明了其强大的功能。如果实现TCP/IP协议和嵌入式系统的结合,嵌入式系统联网问题就能得到有效解决。目前,嵌入式系统联网主要有如下几种方案:①EMIT,以PC或其它高档计算机为网关,将CAN、RS-232等设备接入重量级网络;②采用32位MCU+实时操作系统,高档MCU功能强大,可以实现复杂操作,但需要有RTOS
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved