程序框图:
本设计使用高速晶体振荡器,程序如下: 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.5v ADC12CTL1 = SHP + ADC12SSEL_3; //Use sampling timer, SMCLK for(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-1 return 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 != '\0') { 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); } |