?? pid程序.c
字號:
/***********************************************************************
文件名:PID程序.C
功能: 用PID算法閉環控制BANGK3區DAC0832的輸出電壓,通過設置年想要的輸出
電壓,它通過ADC0804將O832的輸出電壓讀回單片機進行PID自動調節,
并經過短時間將DAC0832的輸出電壓升到設置的電壓
/此程序用的是位置式調節/
作者:測控五組 ¤春暖花★開
日期:2007/4/16/17:16
版本:V1.0
***********************************************************************/
#include <reg51.h>
#include <absacc.h>
#include <string.h>
#include <stdio.h>
#include<math.h>
sbit ADC_INT = P3^2;
code unsigned char Tab[10] ={0x0c0,0x0f9,0x0a4,0x0b0,0x99,0x92,0x82,0x0f8,0x80,0x90};
typedef struct
{
double SetPoint; /* 設定目標 Desired Value */
double Proportion; /* 比例常數 Proportional Const */
double Integral; /* 積分常數 Integral Const */
double Derivative; /* 微分常數 Derivative Const */
double LastError; /* 前一項誤差 */
double PrevError; /* 前第二項誤差 */
double SumError; /* 總誤差 */
} PID;
unsigned char sensor () ; /* 傳感器返回信號數據 **/
void actuator(unsigned char rDelta); /* 執行機構函數 */
void Delay(unsigned char t);
void display(unsigned char rIn);
/****************************************************************************
PID計算部分
****************************************************************************/
double PIDCalc( PID *pp, double NextPoint )
{
double dError,Error;
Error = pp->SetPoint - NextPoint; /* 計算當前偏差 */
pp->SumError += Error; /* 積分《總偏差》*/
dError = pp->LastError - pp->PrevError; /* 當前微分 */
pp->PrevError = pp->LastError;
pp->LastError = Error; /* 三個誤差值移位 */
return(NextPoint+pp->Proportion * Error + pp->Integral * pp->SumError + pp->Derivative * dError ); /*《返回總的誤差值》*/
}
/*******************************************************************************
主函數部分
********************************************************************************/
void main(void)
{
PID sPID; /* 定義PID結構體變量 */
double rOut; /* PID 響應輸出 */
unsigned char rIn; /* PID 反饋 (Input) */
double x;
sPID.Proportion = 0.74; /* 設置 PID 比例系數 */
sPID.Integral = 0.70; /* 設置PID積分系數 */
sPID.Derivative = 0.0; /* 設置PID微分系數 */
sPID.SetPoint = 2.0; /* 設置 PID 輸出值 */
for (;;)
{
unsigned char sumout;
/* PID進入循環檢測狀態中 */
unsigned char i;
rIn = sensor (); /* 讀傳感器輸出 */
for(i=0;i<50;i++)
display(rIn);
x = 5.0 * (double)rIn / 256.0;
rOut = PIDCalc ( &sPID,x ); /* 計算PID 輸出 */
sumout=rOut*256/5;
actuator ( sumout ); /* 將要反饋的數據輸出 */
}
}
/*******************************************************************************
程序名稱:8位并行D/A芯片DAC0832
*********************************************************************************/
void actuator(unsigned char rDelta)
{
XBYTE[0xA000] = rDelta;
Delay(10);
}
/*******************************************************************************
函數:Delay()
功能:延時0.01s~2.56s
參數:t>0時,延時(t*0.01)s
t=0時,延時2.56s
說明:定時10ms的定時器初值=65536-0.01/(1/(f/12)),其中f為晶振頻率
*******************************************************************************/
void Delay(unsigned char t)
{
TMOD &= 0xF0;
TMOD |= 0x01;
EA=1;
EX0=1;
do
{
TH0 = 0xee; /* 設置定時器初值(定時5ms)*/
TL0 = 0x00;
TR0 = 1; /* 啟動定時器 */
while ( !TF0 ); /* 等待定時器溢出 */
TR0 = 0; /* 停止定時器 */
TF0 = 0; /* 清除溢出標志 */
} while ( --t != 0 ); /* 循環t次 */
}
unsigned char sensor (void)
{
unsigned char v;
Delay(30);
XBYTE[0xB000] = 0xFF; /* 啟動A/D轉換 */
Delay(1);
while ( ADC_INT ); /* 等待A/D轉換完畢 */
v = XBYTE[0xB000]; /* 讀取A/D轉換結果 */
return (v);
}
void display(unsigned char rIn)
{
float num;
int N;
num=5.0*rIn/256;
N=(int)(num*1000.0);
XBYTE[0x8000]=0x08;
XBYTE[0x9000]=Tab[N/1000]&0x7f;
Delay(1);
XBYTE[0x8000]=0x04;
XBYTE[0x9000]=Tab[N%1000/100];
Delay(1);
XBYTE[0x8000]=0x02;
XBYTE[0x9000]=Tab[N%100/10];
Delay(1);
XBYTE[0x8000]=0x01;
XBYTE[0x9000]=Tab[N%10];
Delay(1);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -