msp430f149温度pid控制

2019-07-26 18:51发布

程序框图:
图片1.jpg
本设计使用高速晶体振荡器,程序如下:BCSCTL1 &= ~XT2OFF;//打开XT2高频晶体振荡do{   IFG1 &= ~OFIFG;//清除晶振失败标志   for (i = 0xFF; i > 0; i--);//等待8MHz晶体起振 }   while ((IFG1 & OFIFG));//晶振失效标志仍然存在?   BCSCTL2 |= SELM_2 + SELS;//MCLK和SMCLK选择高频晶振PID算法程序:void PIDCalc(void){float Rate;//误差变化率                              Current_Error =   Set_Temp  - Pre_Temp ;// 当前误差计算Sum_Error    +=   Current_Error;// 误差积分Prev_Error    =   Last_Error;// 存储误差更新Last_Error    =   Current_Error;// 存储误差更新Rate          =   ( Current_Error - Last_Error )*1000/ Ctrl_Period;  // 当前误差微分if(Rate>5)//对误差变化率进行限制,锅炉温度不可能变化太大Rate=5;if(Rate<-5)Rate=-5;    P_OUT = P * Gain * Current_Error  ; /*比例项*/I_OUT = I * Gain * Sum_Error  ;/*积分项*/ //积分限幅处理if( I_OUT>PID_I_MAX )  I_OUT = PID_I_MAX;if( I_OUT<PID_I_MIN )  I_OUT = PID_I_MIN;if( ( Current_Error <= 2.5 ) && ( Prev_Error <=2.8)){ I_OUT=I_OUT * 0.5; }if( (Current_Error <= 0.45 ) && ( Last_Error <=55)){ I_OUT=I_OUT * 0.08; } //因为锅炉只能加温不能降温所以一旦超过设定值令积分值为零        if( ( Current_Error <= 0 ) && ( Last_Error <=0 )) {  I_OUT=0;  }          //微分延迟输出处理  D_OUT= ( D_OUT * Sdde_Para + D * Rate * (1-Sdde_Para) )*Gain  ;  PID_OUT =  P_OUT  +  I_OUT  +  D_OUT ;  if ( PID_OUT >= PWM_DATA_MAX )  PID_OUT = PWM_DATA_MAX;  if ( PID_OUT <= PWM_DATA_MIN )  PID_OUT = PWM_DATA_MIN;  if( Set_Temp - Pre_Temp >=10)    PID_OUT=16383;  }void main(){ Device_Init( ); while(1){ LED8_Rollback;//系统运行指示灯 Parameter_Show( ); } }ADC模数转换程序char ADC12Init(char n,char channels[],char rep){ if(n>15)return 0;ADC12CTL0 = ADC12ON + MSC + SHT0_0 + REFON + REF2_5V;// 开启ad,参考电压2.5vADC12CTL1 = SHP + ADC12SSEL_3;  //Use sampling timer, SMCLKfor(int i = 0;i < n;i++){if(channels >= 0x80)return 0;*(char*)(ADC12MCTL0_ + i) = channels;//每个MCTL设置 }*(char*)(ADC12MCTL0_ + n - 1) |= EOS;//序列结束      if(rep != 0)//多次转换{ADC12CTL1 |= CONSEQ_3;}else{ ADC12CTL1 |= CONSEQ_1;}ADC12IE = 1<<(n-1);// Enable ADC12IFG.n-1return 1;}定时器设置程序void TA_Init(void){  TACTL=TASSEL0+TACLR;//设定定时器A控制寄存器  CCTL0=CCIE;//使能中断  CCR0=3276;//设置CCR0初值,及100毫秒中断一次  TACTL|=MC0;//计数器加模式}void TimerB_Init(void){     TBCTL=TBSSEL_1+TBCLR+MC0+ID_3;    TBCCTL1=OUTMOD_3;    TBCCR0=16384;//PWM中断周期    TBCCR1=4000;//PWM低电平时间    P4DIR|=BIT1;//设置PWMIO口    P4SEL|=BIT1;}void TimerB_Duty(u16 duty){    TBCCR1=duty;//PWM低电平时间}异步通讯程序void UART0_Init(void){       WDTCTL = WDTPW + WDTHOLD;// Stop WDT    P3SEL |= 0x30;// P3.4,5 = USART0 TXD/RXD    ME1 |= UTXE0+URXE0;// Enable USART0 TXD/RXD    UCTL0 |= CHAR;// 8-bit character    UTCTL0 |= SSEL0;// UCLK = ACLK    UBR00 = 0x03;// 32k/9600 - 3.41    UBR10 = 0x00;                                 UMCTL0 = 0x4A;// Modulation    UCTL0 &= ~SWRST;// Initialize USART state machine    IE1 |= URXIE0;// 使能USART0的接收中断}void PutChar(uchar data){    while (!(IFG1 & UTXIFG0));// TX缓存空闲?     TXBUF0 = data;// 发送数据}void Blank(void)    {     PutChar(0x20);}void Newline()   {   PutChar(0x0d);//发送一个回车   PutChar(0x0a);//发送一个换行}void PutString(uchar *ptr){   while(*ptr != ''){     PutChar(*ptr++);  }  }温度拟合程序float Scale_Conv( u16 Value){float  Temp1=0,Temp2=0; //温度拟合(二次函数)Temp1=Value*A_para;Temp1=Value*Temp1;Temp2=Value*B_para;//当前温度=A*X*X+B*X+C-零漂return (Temp1+Temp2+C_para+Null_shift);        }
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
尤彼卡
1楼-- · 2019-07-26 22:48
 精彩回答 2  元偷偷看……
dirtwillfly
2楼-- · 2019-07-27 01:48
尤彼卡 发表于 2015-7-29 09:57
这是用于哪方面的,有没原理图呀,感觉很不错

移植一下都可以用
ruogurencheng
3楼-- · 2019-07-27 06:39
收了
米尔豪斯
4楼-- · 2019-07-27 07:13
PID算法程序值得借鉴,收藏先

一周热门 更多>