|
以下是一個結(jié)合了零點滿度校正、多點線性校正、使用二階低通巴特沃斯濾波器和溫度模糊PID控制的51單片機程序
- #include <reg51.h>
- #define ADC_CS P1_0
- #define ADC_CLK P1_1
- #define ADC_DIN P1_2
- #define ADC_DOUT P1_3
- // 巴特沃斯濾波器參數(shù)
- float b0 = 0.0025; // b0系數(shù)
- float b1 = 0.005; // b1系數(shù)
- float b2 = 0.0025; // b2系數(shù)
- float a1 = -1.8227; // a1系數(shù)
- float a2 = 0.8316; // a2系數(shù)
- // 狀態(tài)變量
- float x[2] = {0.0, 0.0}; // 巴特沃斯濾波器輸入狀態(tài)變量
- float y[2] = {0.0, 0.0}; // 巴特沃斯濾波器輸出狀態(tài)變量
- // PID控制參數(shù)
- float kp = 0.0; // 比例系數(shù)
- float ki = 0.0; // 積分系數(shù)
- float kd = 0.0; // 微分系數(shù)
- // 模糊PID控制參數(shù)
- float e_last = 0.0; // 上一次誤差
- float ec[3] = {0.0, 0.0, 0.0}; // 誤差變化率數(shù)組
- float u[3] = {0.0, 0.0, 0.0}; // 控制量變化率數(shù)組
- float u_out = 0.0; // 控制量輸出
- // 延時函數(shù)
- void delay(unsigned int n)
- {
- unsigned int i;
- while (n--)
- {
- for (i = 0; i < 1000; i++);
- }
- }
- // 發(fā)送24位指令并讀取16位數(shù)據(jù)
- unsigned int adc_read(void)
- {
- unsigned char i;
- unsigned int data = 0;
- // 發(fā)送指令
- ADC_CS = 0;
- ADC_CLK = 0;
- ADC_DIN = 1;
- delay(1);
- ADC_CLK = 1;
- delay(1);
- ADC_CLK = 0;
- delay(1);
- ADC_DIN = 1;
- delay(1);
- ADC_CLK = 1;
- delay(1);
- ADC_CLK = 0;
- delay(1);
- // 讀取數(shù)據(jù)
- for (i = 0; i < 24; i++)
- {
- if (i < 16)
- {
- data <<= 1;
- ADC_CLK = 1;
- delay(1);
- ADC_CLK = 0;
- delay(1);
- data |= ADC_DOUT;
- delay(1);
- }
- else
- {
- ADC_DIN = 0;
- ADC_CLK = 1;
- delay(1);
- ADC_CLK = 0;
- delay(1);
- ADC_DIN = 1;
- delay(1);
- }
- }
- ADC_CS = 1;
- return data;
- }
- // 零點滿度校正
- void adc_zero_full_calibration(void)
- {
- unsigned int zero_code, full_code;
- // 獲取零點碼值
- ADC_CS = 0;
- delay(1);
- zero_code = adc_read();
- ADC_CS = 1;
- // 獲取滿量程碼值
- ADC_CS = 0;
- delay(1);
- full_code = adc_read();
- ADC_CS = 1;
- // 計算比例和偏移
- float k = 4096.0 / (full_code - zero_code); // 計算比例系數(shù)
- float b = -zero_code * k; // 計算偏移量
- }
- // 多點線性校正
- void adc_multi_point_calibration(void)
- {
- unsigned char i;
- unsigned int code[5] = {0x0000, 0x1000, 0x2000, 0x3000, 0x4000};
- float volt[5] = {0.0, 1.0, 2.0, 3.0, 4.0};
- float k[4], b[4];
- for (i = 0; i < 4; i++)
- {
- k[i] = (volt[i + 1].volt[i]) / (code[i + 1] - code[i]); // 計算比例系數(shù) b[i] = volt[i] - k[i] * code[i]; // 計算偏移量 } }
- // 將電壓轉(zhuǎn)換為溫度,根據(jù)具體傳感器進行修改
- float voltage_to_temperature(float voltage)
- {
- float temperature = (voltage - 0.5) * 100; // 線性轉(zhuǎn)換
- return temperature;
- }
- // 二階低通巴特沃斯濾波器
- float butterworth_filter(float input)
- {
- float output = b0 * input + b1 * x[0] + b2 * x[1] - a1 * y[0] - a2 * y[1]; // 計算輸出值
- // 更新狀態(tài)變量
- x[1] = x[0]; // 將當前輸入值保存到x[1]中,用于下一次迭代時計算b1
- x[0] = input; // 用當前輸入值更新x[0]
- y[1] = y[0]; // 將當前輸出值保存到y(tǒng)[1]中,用于下一次迭代時計算a1
- y[0] = output; // 用當前輸出值更新y[0]
- return output;
- }
- // 模糊PID控制函數(shù)
- float fuzzy_pid_control(float setpoint, float process_value)
- {
- float e = setpoint - process_value; // 計算誤差
- float ec_now = e - e_last; // 計算當前誤差變化率
- // 計算當前權(quán)重
- float w_e = 0.5; // 誤差權(quán)重
- float w_ec = 0.3; // 誤差變化率權(quán)重
- float w_u = 0.2; // 控制量變化率權(quán)重
- // 計算模糊控制量
- ec[2] = ec[1]; ec[1] = ec[0]; ec[0] = ec_now; // 更新誤差變化率數(shù)組
- u[2] = u[1]; u[1] = u[0]; // 更新控制量變化率數(shù)組
- u[0] = kp * (w_e * e + w_ec * (ec_now + ec[1] + ec[2]) + w_u * (u[1] + u[2])) + // 計算P項
- ki * (w_e * e + w_ec * ec_now + w_u * u[0]) + // 計算I項
- kd * (w_e * e + w_ec * (ec_now - ec[1]) + w_u * (u[0] - u[1])); // 計算D項
- // 更新上一次誤差
- e_last = e;
- // 輸出控制量
- return u_out;
- }
- void main()
- {
- float setpoint = 25.0; // 設定溫度
- // 零點滿度校正
- adc_zero_full_calibration();
- // 多點線性校正
- adc_multi_point_calibration();
- while (1)
- {
- // 抗干擾濾波 --> 巴特沃斯濾波器
- unsigned int adc_result = adc_read(); // 獲取ADC采樣值
- float voltage = (float)adc_result * k + b; // 轉(zhuǎn)換為電壓
- float temperature = voltage_to_temperature(voltage); // 將電壓轉(zhuǎn)換為溫度
- float filtered_temp = butterworth_filter(temperature); // 進行抗干擾濾波
- // 模糊PID控制
- float output = fuzzy_pid_control(setpoint, filtered_temp);
- // 輸出控制信號
- // TODO: your code here
- }
- }
復制代碼
該程序基于51單片機,使用巴特沃斯濾波器對采集到的溫度數(shù)據(jù)進行抗干擾濾波,并使用模糊PID控制算法來實現(xiàn)溫度控制。
在主函數(shù)中,我們首先進行了零點滿度校正和多點線性
2023/4/22 11:11:34
繼續(xù)
2023/4/22 11:12:00
校正,以提高ADC采樣值的精度。在校正之后,程序進入了一個死循環(huán)中,不斷地從ADC獲取溫度采樣值,并進行濾波和控制。
抗干擾濾波部分使用了二階低通巴特沃斯濾波器。該濾波器有五個參數(shù):b0、b1、b2、a1、a2。其中,b0、b1、b2是濾波器輸入狀態(tài)變量與輸出狀態(tài)變量的系數(shù),a1、a2是濾波器輸出狀態(tài)變量的系數(shù)。這些系數(shù)可以根據(jù)具體的要求進行調(diào)整,以達到不同的濾波效果。
模糊PID控制部分使用了模糊邏輯來處理誤差、誤差變化率和控制量變化率,以計算出控制量。該算法有四個參數(shù):kp、ki、kd、w_e、w_ec、w_u。其中,kp、ki、kd是比例、積分、微分系數(shù),w_e、w_ec、w_u是三個變量的權(quán)重系數(shù)。這些參數(shù)可以根據(jù)具體的需要進行調(diào)整,以達到更好的控制效果。
最后,程序通過輸出控制信號實現(xiàn)對溫度的控制。需要注意的是,在實際應用中,我們需要將控制信號轉(zhuǎn)換為對應的電氣信號,并控制溫度調(diào)節(jié)器來實現(xiàn)溫度的控制。
|
|