|
用智能控制的算法實(shí)現(xiàn)的,三角形隸屬函數(shù),輸入為污泥度和油脂度,輸出為電動(dòng)機(jī)的轉(zhuǎn)動(dòng)時(shí)間,程序都有詳細(xì)標(biāo)注
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機(jī)源程序如下:
- /**********
- 論域e ec u 規(guī)則r
- e[e_length] e_length 5+1 //第一個(gè)輸入變量表的長(zhǎng)度
- ec[ec_length] ec_length 5+1 //第二個(gè)輸入變量表的長(zhǎng)度
- u[]
- r[r_Line_width][r_Column_width] r_Line_width 5 //規(guī)則表的行
- r_Column_width 5//規(guī)則表的列
- //等級(jí)表自動(dòng)生成的
- unsigned char e_level[e_length-1]={0};
- unsigned char ec_level[ec_length]={0};
- unsigned char u_level[u_level_length]={0};
- unsigned char x;//第一個(gè)電壓的等級(jí)
- unsigned char y;//第二個(gè)電壓的等級(jí)
- unsigned char z;//輸出等級(jí)
- *************/
- #include <REG52.H>//頭文件
- #include "TLC2543.h"
- #define uchar unsigned char//宏定義
- #define uint unsigned int
- /*******************************數(shù)碼表****************************/
- unsigned char code Tab[11]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //數(shù)碼管顯示0~9的段碼表
- /************修改長(zhǎng)度區(qū)****************************/
- //論域的長(zhǎng)度
- #define e_length 5+1 //e的長(zhǎng)度
- #define ec_length 5+1 //第二個(gè)輸入變量表的長(zhǎng)度
- #define u_length 5
- //規(guī)則表的行列
- #define r_Line_width 5 //規(guī)則表的行
- #define r_Column_width 5//規(guī)則表的列
- /*************論域表****************************/
- // 0 1 2 3 4
- double code e[e_length] ={0, 0.7, 2.0, 3.0, 4.2, 5};//5個(gè)范圍6個(gè)數(shù)代表實(shí)際輸入電壓
- double code ec[ec_length]={0, 0.7, 2.0, 3.0, 4.2, 5};//5個(gè)范圍6個(gè)數(shù)
- unsigned char code u[u_length]={28,34,40,46,52};
- /*************論域等級(jí)表****************************/
- unsigned char e_level[e_length-1]={0};//等級(jí)表自動(dòng)生成的
- unsigned char ec_level[ec_length-1]={0};
- unsigned char u_level[u_length]={0};
- /*****************規(guī)則表**************************/
- unsigned char r[r_Line_width][r_Column_width]= //規(guī)則表(里面的數(shù)據(jù)代表的輸出等級(jí))
- {
- 1,1,2,3,4,
- 1,2,3,4,5,
- 2,3,3,4,5,
- 3,4,4,5,5,
- 4,5,5,5,5
- };
- //兩個(gè)輸入和一個(gè)輸出得等級(jí)
- unsigned char x;//第一個(gè)電壓的等級(jí)
- unsigned char y;//第二個(gè)電壓的等級(jí)
- unsigned char z;//輸出等級(jí)
- //兩個(gè)真實(shí)的電壓
- double e_u;
- double ec_u;
- unsigned char u_t;//電動(dòng)機(jī)轉(zhuǎn)動(dòng)時(shí)間
- //tlc2543讀取的兩個(gè)電壓
- uint ad_value1=0;
- uint ad_value2=0;
- unsigned char int_time; //記錄中斷次數(shù)
- unsigned char second; //儲(chǔ)存秒
- unsigned char second1; //儲(chǔ)存秒
- uint t=0,tt=0;
- uint t1=0,tt1=0;
- //按鍵定義
- sbit k_start=P0^7;
- sbit k_stop=P0^6;
- sbit k3=P0^2;
- sbit sg=P0^3;
- sbit Upper_leve=P0^4;//上液位
- sbit Lower_level=P0^5;//下液位
- sbit ledon=P0^7;
- sbit washing_led=P2^0;//洗滌燈
- sbit drying_led=P2^1;//甩干燈
- sbit in_led=P2^5;//進(jìn)水燈
- sbit out_led=P2^6;//排水燈
- sbit p30=P3^0;
- sbit p31=P3^1;
- sbit beepon=P2^7;//蜂鳴器
- sbit sm1=P3^6;//進(jìn)水閥門
- sbit sm2=P3^7;//出水閥門
- void DisplaySecond(unsigned char k);
- unsigned char rule_process(double e_local[e_length] ,double ec_local[ec_length],unsigned char r_local[r_Line_width][r_Column_width])
- {
- //將兩個(gè)輸入的論域分為等級(jí)存在兩個(gè)表中分別為01234....
- uchar i=0;
- uchar j=0;
- uchar t;
- //等級(jí)i分為01234
- for(i=0;i<e_length-1;i++)//循環(huán)01234
- {
- e_level[i]=i; //存進(jìn)去表01234
- if ( (e_local[i]<e_u) && (e_u<=e_local[i+1]) ) //e電壓大于第0個(gè)數(shù)小于第一個(gè)數(shù)
- x=i; // x等級(jí)為0
- }
-
- //等級(jí)j分為01234
- for(j=0;j<ec_length-1;j++)
- {
- ec_level[j]=j;
- if ( (ec_local[j]<ec_u) && (ec_u<=ec_local[j+1]) ) //ec電壓大于第0個(gè)數(shù)小于第一個(gè)數(shù)
- y=j; // y等級(jí)為0
- }
- z=r_local[x][y];//確定輸出z的等級(jí)(查找規(guī)則)等級(jí)輸出為12345
- t=u[z-1];//輸出電動(dòng)機(jī)轉(zhuǎn)動(dòng)的時(shí)間//等級(jí)輸出01234所對(duì)應(yīng)的時(shí)間
- return t;
- }
- //延時(shí)函數(shù)
- void delay2(void)
- {
- unsigned char m;
- for(m=0;m<200;m++);
- }
- void delay1(int s)
- {
- int i;
- for(;s>0;s--)
- for(i=0;i<65;i++);
- }
-
- void delay(uint i)
- {
- uchar j;
- for(i;i>0;i--)
- for(j=255;j>0;j--);
- }
- //顯示函數(shù)
- void DisplaySecond(unsigned char k)
- {
-
- sm1=0; //P2.6引腳輸出低電平, DS6點(diǎn)亮
- P1=Tab[k/10]; //顯示十位
- delay2();
- delay2();
- sm1=1;
- sm2=0; //P2.7引腳輸出低電平, DS7點(diǎn)亮
- P1=Tab[k%10]; //顯示個(gè)位
- delay2();
- delay2();
- P3=0xff; //關(guān)閉所有數(shù)碼管
- P1=1; //顯示個(gè)位
- delay2();
- delay2();
- }
- //響蜂鳴器程序
- void beep()
- {
- p30=0;
- p31=0;
- t=0;
- while(1)
- {
- beepon^=1;
- delay(300);
- if(t>=80) break;
- }
- beepon=0;
- }
-
- void Washing(uint Washing_time_sec)
- {
- t=0;
- tt=0;
- int_time=0;
- second=Washing_time_sec;
- //洗滌的時(shí)間
- while(1)
- {
- //每20代表真實(shí)的一秒
- if(tt>=Washing_time_sec*20) break; //洗滌時(shí)間總共是Washing_time_sec秒 時(shí)間到了退出循環(huán)
- t=0;
- //正轉(zhuǎn)2s
- while(t<40&&tt<=Washing_time_sec*20)
- {
- p31=0;
- p30=1; //正轉(zhuǎn) 2s
- DisplaySecond(second);
- }
- t=0;
- //反轉(zhuǎn) 2s
- while(t<40&&tt<=400)
- {
- p30=0;
- p31=1;
- DisplaySecond(second);
- }
- }
- //停止轉(zhuǎn)動(dòng)
- p30=0;
- p31=0;
- }
- void out_water()
- {
- p30=0;
- p31=0;
- out_led=1; //排水閥燈亮 等待霍爾開(kāi)關(guān)2
- while(Lower_level);
- if(Lower_level==0) //如果閉合
- out_led=0; //排水燈滅
- }
- void in_water()
- {
- p30=0;
- p31=0;
- in_led=1;//進(jìn)水燈亮起
- while(Upper_leve);//等待
- if(Upper_leve==0)//進(jìn)水完畢
- in_led=0;//進(jìn)水燈關(guān)閉
- }
- void drying(uint Drying_time)
- {
- t=0;
- int_time=0;
- DisplaySecond(0);
- second=Drying_time;
- while(t<=Drying_time*20)
- {
- p31=0;
- p30=1;
- if(second>=0)
- DisplaySecond(second);
- }
- }
- void work()
- {
- //甩干占4s 兩次占8s 兩次進(jìn)出水共計(jì)6s 所以兩次洗滌 (u_t-14)/2
- in_water(); //等待進(jìn)水完畢才往下走
- Washing((u_t-14)/2); //洗滌10S
- out_water(); //洗滌結(jié)束開(kāi)始排水//等待排水排干再繼續(xù)往下走
- drying(4); //甩干4s
- in_water(); //進(jìn)水開(kāi)始等待進(jìn)水結(jié)束
- Washing((u_t-14)/2); //漂洗10S
- out_water(); //漂洗結(jié)束開(kāi)始排水//等待排水排干再繼續(xù)往下走
- drying(4);
- beep();
- }
- void Read_voltage()
- {
- // e_u=3; //輸入電壓
- // ec_u=4; //輸入電壓
- // u_t=rule_process(e,ec,r);//輸入?yún)?shù)為e ec 和r
- //真實(shí)得到電壓小數(shù) 第一個(gè)電壓
- //小數(shù)兩位b=(uint)(e_u*1000)%1000/10
- //整數(shù)一位a=(uint)(e_u*1000)/1000
- ad_value1=(read2543(0)*5000.0)/4095;//第一通道//輸出電壓是一個(gè)4位整數(shù)
- e_u=ad_value1/1000.0;
- ad_value2=(read2543(1)*5000.0)/4095;//第二通道//輸出電壓是一個(gè)4位整數(shù)
- ec_u=ad_value2/1000.0; //第二個(gè)電壓
- }
- int main(void)
- {
- TMOD=0x01; //方式1 16位計(jì)數(shù)器
- TH0=-50000/256; //設(shè)定初值
- TL0=-50000%256;
- EA=1; //開(kāi)總中斷
- ET0=1; //開(kāi)定時(shí)器0中斷
- TR0=1; //啟動(dòng)定時(shí)器0
- P2=0;
- int_time=0; //中斷次數(shù)初始化
- second=00; //秒初始化
- while(1)
- {
- if(k_start==0)
- {
- while(1)
- {
- Read_voltage(); //將兩個(gè)的電壓讀入到e_u ec_u
- u_t=rule_process(e,ec,r); //輸入?yún)?shù)為e ec 和r
- work();
- }
-
- }
-
-
- // DisplaySecond(u_t); //顯示出應(yīng)該輸出的電機(jī)轉(zhuǎn)動(dòng)的時(shí)間
- }
- return 0;
- }
- void time0() interrupt 1 using 1
- {
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
程序加仿真洗衣機(jī)版本五.rar
(161.4 KB, 下載次數(shù): 150)
2019-1-23 18:31 上傳
點(diǎn)擊文件名下載附件
|
評(píng)分
-
查看全部評(píng)分
|