找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2332|回复: 3
收起左侧

单片机小白求教问题—数码管不显示

[复制链接]
ID:675269 发表于 2022-3-6 21:15 | 显示全部楼层 |阅读模式
问题:数码管不显示问题
情况:加上Fuzzy模块的函数后,数码管不显示

单片机源程序如下:
  1. void display_service();

  2. unsigned char ad_result = 0,ControlOut=0; // 0-255
  3. int ad_show = 0;

  4. void main()
  5. {

  6.         while(1)
  7.         {
  8.                 ad_result = ADC_Conv();
  9.                 ad_show = ad_result;  //5v - 500  255-份
  10.                 display_service();
  11.                 Display();
  12.                 ControlOut = Control_Fuzzy(ad_result);  //如果注释掉这行代码,不调用这个函数就会正常
  13.                 DAC0832_Conv(ControlOut);
  14.         }
  15. }

  16. void display_service()
  17. {
  18.         LEDBUF[0]=ad_show/1000%100;
  19.         LEDBUF[1]=ad_show/100%10;
  20.         LEDBUF[2]=ad_show/10%10;
  21.         LEDBUF[3]=ad_show%10;
  22. }
复制代码

fuzzy模块代码
  1. const float code WaterLevel_FuzzyControl_table[7][7]=
  2.     // NL NM NS ZO PS PM PL
  3. {
  4.         3, 3, 3, 3, 2, 1, 0, //NL
  5.         3, 3, 3, 2, 1, 0, 0, //NM
  6.         3, 3, 2, 0, 0, 0, 0, //NS
  7.         0, 0, 0, 0, 0, 0, 0, //ZO
  8.         0, 0, 0, 0,-2,-3,-3, //PS
  9.         0, 0,-1,-2,-3,-3,-3, //PM
  10.         0,-1,-2,-3,-3,-3,-3        //PL
  11. };

  12. /*
  13. 函数名称:隶属度计算函数
  14. 参数:x为清晰值对应的模糊值,x0,x1,x2为端点中点值
  15.           a,b,c为过程隶属度,u为最终隶属度
  16. */
  17. float Membership( char x0, char x1, char x2, float x)
  18. {
  19.         float a,b,c,u;//r,

  20.         //r = x1-x0;                                        //相似三角形算法
  21.         //if(r == 0)
  22.         //        r = 0.001;                                //保证分母不为零
  23.         a = (x-x0)/(x1-x0);//r;
  24.         //r = x2-x1;
  25.         //if(r == 0)
  26.         //        r = 0.001;
  27.         b = (x2-x)/(x2-x1);//r;
  28. /*  tanx算法  tanx=1
  29.     a = x-x0;   
  30.         b = x2-x;
  31. */
  32.                
  33.         if(a <= b)                                        //比较取小
  34.                 c = a;
  35.         else
  36.                 c = b;
  37.         if(c < 0)                                        //若隶属度小于零,则强制为零
  38.                 u = 0;                                        //隶属度为什么等于零
  39.         else
  40.                 u = c;
  41.         return u;                                        //返回隶属度
  42. }

  43. /*
  44. 函数名称:控制函数
  45. 参数:入口参数WL;WLE水位偏差;WLEC偏差变化;
  46.           WLFlag水位控制标志;WL0上一次的水位值;
  47.           WLE0为上一次的水位偏差;WLOut为累计的水位控制输出;
  48.           K为水位控制输出比例因子。
  49. */

  50. unsigned int Control_Fuzzy(unsigned char WL)

  51. {
  52.         /*float ControlOut;
  53.         ControlOut = WL;*/
  54.         static unsigned char WL0 = 0, WLE0 = 0 ;//WLOut = 127 ,;
  55.         float ControlOut,WLE,WLEC;//,CG = 0
  56.         float code K = 2.67;
  57.         char i,j;//,k = 0
  58.         static char WLFlag = 0;
  59.         float MembershipE[7],MembershipEE[7];//        //定义隶属度值缓冲区

  60.         if(WLFlag == 1) goto FC;                //满足条件,进入模糊控子程序
  61. //*************水位异常报警**************
  62.         if(WL <= 106)                                //水位超低
  63.                 {
  64.                 if(WL0 == 0)                        //第一次进入程序不进行控制
  65.                         {
  66.                                 ControlOut = 0;
  67.                                 WL0 = WL;
  68.                         }
  69.                 else                                        //否则报警
  70.                         {
  71.                                 ControlOut = 0xff;
  72.                                 //Alarm();
  73.                         }
  74.                 }
  75.         else if (WL >= 150)                        //水位超高
  76.                 {
  77.                 if(WL0 == 0)                        //第一次进入程序不进行控制
  78.                         {
  79.                                 ControlOut = 0;
  80.                                 WL0 = WL;
  81.                         }
  82.                 else                                        //否则报警
  83.                         {
  84.                                 ControlOut = 0;
  85.                                 //Alarm();
  86.                         }
  87.                 }
  88. //爆管与虚假水位报警
  89.         WLE = WL - WL0;                                //计算水位偏差及其变化
  90.         WLEC = WLE - WLE0;
  91.         WL0 = WL;
  92.         if(WLEC*10 <= -1)                        //爆管
  93.                 {
  94.                         ControlOut = 0xff;
  95.                         //Alarm();
  96.                 }
  97.         else if(WLEC*10 >= 3)
  98.                 {
  99.                         ControlOut = 0;                //虚假水位
  100.                         //Alarm();
  101.                 }
  102.         else
  103.         FC:
  104.                 {
  105.                         if(WLFlag == 0)                                //第一次进入程序不进行控制
  106.                                 {
  107.                                         WLFlag = 1;
  108.                                         //K = 2.67;
  109.                                         WLE = (WL - 127)*0.035;                //论域转换
  110.                                         WL0 = WL;
  111.                                         WLE = WLE0;
  112.                                         ControlOut = 0;
  113.                                 }
  114.                         else
  115.                                 {
  116.                                         WLFlag = 1;
  117.                                         WLE = (WL - 127)*0.035;                //论域转换
  118.                                         WL0 = WL;
  119.                                         WLEC = (WLE0 - WLE)*0.024;
  120.                                         WLEC = WLE;
  121.                                 }        
  122.         //**************计算WLE的隶属度************                                
  123.                 MembershipE[1] = Membership(-4,-3,-2,WLE);
  124.                 MembershipE[2] = Membership(-3,-2,-1,WLE);
  125.                 MembershipE[3] = Membership(-2,-1,-0,WLE);
  126.                 MembershipE[4] = Membership(-1,-0,1,WLE);
  127.                 MembershipE[5] = Membership(0,1,2,WLE);
  128.                 MembershipE[6] = Membership(1,2,3,WLE);
  129.                 MembershipE[7] = Membership(2,3,4,WLE);

  130.         //**************计算WLEC的隶属度************
  131.                 MembershipEE[1] = Membership(-4,-3,-2,WLEC);
  132.                 MembershipEE[2] = Membership(-3,-2,-1,WLEC);
  133.                 MembershipEE[3] = Membership(-2,-1,-0,WLEC);
  134.                 MembershipEE[4] = Membership(-1,-0,1,WLEC);
  135.                 MembershipEE[5] = Membership(0,1,2,WLEC);
  136.                 MembershipEE[6] = Membership(1,2,3,WLEC);
  137.                 MembershipEE[7] = Membership(2,3,4,WLEC);
  138.                
  139.         //**************求输出************
  140.                 for(i=1;i<8;i++)
  141.                 {
  142.                         if(MembershipE[i]>0)
  143.                                 {
  144.                                         i=i;
  145.                                 }
  146.                 }
  147.                 for(j=1;j<8;j++)
  148.                 {
  149.                         if(MembershipEE[i]>0)
  150.                                 {
  151.                                         j=j;
  152.                                 }
  153.                 }        
  154.                 ControlOut = WaterLevel_FuzzyControl_table[i][j]*K*16+127;        //计算结果并且转化论域
  155.                 }
  156.                 return ControlOut;
  157. }
