|
仿真及程序下載:
LPC2124的溫度模糊控制系統(tǒng)Proteus仿真 源代碼.rar
(158.51 KB, 下載次數(shù): 86)
2016-9-5 13:31 上傳
點擊文件名下載附件
下面是部分源代碼預(yù)覽:
- /****************************************************************************
- * File: main.c
- * 功能:向LCD輸出計數(shù)值
- ****************************************************************************/
- #include "config.h"
- #define rs (1<<9)
- #define rw (1<<10)
- #define en (1<<11)
- #define busy (1<<7)
- #define ke 2
- #define kec 2.5
- uint8 e,ec;
- fp32 ectemp,prelevel,etemp;
- uint8 temp=0;
- uint8 fuzzycode[21][11]=
- {
- {5,5,5,5,5,5,4,3,2,1,1},
- {5,5,5,5,5,5,4,2,2,1,1},
- {5,5,5,5,5,5,4,2,2,1,1},
- {5,5,5,5,5,5,4,2,1,1,1},
- {5,5,5,5,5,5,4,2,1,1,1},
- {5,5,5,5,5,5,4,2,1,1,1},
- {5,5,5,4,4,4,3,2,1,1,1},
- {5,5,5,4,4,4,3,2,1,1,1},
- {5,5,4,4,4,3,2,2,1,0,0},
- {5,5,4,4,3,2,1,1,1,0,0},
- {4,4,3,3,2,1,1,1,0,0,0},
- {3,3,2,2,1,1,1,0,0,0,0},
- {2,2,2,2,1,1,1,0,0,0,0},
- {2,2,2,1,1,0,0,0,0,0,0},
- {2,2,2,1,1,0,0,0,0,0,0},
- {1,1,1,1,1,0,0,0,0,0,0},
- {1,1,1,1,1,0,0,0,0,0,0},
- {1,1,1,1,1,0,0,0,0,0,0},
- {1,1,1,1,1,0,0,0,0,0,0},
- {1,1,1,1,1,0,0,0,0,0,0},
- {1,1,1,1,1,0,0,0,0,0,0}
- };
- uint8 BCD[7]; //十位二進(jìn)制的顯示碼分別是千百十個位的顯示
- uint32 ADC_Data;
- void ShowInt(uint8 addr,uint16 num);
- void ShowByte(uint8 addr,uint16 num);
- uint32 AD_Convert(void) ;
- void fuzzy(void);
- void PWM0(void);
- void PWM1(void);
- void PWM2(void);
- void PWM3(void);
- void PWM4(void);
- void PWM5(void);
- /****************************************************************************
- * File: main()
- * 功能:顯示計數(shù)值
- ****************************************************************************/
- int main(void)
- {
- PINSEL0=0x00020000;
- PINSEL1=0x00000000;
- IO0DIR=0x00cfffff; //設(shè)置為輸出
- IO0CLR=0xeff;
- TargetInit();
-
- ShowByte(0x80,0);
- ShowByte(0xc0,0);
-
- fuzzy();
-
- return(0);
- }
- /****************************************************************************
- * File:delay()
- * 功能:延時
- ****************************************************************************/
- void delay(uint32 dly)
- { uint32 i;
- for(; dly>0; dly--)
- for(i=0; i<500; i++);
- }
- /****************************************************************************
- * File:timer0_init
- * 功能:定時器0初始化
- ****************************************************************************/
- void timer0_init(void)
- {//定時器計數(shù)器0設(shè)置,晶振為12M,1秒要運行1000000個周期,
- T0PR=0; //預(yù)分頻寄存器
- T0MR0=Fpclk/20; //匹配值
- T0MCR=0x00000003; //開放匹配0中斷
- T0TCR=0x00000003; //T0PC和T0TC復(fù)位
- T0TCR=0x00000001; //T0PC和T0TC復(fù)位
- }
- void timer1_init(void)
- {//定時器計數(shù)器0設(shè)置,晶振為12M,1秒要運行1000000個周期,
- T1PR=0; //預(yù)分頻寄存器
- T1MR0=Fpclk/20; //匹配值
- T1MCR=0x00000003; //開放匹配0中斷
- T1TCR=0x00000003; //T0PC和T0TC復(fù)位
- T1TCR=0x00000001; //T0PC和T0TC復(fù)位
- }
- /****************************************************************************
- * File:timerInt
- * 功能:中斷處理程序
- ****************************************************************************/
- void __irq timer0Int(void)
- { uint32 d;
- d=AD_Convert();
- ShowInt(0x86,d);
-
- VICVectAddr=0;
- T0IR=0x00000001;
- }
- void __irq timer1Int(void)
- {
- fuzzy();
-
- VICVectAddr=0;
- T0IR=0x00000001;
- }
- /****************************************************************************
- * File:int_init()
- * 功能:中斷初始化
- ****************************************************************************/
- void int_init(void)
- {
- VICIntSelect=0x00000000;
- VICIntEnable=0x00000030;
- VICVectCntl0=0x00000024;
- VICVectAddr0=(int)timer0Int;
- VICVectCntl1=0x00000025;
- VICVectAddr1=(int)timer1Int;
-
-
- }
- /****************************************************************************
- * 名稱:ChkBusy()
- * 功能:檢查總線是否忙
- ****************************************************************************/
- void ChkBusy()
- {
- IO0DIR=0xe00;
- while(1)
- {
- IO0CLR=rs;
- IO0SET=rw;
- IO0SET=en;
- if(!(IO0PIN & busy))break;
- IO0CLR=en;
- }
- IO0DIR=0xeff;
- }
- /****************************************************************************
- * 名稱:WrOp()
- * 功能:寫函數(shù)
- ****************************************************************************/
- void WrOp(uint8 dat)
- {
- ChkBusy();
- IO0CLR=rs; //全部清零
- IO0CLR=rw;
- IO0CLR=0xff; //先清零
- IO0SET=dat; //再送數(shù)
- IO0SET=en;
- IO0CLR=en;
- }
- /****************************************************************************
- * 名稱:WrDat()
- * 功能:寫數(shù)據(jù)函數(shù)
- ****************************************************************************/
- void WrDat(uint8 dat)
- {
- ChkBusy();
- IO0SET=rs;
- IO0CLR=rw;
- IO0CLR=0xff; //先清零
- IO0SET=dat; //再送數(shù)
- IO0SET=en;
- IO0CLR=en;
- }
- /****************************************************************************
- * 名稱:lcd_init()
- * 功能:lcd初始化函數(shù)
- ****************************************************************************/
- void lcd_init(void)
- {
- WrOp(0x38);
- WrOp(0x06); //光標(biāo)加1
- WrOp(0x0c); //開顯示
- }
- /****************************************************************************
- * 名稱:DisText()
- * 功能:顯示文本函數(shù)
- ****************************************************************************/
- void DisText(uint8 addr,uint8 *p)
- {
- WrOp(addr);
- while(*p !='\0')WrDat(*(p++));
- }
- /****************************************************************************
- * 名稱:DisInt()
- * 功能:顯示文本函數(shù)
- ****************************************************************************/
- void ShowInt(uint8 addr,uint16 num) //在addr處顯示數(shù)字num
- {//將num轉(zhuǎn)化成五個BCD碼存放在全局?jǐn)?shù)組BCD[5]中
- uint8 i;
-
- for(i=5;i>0;i--) //將NUM數(shù)據(jù)轉(zhuǎn)化成ASCII碼,如521會轉(zhuǎn)化為00521
- {
- BCD[i-1]=(uint8)(num%10+0x30); //取出最低位
- num/=10; //去掉最低位
- }
- i=0;
- while(BCD[i] ==0x30 && i<4) BCD[i++]=' '; //NUM轉(zhuǎn)換成數(shù)組存放,沒有加上小數(shù)點
- BCD[5]='\0';
-
-
- DisText(addr,BCD);
- }
- void ShowByte(uint8 addr,uint16 num) //在addr處顯示數(shù)字num
- {//將num轉(zhuǎn)化成五個BCD碼存放在全局?jǐn)?shù)組BCD[5]中
-
- uint8 str1[]="MeasT:";
- uint8 str2[]="SetT:";
- if (addr==0x80){DisText(addr,str1);}
- if (addr==0xc0){DisText(addr,str2);}
-
- }
- uint32 AD_Convert(void)
- {
- uint32 data;
-
-
- // 進(jìn)行ADC模塊設(shè)置,其中x<<n表示第n位設(shè)置為x(若x超過一位,則向高位順延)
- ADCR = (1 << 0) | // SEL = 1 ,選擇通道0
- ((Fpclk / 1000000 - 1) << 8) | // CLKDIV = Fpclk / 1000000 - 1 ,即轉(zhuǎn)換時鐘為1MHz
- (0 << 16) | // BURST = 0 ,軟件控制轉(zhuǎn)換操作
- (0 << 17) | // CLKS = 0 ,使用11clock轉(zhuǎn)換
- (1 << 21) | // PDN = 1 , 正常工作模式(非掉電轉(zhuǎn)換模式)
- (0 << 22) | // TEST1:0 = 00 ,正常工作模式(非測試模式)
- (1 << 24) | // START = 1 ,直接啟動ADC轉(zhuǎn)換
- (0 << 27); // EDGE = 0 (CAP/MAT引腳下降沿觸發(fā)ADC轉(zhuǎn)換)
- delay(10);
- ADC_Data = ADDR; // 讀取ADC結(jié)果,并清除DONE標(biāo)志位
-
- while(1)
- {
- ADCR = (ADCR&0x00FFFF00)|0x01|(1 << 24); // 設(shè)置通道1,并進(jìn)行第一次轉(zhuǎn)換
- while( (ADDR&0x80000000)==0 ); // 等待轉(zhuǎn)換結(jié)束
- ADCR = ADCR | (1 << 24); // 再次啟運轉(zhuǎn)換
- while( (ADDR&0x80000000)==0 ); // 等待轉(zhuǎn)換結(jié)束
- ADC_Data = ADDR; // 讀取ADC結(jié)果
- ADC_Data = (ADC_Data>>6) & 0x3FF; // 提取AD轉(zhuǎn)換值
- ADC_Data = ADC_Data * 100/1024; // 數(shù)值轉(zhuǎn)換
- data=ADC_Data;
-
- return(data);
- }
- }
- void PWM0(void)
- { IO0DIR=1<<23|1<<8;
- IO0SET=1<<23;
-
-
- PWMMR0=Fpclk/2.5; //設(shè)置PWM周期
- PWMMR4=0; //設(shè)置PWM占空比
- PWMLER=0x11;
- }
- void PWM1(void)
- { IO0DIR=1<<23|1<<8;
- IO0CLR=1<<23;
- PWMMR0=Fpclk/2.5; //設(shè)置PWM周期
- PWMMR4=Fpclk/50; //設(shè)置PWM占空比
- PWMLER=0x11;
- }
- void PWM2(void)
- { IO0DIR=1<<23|1<<8;
- IO0CLR=1<<23;
-
- PWMMR0=Fpclk/2.5; //設(shè)置PWM周期
- PWMMR4=Fpclk/10; //設(shè)置PWM占空比
- PWMLER=0x11;
- }
- void PWM3(void)
- { IO0DIR=1<<23|1<<8;
- IO0CLR=1<<23;
-
- PWMMR0=Fpclk/2.5; //設(shè)置PWM周期
- PWMMR4=Fpclk/5; //設(shè)置PWM占空比
- PWMLER=0x11;
- }
- void PWM4(void)
- { IO0DIR=1<<23|1<<8;
- IO0CLR=1<<23;
- PWMMR0=Fpclk/2.5; //設(shè)置PWM周期
- PWMMR4=Fpclk/3.3; //設(shè)置PWM占空比
- PWMLER=0x11;
- }
- void PWM5(void)
- { IO0DIR=1<<23|1<<8;
- IO0CLR=1<<23;
- PWMMR0=Fpclk/2.5; //設(shè)置PWM周期
- PWMMR4=Fpclk/2.49; //設(shè)置PWM占空比
- PWMLER=0x11;
- }
- void fuzzy(void)
- {
- uint8 U;
-
- uint8 setlevel;
- fp32 nowlevelc;
- IO0DIR=1<<23;
- while(1)
- { if((IO0PIN&0x00300000)!=0x00300000)
- delay(10);
- if((IO0PIN&0x00300000)!=0x00300000)
- {
- if((IO0PIN&0x00300000)==0x00200000)
- temp++;
- if((IO0PIN&0x00300000)==0x00100000)
- temp--;
- while((IO0PIN&0x00300000)!=0x00300000);
- ShowInt(0xc6,temp);
- }
-
-
-
- setlevel=temp;
- nowlevelc=AD_Convert();
- etemp=nowlevelc-setlevel;
- ectemp=10*(nowlevelc-prelevel);
- prelevel=nowlevelc;
-
-
- if(etemp>=5){e=5*ke+10; }
- else if(etemp<=-5){e=-5*ke+10;}
- else {e=etemp*ke+10;}
- if(ectemp>=2) {ec=2*kec+5;}
- else if(ectemp<=-2) {ec=-2*kec+5;}
- else
- {
- if(ectemp<=-1.5){ec=-2*kec+5;}
- else if(ectemp>-1.5 && ectemp<=-0.5) {ec=-1*kec+5;}
- else if(ectemp>-0.5 && ectemp<=0.5){ec=5;}
- else if(ectemp>0.5 && ectemp<1.5) {ec=kec+5;}
- else {ec=2*kec+5;}
- }
-
- U=fuzzycode[e][ec];
-
- if (U==0){PWM0();}
- if (U==1){PWM1();}
- if (U==2){PWM2();}
- if (U==3){PWM3();}
- if (U==4){PWM4();}
- if (U==5){PWM5();}
-
- }
- }
復(fù)制代碼
|
|