找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3963|回复: 2
打印 上一主题 下一主题
收起左侧

LPC2124单片机温度模糊控制系统源代码及Proteus仿真

[复制链接]
跳转到指定楼层
楼主

仿真及程序下载: LPC2124的温度模糊控制系统Proteus仿真 源代码.rar (158.51 KB, 下载次数: 85)

下面是部分源代码预览:
  1. /****************************************************************************
  2. * File: main.c
  3. * 功能:向LCD输出计数值
  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];                        //十位二进制的显示码分别是千百十个位的显示
  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. * 功能:显示计数值
  54. ****************************************************************************/
  55. int  main(void)
  56. {
  57.     PINSEL0=0x00020000;
  58.     PINSEL1=0x00000000;   
  59.         IO0DIR=0x00cfffff;                //设置为输出
  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. * 功能:延时
  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. * 功能:定时器0初始化
  82. ****************************************************************************/
  83. void timer0_init(void)
  84. {//定时器计数器0设置,晶振为12M,1秒要运行1000000个周期,
  85.         T0PR=0;                //预分频寄存器
  86.         T0MR0=Fpclk/20;                //匹配值
  87.         T0MCR=0x00000003;                //开放匹配0中断
  88.         T0TCR=0x00000003;                //T0PC和T0TC复位
  89.         T0TCR=0x00000001;                //T0PC和T0TC复位
  90. }
  91. void timer1_init(void)
  92. {//定时器计数器0设置,晶振为12M,1秒要运行1000000个周期,
  93.         T1PR=0;                //预分频寄存器
  94.         T1MR0=Fpclk/20;                //匹配值
  95.         T1MCR=0x00000003;                //开放匹配0中断
  96.         T1TCR=0x00000003;                //T0PC和T0TC复位
  97.         T1TCR=0x00000001;                //T0PC和T0TC复位
  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. * 功能:写函数
  153. ****************************************************************************/
  154. void WrOp(uint8 dat)
  155. {
  156.         ChkBusy();
  157.         IO0CLR=rs;                //全部清零
  158.         IO0CLR=rw;
  159.         IO0CLR=0xff;                //先清零
  160.         IO0SET=dat;                //再送数
  161.         IO0SET=en;
  162.         IO0CLR=en;
  163. }
  164. /****************************************************************************
  165. * 名称:WrDat()
  166. * 功能:写数据函数
  167. ****************************************************************************/
  168. void WrDat(uint8 dat)       
  169. {
  170.         ChkBusy();
  171.         IO0SET=rs;
  172.         IO0CLR=rw;
  173.         IO0CLR=0xff;                //先清零
  174.         IO0SET=dat;                //再送数
  175.         IO0SET=en;
  176.         IO0CLR=en;
  177. }
  178. /****************************************************************************
  179. * 名称:lcd_init()
  180. * 功能:lcd初始化函数
  181. ****************************************************************************/
  182. void lcd_init(void)
  183. {
  184.         WrOp(0x38);                       
  185.         WrOp(0x06);                        //光标加1
  186.         WrOp(0x0c);                        //开显示
  187. }
  188. /****************************************************************************
  189. * 名称:DisText()
  190. * 功能:显示文本函数
  191. ****************************************************************************/
  192. void DisText(uint8 addr,uint8 *p)
  193. {
  194.         WrOp(addr);
  195.         while(*p !='\0')WrDat(*(p++));
  196. }

  197. /****************************************************************************
  198. * 名称:DisInt()
  199. * 功能:显示文本函数
  200. ****************************************************************************/

  201. void ShowInt(uint8 addr,uint16 num)                        //在addr处显示数字num
  202. {//将num转化成五个BCD码存放在全局数组BCD[5]中
  203.         uint8 i;
  204.        
  205.         for(i=5;i>0;i--)       //将NUM数据转化成ASCII码,如521会转化为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转换成数组存放,没有加上小数点
  212.         BCD[5]='\0';
  213.        
  214.          
  215.         DisText(addr,BCD);
  216. }
  217. void ShowByte(uint8 addr,uint16 num)                        //在addr处显示数字num
  218. {//将num转化成五个BCD码存放在全局数组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.     // 进行ADC模块设置,其中x<<n表示第n位设置为x(若x超过一位,则向高位顺延)
  232.     ADCR = (1 << 0)                     |                // SEL = 1 ,选择通道0
  233.            ((Fpclk / 1000000 - 1) << 8) |                 // CLKDIV = Fpclk / 1000000 - 1 ,即转换时钟为1MHz
  234.            (0 << 16)                    |                // BURST = 0 ,软件控制转换操作
  235.            (0 << 17)                    |                 // CLKS = 0 ,使用11clock转换
  236.            (1 << 21)                    |                 // PDN = 1 , 正常工作模式(非掉电转换模式)
  237.            (0 << 22)                    |                 // TEST1:0 = 00 ,正常工作模式(非测试模式)
  238.            (1 << 24)                    |                 // START = 1 ,直接启动ADC转换
  239.            (0 << 27);                                                        // EDGE = 0 (CAP/MAT引脚下降沿触发ADC转换)
  240.     delay(10);                                                               
  241.     ADC_Data = ADDR;                                                        // 读取ADC结果,并清除DONE标志位
  242.    
  243.     while(1)
  244.     {  
  245.         ADCR = (ADCR&0x00FFFF00)|0x01|(1 << 24);        // 设置通道1,并进行第一次转换
  246.         while( (ADDR&0x80000000)==0 );                    // 等待转换结束
  247.         ADCR = ADCR | (1 << 24);                                        // 再次启运转换
  248.         while( (ADDR&0x80000000)==0 );              // 等待转换结束
  249.         ADC_Data = ADDR;                                                        // 读取ADC结果
  250.         ADC_Data = (ADC_Data>>6) & 0x3FF;           // 提取AD转换值
  251.         ADC_Data = ADC_Data * 100/1024;                 // 数值转换
  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;                      //设置PWM周期
  263.           PWMMR4=0;                      //设置PWM占空比
  264.           PWMLER=0x11;
  265. }
  266. void PWM1(void)
  267. {   IO0DIR=1<<23|1<<8;
  268.       IO0CLR=1<<23;   
  269.           PWMMR0=Fpclk/2.5;                      //设置PWM周期
  270.           PWMMR4=Fpclk/50;                      //设置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;                      //设置PWM周期
  278.           PWMMR4=Fpclk/10;                      //设置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;                      //设置PWM周期
  286.           PWMMR4=Fpclk/5;                      //设置PWM占空比
  287.           PWMLER=0x11;
  288.          }
  289. void PWM4(void)
  290. {   IO0DIR=1<<23|1<<8;
  291.        IO0CLR=1<<23;
  292.           PWMMR0=Fpclk/2.5;                      //设置PWM周期
  293.           PWMMR4=Fpclk/3.3;                      //设置PWM占空比
  294.           PWMLER=0x11;
  295.          }
  296. void PWM5(void)
  297. {  IO0DIR=1<<23|1<<8;
  298. IO0CLR=1<<23;
  299.           PWMMR0=Fpclk/2.5;                      //设置PWM周期
  300.           PWMMR4=Fpclk/2.49;                      //设置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. }
复制代码




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:206437 发表于 2017-6-5 15:52 | 只看该作者
这是几阶的传递函数
回复

使用道具 举报

板凳
ID:229057 发表于 2017-8-23 23:55 | 只看该作者
东西看起来非常不错
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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