复制代码


代码仿真.zip

149 KB, 下载次数: 5

回复

使用道具 举报

ID:415064 发表于 2022-3-7 08:52 | 显示全部楼层
要么死循环,要么崩了
回复

使用道具 举报

ID:675269 发表于 2022-3-7 15:31 | 显示全部楼层
wojiaoguogai 发表于 2022-3-7 08:52
要么死循环,要么崩了

谢谢解答,我模拟跑了一遍,发现每次经过fuzzy模块出来后,再display后有又从第一个switch语句开始。死循环了,不知道是什么原因,现在我用定时中断刷新display后可以显示了。
回复

使用道具 举报

ID:161164 发表于 2022-3-7 17:37 | 显示全部楼层
fuzzy.c :
行64:float MembershipE[7],MembershipEE[7];//        //定义隶属度值缓冲区

行128~144:
        //**************计算WLE的隶属度************                               
                MembershipE[1] = Membership(-4,-3,-2,WLE);
                MembershipE[2] = Membership(-3,-2,-1,WLE);
                MembershipE[3] = Membership(-2,-1,-0,WLE);
                MembershipE[4] = Membership(-1,-0,1,WLE);
                MembershipE[5] = Membership(0,1,2,WLE);
                MembershipE[6] = Membership(1,2,3,WLE);
                MembershipE[7] = Membership(2,3,4,WLE);

        //**************计算WLEC的隶属度************
                MembershipEE[1] = Membership(-4,-3,-2,WLEC);
                MembershipEE[2] = Membership(-3,-2,-1,WLEC);
                MembershipEE[3] = Membership(-2,-1,-0,WLEC);
                MembershipEE[4] = Membership(-1,-0,1,WLEC);
                MembershipEE[5] = Membership(0,1,2,WLEC);
                MembershipEE[6] = Membership(1,2,3,WLEC);
                MembershipEE[7] = Membership(2,3,4,WLEC);

[]内只能是0~6,MembershipEE[7] 指向了不知明地址
当中可能包含了display内的i
而当你把display放进定时中断内
display内的i的地址改变了
于是显示就正常了
但依然存某地址不断被MembershipEE[7] = Membership(2,3,4,WLEC);覆写的危险

而且display内的i应定义为静态变数
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表