找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 5037|回復(fù): 2
收起左側(cè)

LPC2124單片機(jī)溫度模糊控制系統(tǒng)源代碼及Proteus仿真

[復(fù)制鏈接]
ID:137190 發(fā)表于 2016-9-5 13:31 | 顯示全部樓層 |閱讀模式
0.png 0.png
仿真及程序下載: LPC2124的溫度模糊控制系統(tǒng)Proteus仿真 源代碼.rar (158.51 KB, 下載次數(shù): 86)

下面是部分源代碼預(yù)覽:
  1. /****************************************************************************
  2. * File: main.c
  3. * 功能:向LCD輸出計(jì)數(shù)值
  4. ****************************************************************************/
  5. #include  "config.h"

  6. #define rs (1<<9)
  7. #define rw (1<<10)
  8. #define en (1<<11)
  9. #define busy (1<<7)       
  10. #define ke 2
  11. #define kec 2.5


  12. uint8 e,ec;
  13. fp32 ectemp,prelevel,etemp;
  14. uint8 temp=0;

  15. uint8 fuzzycode[21][11]=
  16. {
  17. {5,5,5,5,5,5,4,3,2,1,1},
  18. {5,5,5,5,5,5,4,2,2,1,1},
  19. {5,5,5,5,5,5,4,2,2,1,1},
  20. {5,5,5,5,5,5,4,2,1,1,1},
  21. {5,5,5,5,5,5,4,2,1,1,1},
  22. {5,5,5,5,5,5,4,2,1,1,1},
  23. {5,5,5,4,4,4,3,2,1,1,1},
  24. {5,5,5,4,4,4,3,2,1,1,1},
  25. {5,5,4,4,4,3,2,2,1,0,0},
  26. {5,5,4,4,3,2,1,1,1,0,0},
  27. {4,4,3,3,2,1,1,1,0,0,0},
  28. {3,3,2,2,1,1,1,0,0,0,0},
  29. {2,2,2,2,1,1,1,0,0,0,0},
  30. {2,2,2,1,1,0,0,0,0,0,0},
  31. {2,2,2,1,1,0,0,0,0,0,0},
  32. {1,1,1,1,1,0,0,0,0,0,0},
  33. {1,1,1,1,1,0,0,0,0,0,0},
  34. {1,1,1,1,1,0,0,0,0,0,0},
  35. {1,1,1,1,1,0,0,0,0,0,0},
  36. {1,1,1,1,1,0,0,0,0,0,0},
  37. {1,1,1,1,1,0,0,0,0,0,0}
  38. };


  39. uint8 BCD[7];                        //十位二進(jìn)制的顯示碼分別是千百十個(gè)位的顯示
  40. uint32 ADC_Data;

  41. void ShowInt(uint8 addr,uint16 num);
  42. void ShowByte(uint8 addr,uint16 num);
  43. uint32 AD_Convert(void) ;       

  44. void fuzzy(void);
  45. void PWM0(void);
  46. void PWM1(void);
  47. void PWM2(void);
  48. void PWM3(void);
  49. void PWM4(void);
  50. void PWM5(void);
  51. /****************************************************************************
  52. * File: main()
  53. * 功能:顯示計(jì)數(shù)值
  54. ****************************************************************************/
  55. int  main(void)
  56. {
  57.     PINSEL0=0x00020000;
  58.     PINSEL1=0x00000000;   
  59.         IO0DIR=0x00cfffff;                //設(shè)置為輸出
  60.         IO0CLR=0xeff;
  61.         TargetInit();       
  62.                           
  63.     ShowByte(0x80,0);
  64.     ShowByte(0xc0,0);
  65.                   
  66.         fuzzy();
  67.                
  68.         return(0);
  69. }



  70. /****************************************************************************
  71. * File:delay()
  72. * 功能:延時(shí)
  73. ****************************************************************************/
  74. void  delay(uint32  dly)
  75. {  uint32  i;

  76.    for(; dly>0; dly--)
  77.       for(i=0; i<500; i++);
  78. }

  79. /****************************************************************************
  80. * File:timer0_init
  81. * 功能:定時(shí)器0初始化
  82. ****************************************************************************/
  83. void timer0_init(void)
  84. {//定時(shí)器計(jì)數(shù)器0設(shè)置,晶振為12M,1秒要運(yùn)行1000000個(gè)周期,
  85.         T0PR=0;                //預(yù)分頻寄存器
  86.         T0MR0=Fpclk/20;                //匹配值
  87.         T0MCR=0x00000003;                //開(kāi)放匹配0中斷
  88.         T0TCR=0x00000003;                //T0PC和T0TC復(fù)位
  89.         T0TCR=0x00000001;                //T0PC和T0TC復(fù)位
  90. }
  91. void timer1_init(void)
  92. {//定時(shí)器計(jì)數(shù)器0設(shè)置,晶振為12M,1秒要運(yùn)行1000000個(gè)周期,
  93.         T1PR=0;                //預(yù)分頻寄存器
  94.         T1MR0=Fpclk/20;                //匹配值
  95.         T1MCR=0x00000003;                //開(kāi)放匹配0中斷
  96.         T1TCR=0x00000003;                //T0PC和T0TC復(fù)位
  97.         T1TCR=0x00000001;                //T0PC和T0TC復(fù)位
  98. }
  99. /****************************************************************************
  100. * File:timerInt
  101. * 功能:中斷處理程序
  102. ****************************************************************************/


  103. void __irq timer0Int(void)
  104. {   uint32 d;
  105.     d=AD_Convert();
  106.     ShowInt(0x86,d);
  107.            
  108.         VICVectAddr=0;
  109.         T0IR=0x00000001;  
  110. }
  111. void __irq timer1Int(void)
  112. {      
  113.         fuzzy();
  114.        
  115.         VICVectAddr=0;
  116.         T0IR=0x00000001;  
  117. }
  118. /****************************************************************************
  119. * File:int_init()
  120. * 功能:中斷初始化
  121. ****************************************************************************/
  122. void int_init(void)
  123. {   
  124.         VICIntSelect=0x00000000;
  125.         VICIntEnable=0x00000030;
  126.         VICVectCntl0=0x00000024;
  127.         VICVectAddr0=(int)timer0Int;
  128.         VICVectCntl1=0x00000025;
  129.         VICVectAddr1=(int)timer1Int;   
  130.    
  131.        
  132. }

  133. /****************************************************************************
  134. * 名稱:ChkBusy()
  135. * 功能:檢查總線是否忙
  136. ****************************************************************************/
  137. void ChkBusy()
  138. {
  139.         IO0DIR=0xe00;
  140.         while(1)
  141.         {
  142.                 IO0CLR=rs;
  143.                 IO0SET=rw;
  144.                 IO0SET=en;
  145.                 if(!(IO0PIN & busy))break;
  146.                 IO0CLR=en;
  147.         }
  148.         IO0DIR=0xeff;
  149. }
  150. /****************************************************************************
  151. * 名稱:WrOp()
  152. * 功能:寫(xiě)函數(shù)
  153. ****************************************************************************/
  154. void WrOp(uint8 dat)
  155. {
  156.         ChkBusy();
  157.         IO0CLR=rs;                //全部清零
  158.         IO0CLR=rw;
  159.         IO0CLR=0xff;                //先清零
  160.         IO0SET=dat;                //再送數(shù)
  161.         IO0SET=en;
  162.         IO0CLR=en;
  163. }
  164. /****************************************************************************
  165. * 名稱:WrDat()
  166. * 功能:寫(xiě)數(shù)據(jù)函數(shù)
  167. ****************************************************************************/
  168. void WrDat(uint8 dat)       
  169. {
  170.         ChkBusy();
  171.         IO0SET=rs;
  172.         IO0CLR=rw;
  173.         IO0CLR=0xff;                //先清零
  174.         IO0SET=dat;                //再送數(shù)
  175.         IO0SET=en;
  176.         IO0CLR=en;
  177. }
  178. /****************************************************************************
  179. * 名稱:lcd_init()
  180. * 功能:lcd初始化函數(shù)
  181. ****************************************************************************/
  182. void lcd_init(void)
  183. {
  184.         WrOp(0x38);                       
  185.         WrOp(0x06);                        //光標(biāo)加1
  186.         WrOp(0x0c);                        //開(kāi)顯示
  187. }
  188. /****************************************************************************
  189. * 名稱:DisText()
  190. * 功能:顯示文本函數(shù)
  191. ****************************************************************************/
  192. void DisText(uint8 addr,uint8 *p)
  193. {
  194.         WrOp(addr);
  195.         while(*p !='\0')WrDat(*(p++));
  196. }

  197. /****************************************************************************
  198. * 名稱:DisInt()
  199. * 功能:顯示文本函數(shù)
  200. ****************************************************************************/

  201. void ShowInt(uint8 addr,uint16 num)                        //在addr處顯示數(shù)字num
  202. {//將num轉(zhuǎn)化成五個(gè)BCD碼存放在全局?jǐn)?shù)組BCD[5]中
  203.         uint8 i;
  204.        
  205.         for(i=5;i>0;i--)       //將NUM數(shù)據(jù)轉(zhuǎn)化成ASCII碼,如521會(huì)轉(zhuǎn)化為00521
  206.         {
  207.                  BCD[i-1]=(uint8)(num%10+0x30);     //取出最低位
  208.                  num/=10;                           //去掉最低位
  209.     }
  210.     i=0;
  211.         while(BCD[i] ==0x30 && i<4) BCD[i++]=' ';    //NUM轉(zhuǎn)換成數(shù)組存放,沒(méi)有加上小數(shù)點(diǎn)
  212.         BCD[5]='\0';
  213.        
  214.          
  215.         DisText(addr,BCD);
  216. }
  217. void ShowByte(uint8 addr,uint16 num)                        //在addr處顯示數(shù)字num
  218. {//將num轉(zhuǎn)化成五個(gè)BCD碼存放在全局?jǐn)?shù)組BCD[5]中
  219.        
  220.         uint8  str1[]="MeasT:";
  221.         uint8  str2[]="SetT:";
  222.         if (addr==0x80){DisText(addr,str1);}
  223.         if (addr==0xc0){DisText(addr,str2);}  
  224.        
  225. }



  226. uint32 AD_Convert(void)
  227. {  
  228.    uint32 data;
  229.    
  230.    
  231.     // 進(jìn)行ADC模塊設(shè)置,其中x<<n表示第n位設(shè)置為x(若x超過(guò)一位,則向高位順延)
  232.     ADCR = (1 << 0)                     |                // SEL = 1 ,選擇通道0
  233.            ((Fpclk / 1000000 - 1) << 8) |                 // CLKDIV = Fpclk / 1000000 - 1 ,即轉(zhuǎn)換時(shí)鐘為1MHz
  234.            (0 << 16)                    |                // BURST = 0 ,軟件控制轉(zhuǎn)換操作
  235.            (0 << 17)                    |                 // CLKS = 0 ,使用11clock轉(zhuǎn)換
  236.            (1 << 21)                    |                 // PDN = 1 , 正常工作模式(非掉電轉(zhuǎn)換模式)
  237.            (0 << 22)                    |                 // TEST1:0 = 00 ,正常工作模式(非測(cè)試模式)
  238.            (1 << 24)                    |                 // START = 1 ,直接啟動(dòng)ADC轉(zhuǎn)換
  239.            (0 << 27);                                                        // EDGE = 0 (CAP/MAT引腳下降沿觸發(fā)ADC轉(zhuǎn)換)
  240.     delay(10);                                                               
  241.     ADC_Data = ADDR;                                                        // 讀取ADC結(jié)果,并清除DONE標(biāo)志位
  242.    
  243.     while(1)
  244.     {  
  245.         ADCR = (ADCR&0x00FFFF00)|0x01|(1 << 24);        // 設(shè)置通道1,并進(jìn)行第一次轉(zhuǎn)換
  246.         while( (ADDR&0x80000000)==0 );                    // 等待轉(zhuǎn)換結(jié)束
  247.         ADCR = ADCR | (1 << 24);                                        // 再次啟運(yùn)轉(zhuǎn)換
  248.         while( (ADDR&0x80000000)==0 );              // 等待轉(zhuǎn)換結(jié)束
  249.         ADC_Data = ADDR;                                                        // 讀取ADC結(jié)果
  250.         ADC_Data = (ADC_Data>>6) & 0x3FF;           // 提取AD轉(zhuǎn)換值
  251.         ADC_Data = ADC_Data * 100/1024;                 // 數(shù)值轉(zhuǎn)換
  252.        data=ADC_Data;
  253.       
  254.           return(data);
  255.     }

  256. }
  257. void PWM0(void)
  258. {  IO0DIR=1<<23|1<<8;
  259.     IO0SET=1<<23;
  260.          
  261.          
  262.           PWMMR0=Fpclk/2.5;                      //設(shè)置PWM周期
  263.           PWMMR4=0;                      //設(shè)置PWM占空比
  264.           PWMLER=0x11;
  265. }
  266. void PWM1(void)
  267. {   IO0DIR=1<<23|1<<8;
  268.       IO0CLR=1<<23;   
  269.           PWMMR0=Fpclk/2.5;                      //設(shè)置PWM周期
  270.           PWMMR4=Fpclk/50;                      //設(shè)置PWM占空比
  271.           PWMLER=0x11;
  272. }
  273. void PWM2(void)
  274. {   IO0DIR=1<<23|1<<8;
  275. IO0CLR=1<<23;
  276.       
  277.           PWMMR0=Fpclk/2.5;                      //設(shè)置PWM周期
  278.           PWMMR4=Fpclk/10;                      //設(shè)置PWM占空比
  279.           PWMLER=0x11;
  280.          }
  281.   void PWM3(void)
  282. {  IO0DIR=1<<23|1<<8;
  283.   IO0CLR=1<<23;
  284.       
  285.           PWMMR0=Fpclk/2.5;                      //設(shè)置PWM周期
  286.           PWMMR4=Fpclk/5;                      //設(shè)置PWM占空比
  287.           PWMLER=0x11;
  288.          }
  289. void PWM4(void)
  290. {   IO0DIR=1<<23|1<<8;
  291.        IO0CLR=1<<23;
  292.           PWMMR0=Fpclk/2.5;                      //設(shè)置PWM周期
  293.           PWMMR4=Fpclk/3.3;                      //設(shè)置PWM占空比
  294.           PWMLER=0x11;
  295.          }
  296. void PWM5(void)
  297. {  IO0DIR=1<<23|1<<8;
  298. IO0CLR=1<<23;
  299.           PWMMR0=Fpclk/2.5;                      //設(shè)置PWM周期
  300.           PWMMR4=Fpclk/2.49;                      //設(shè)置PWM占空比
  301.           PWMLER=0x11;
  302. }


  303. void fuzzy(void)
  304. {
  305.    uint8 U;
  306.   
  307.      uint8 setlevel;
  308.      fp32 nowlevelc;
  309. IO0DIR=1<<23;
  310.   while(1)
  311.      {  if((IO0PIN&0x00300000)!=0x00300000)
  312.                 delay(10);
  313.                 if((IO0PIN&0x00300000)!=0x00300000)
  314.                         {
  315.                         if((IO0PIN&0x00300000)==0x00200000)
  316.                                 temp++;                               
  317.                         if((IO0PIN&0x00300000)==0x00100000)
  318.                                 temp--;
  319.                  while((IO0PIN&0x00300000)!=0x00300000);
  320.         ShowInt(0xc6,temp);               
  321.                 }         

  322.                
  323.    
  324.     setlevel=temp;
  325.     nowlevelc=AD_Convert();
  326.     etemp=nowlevelc-setlevel;            
  327.     ectemp=10*(nowlevelc-prelevel);
  328.     prelevel=nowlevelc;


  329. if(etemp>=5){e=5*ke+10; }
  330. else if(etemp<=-5){e=-5*ke+10;}
  331. else  {e=etemp*ke+10;}
  332. if(ectemp>=2) {ec=2*kec+5;}
  333. else if(ectemp<=-2)  {ec=-2*kec+5;}
  334. else
  335.    {
  336.     if(ectemp<=-1.5){ec=-2*kec+5;}
  337.     else if(ectemp>-1.5 && ectemp<=-0.5) {ec=-1*kec+5;}
  338.         else if(ectemp>-0.5 && ectemp<=0.5){ec=5;}
  339.     else if(ectemp>0.5 && ectemp<1.5) {ec=kec+5;}
  340.         else  {ec=2*kec+5;}
  341.    }
  342.   
  343.     U=fuzzycode[e][ec];
  344.    
  345.     if (U==0){PWM0();}
  346.     if (U==1){PWM1();}
  347.     if (U==2){PWM2();}
  348.     if (U==3){PWM3();}
  349.     if (U==4){PWM4();}
  350.     if (U==5){PWM5();}
  351.    
  352.   }
  353. }
復(fù)制代碼




相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

ID:206437 發(fā)表于 2017-6-5 15:52 | 顯示全部樓層
這是幾階的傳遞函數(shù)
回復(fù)

使用道具 舉報(bào)

ID:229057 發(fā)表于 2017-8-23 23:55 | 顯示全部樓層
東西看起來(lái)非常不錯(cuò)
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表