|
問題:數碼管不顯示問題
情況:加上Fuzzy模塊的函數后,數碼管不顯示
單片機源程序如下:
- void display_service();
- unsigned char ad_result = 0,ControlOut=0; // 0-255
- int ad_show = 0;
- void main()
- {
- while(1)
- {
- ad_result = ADC_Conv();
- ad_show = ad_result; //5v - 500 255-份
- display_service();
- Display();
- ControlOut = Control_Fuzzy(ad_result); //如果注釋掉這行代碼,不調用這個函數就會正常
- DAC0832_Conv(ControlOut);
- }
- }
- void display_service()
- {
- LEDBUF[0]=ad_show/1000%100;
- LEDBUF[1]=ad_show/100%10;
- LEDBUF[2]=ad_show/10%10;
- LEDBUF[3]=ad_show%10;
- }
復制代碼
fuzzy模塊代碼
- const float code WaterLevel_FuzzyControl_table[7][7]=
- // NL NM NS ZO PS PM PL
- {
- 3, 3, 3, 3, 2, 1, 0, //NL
- 3, 3, 3, 2, 1, 0, 0, //NM
- 3, 3, 2, 0, 0, 0, 0, //NS
- 0, 0, 0, 0, 0, 0, 0, //ZO
- 0, 0, 0, 0,-2,-3,-3, //PS
- 0, 0,-1,-2,-3,-3,-3, //PM
- 0,-1,-2,-3,-3,-3,-3 //PL
- };
- /*
- 函數名稱:隸屬度計算函數
- 參數:x為清晰值對應的模糊值,x0,x1,x2為端點中點值
- a,b,c為過程隸屬度,u為最終隸屬度
- */
- float Membership( char x0, char x1, char x2, float x)
- {
- float a,b,c,u;//r,
- //r = x1-x0; //相似三角形算法
- //if(r == 0)
- // r = 0.001; //保證分母不為零
- a = (x-x0)/(x1-x0);//r;
- //r = x2-x1;
- //if(r == 0)
- // r = 0.001;
- b = (x2-x)/(x2-x1);//r;
- /* tanx算法 tanx=1
- a = x-x0;
- b = x2-x;
- */
-
- if(a <= b) //比較取小
- c = a;
- else
- c = b;
- if(c < 0) //若隸屬度小于零,則強制為零
- u = 0; //隸屬度為什么等于零
- else
- u = c;
- return u; //返回隸屬度
- }
- /*
- 函數名稱:控制函數
- 參數:入口參數WL;WLE水位偏差;WLEC偏差變化;
- WLFlag水位控制標志;WL0上一次的水位值;
- WLE0為上一次的水位偏差;WLOut為累計的水位控制輸出;
- K為水位控制輸出比例因子。
- */
- unsigned int Control_Fuzzy(unsigned char WL)
- {
- /*float ControlOut;
- ControlOut = WL;*/
- static unsigned char WL0 = 0, WLE0 = 0 ;//WLOut = 127 ,;
- float ControlOut,WLE,WLEC;//,CG = 0
- float code K = 2.67;
- char i,j;//,k = 0
- static char WLFlag = 0;
- float MembershipE[7],MembershipEE[7];// //定義隸屬度值緩沖區
- if(WLFlag == 1) goto FC; //滿足條件,進入模糊控子程序
- //*************水位異常報警**************
- if(WL <= 106) //水位超低
- {
- if(WL0 == 0) //第一次進入程序不進行控制
- {
- ControlOut = 0;
- WL0 = WL;
- }
- else //否則報警
- {
- ControlOut = 0xff;
- //Alarm();
- }
- }
- else if (WL >= 150) //水位超高
- {
- if(WL0 == 0) //第一次進入程序不進行控制
- {
- ControlOut = 0;
- WL0 = WL;
- }
- else //否則報警
- {
- ControlOut = 0;
- //Alarm();
- }
- }
- //爆管與虛假水位報警
- WLE = WL - WL0; //計算水位偏差及其變化
- WLEC = WLE - WLE0;
- WL0 = WL;
- if(WLEC*10 <= -1) //爆管
- {
- ControlOut = 0xff;
- //Alarm();
- }
- else if(WLEC*10 >= 3)
- {
- ControlOut = 0; //虛假水位
- //Alarm();
- }
- else
- FC:
- {
- if(WLFlag == 0) //第一次進入程序不進行控制
- {
- WLFlag = 1;
- //K = 2.67;
- WLE = (WL - 127)*0.035; //論域轉換
- WL0 = WL;
- WLE = WLE0;
- ControlOut = 0;
- }
- else
- {
- WLFlag = 1;
- WLE = (WL - 127)*0.035; //論域轉換
- WL0 = WL;
- WLEC = (WLE0 - WLE)*0.024;
- WLEC = WLE;
- }
- //**************計算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);
-
- //**************求輸出************
- for(i=1;i<8;i++)
- {
- if(MembershipE[i]>0)
- {
- i=i;
- }
- }
- for(j=1;j<8;j++)
- {
- if(MembershipEE[i]>0)
- {
- j=j;
- }
- }
- ControlOut = WaterLevel_FuzzyControl_table[i][j]*K*16+127; //計算結果并且轉化論域
- }
- return ControlOut;
- }
復制代碼
|
-
-
代碼仿真.zip
2022-3-6 21:14 上傳
點擊文件名下載附件
149 KB, 下載次數: 5
|