⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 基于LPC2124的温度模糊控制系统设计
💻 C
字号:
/****************************************************************************
* File: main.c
* 功能:向LCD输出计数值
****************************************************************************/
#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];			//十位二进制的显示码分别是千百十个位的显示
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()
* 功能:显示计数值
****************************************************************************/
int  main(void)
{ 
    PINSEL0=0x00020000;
    PINSEL1=0x00000000;   
	IO0DIR=0x00cfffff;		//设置为输出
	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)
{//定时器计数器0设置,晶振为12M,1秒要运行1000000个周期,
	T0PR=0;		//预分频寄存器
	T0MR0=Fpclk/20;		//匹配值
	T0MCR=0x00000003;		//开放匹配0中断
	T0TCR=0x00000003;		//T0PC和T0TC复位
	T0TCR=0x00000001;		//T0PC和T0TC复位
}
void timer1_init(void)
{//定时器计数器0设置,晶振为12M,1秒要运行1000000个周期,
	T1PR=0;		//预分频寄存器
	T1MR0=Fpclk/20;		//匹配值
	T1MCR=0x00000003;		//开放匹配0中断
	T1TCR=0x00000003;		//T0PC和T0TC复位
	T1TCR=0x00000001;		//T0PC和T0TC复位
}
/****************************************************************************
* 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()
* 功能:写函数
****************************************************************************/
void WrOp(uint8 dat)
{
	ChkBusy();
	IO0CLR=rs;		//全部清零
	IO0CLR=rw;
	IO0CLR=0xff;		//先清零
	IO0SET=dat;		//再送数
	IO0SET=en;
	IO0CLR=en;
}
/****************************************************************************
* 名称:WrDat()
* 功能:写数据函数
****************************************************************************/
void WrDat(uint8 dat)	
{
	ChkBusy();
	IO0SET=rs;
	IO0CLR=rw;
	IO0CLR=0xff;		//先清零
	IO0SET=dat;		//再送数
	IO0SET=en;
	IO0CLR=en;
}
/****************************************************************************
* 名称:lcd_init()
* 功能:lcd初始化函数
****************************************************************************/
void lcd_init(void)
{
	WrOp(0x38);			
	WrOp(0x06);			//光标加1
	WrOp(0x0c);			//开显示
}
/****************************************************************************
* 名称:DisText()
* 功能:显示文本函数
****************************************************************************/
void DisText(uint8 addr,uint8 *p)
{
	WrOp(addr);
	while(*p !='\0')WrDat(*(p++));
}

/****************************************************************************
* 名称:DisInt()
* 功能:显示文本函数
****************************************************************************/

void ShowInt(uint8 addr,uint16 num)			//在addr处显示数字num
{//将num转化成五个BCD码存放在全局数组BCD[5]中
	uint8 i;
	
	for(i=5;i>0;i--)       //将NUM数据转化成ASCII码,如521会转化为00521
	{
       	  BCD[i-1]=(uint8)(num%10+0x30);     //取出最低位
       	  num/=10;                           //去掉最低位
    }
    i=0;
	while(BCD[i] ==0x30 && i<4) BCD[i++]=' ';    //NUM转换成数组存放,没有加上小数点
	BCD[5]='\0';
	
	 
	DisText(addr,BCD);
}
void ShowByte(uint8 addr,uint16 num)			//在addr处显示数字num
{//将num转化成五个BCD码存放在全局数组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;
   
   
    // 进行ADC模块设置,其中x<<n表示第n位设置为x(若x超过一位,则向高位顺延)
    ADCR = (1 << 0)                     |		// SEL = 1 ,选择通道0
           ((Fpclk / 1000000 - 1) << 8) | 		// CLKDIV = Fpclk / 1000000 - 1 ,即转换时钟为1MHz
           (0 << 16)                    |		// BURST = 0 ,软件控制转换操作
           (0 << 17)                    | 		// CLKS = 0 ,使用11clock转换
           (1 << 21)                    | 		// PDN = 1 , 正常工作模式(非掉电转换模式)
           (0 << 22)                    | 		// TEST1:0 = 00 ,正常工作模式(非测试模式)
           (1 << 24)                    | 		// START = 1 ,直接启动ADC转换
           (0 << 27);							// EDGE = 0 (CAP/MAT引脚下降沿触发ADC转换)
    delay(10);								
    ADC_Data = ADDR;							// 读取ADC结果,并清除DONE标志位
   
    while(1)
    {  
        ADCR = (ADCR&0x00FFFF00)|0x01|(1 << 24);	// 设置通道1,并进行第一次转换
        while( (ADDR&0x80000000)==0 );	            // 等待转换结束
        ADCR = ADCR | (1 << 24);					// 再次启运转换
        while( (ADDR&0x80000000)==0 );              // 等待转换结束
        ADC_Data = ADDR;							// 读取ADC结果
        ADC_Data = (ADC_Data>>6) & 0x3FF;           // 提取AD转换值
        ADC_Data = ADC_Data * 100/1024;                 // 数值转换
       data=ADC_Data;
       
	  return(data); 
    }

}
void PWM0(void)
{  IO0DIR=1<<23|1<<8;
    IO0SET=1<<23;
          
          
          PWMMR0=Fpclk/2.5;                      //设置PWM周期
          PWMMR4=0;                      //设置PWM占空比
          PWMLER=0x11;
 }
void PWM1(void)
{   IO0DIR=1<<23|1<<8;
      IO0CLR=1<<23;    
          PWMMR0=Fpclk/2.5;                      //设置PWM周期
          PWMMR4=Fpclk/50;                      //设置PWM占空比
          PWMLER=0x11;
} 
void PWM2(void)
{   IO0DIR=1<<23|1<<8;
IO0CLR=1<<23;
      
          PWMMR0=Fpclk/2.5;                      //设置PWM周期
          PWMMR4=Fpclk/10;                      //设置PWM占空比
          PWMLER=0x11;
         }
  void PWM3(void)
 {  IO0DIR=1<<23|1<<8;
  IO0CLR=1<<23;
       
          PWMMR0=Fpclk/2.5;                      //设置PWM周期
          PWMMR4=Fpclk/5;                      //设置PWM占空比
          PWMLER=0x11;
         } 
void PWM4(void)
{   IO0DIR=1<<23|1<<8;
       IO0CLR=1<<23;
          PWMMR0=Fpclk/2.5;                      //设置PWM周期
          PWMMR4=Fpclk/3.3;                      //设置PWM占空比
          PWMLER=0x11;
         }
 void PWM5(void)
{  IO0DIR=1<<23|1<<8;
IO0CLR=1<<23;
          PWMMR0=Fpclk/2.5;                      //设置PWM周期
          PWMMR4=Fpclk/2.49;                      //设置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();}
    
  }
}




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -