标题:
LPC2124单片机温度模糊控制系统源代码及Proteus仿真
[打印本页]
作者:
51黑ff
时间:
2016-9-5 13:31
标题:
LPC2124单片机温度模糊控制系统源代码及Proteus仿真
0.png
(33.97 KB, 下载次数: 171)
下载附件
2016-9-5 13:29 上传
0.png
(74.73 KB, 下载次数: 175)
下载附件
2016-9-5 13:30 上传
仿真及程序下载:
LPC2124的温度模糊控制系统Proteus仿真 源代码.rar
(158.51 KB, 下载次数: 86)
2016-9-5 13:31 上传
点击文件名下载附件
下载积分: 黑币 -5
下面是部分源代码预览:
/****************************************************************************
* 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();}
}
}
复制代码
作者:
331165061
时间:
2017-6-5 15:52
这是几阶的传递函数
作者:
654381241
时间:
2017-8-23 23:55
东西看起来非常不错
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1