|
以下是一个结合了零点满度校正、多点线性校正、使用二阶低通巴特沃斯滤波器和温度模糊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
- // 巴特沃斯滤波器参数
- float b0 = 0.0025; // b0系数
- float b1 = 0.005; // b1系数
- float b2 = 0.0025; // b2系数
- float a1 = -1.8227; // a1系数
- float a2 = 0.8316; // a2系数
- // 状态变量
- float x[2] = {0.0, 0.0}; // 巴特沃斯滤波器输入状态变量
- float y[2] = {0.0, 0.0}; // 巴特沃斯滤波器输出状态变量
- // PID控制参数
- float kp = 0.0; // 比例系数
- float ki = 0.0; // 积分系数
- float kd = 0.0; // 微分系数
- // 模糊PID控制参数
- float e_last = 0.0; // 上一次误差
- float ec[3] = {0.0, 0.0, 0.0}; // 误差变化率数组
- float u[3] = {0.0, 0.0, 0.0}; // 控制量变化率数组
- float u_out = 0.0; // 控制量输出
- // 延时函数
- void delay(unsigned int n)
- {
- unsigned int i;
- while (n--)
- {
- for (i = 0; i < 1000; i++);
- }
- }
- // 发送24位指令并读取16位数据
- unsigned int adc_read(void)
- {
- unsigned char i;
- unsigned int data = 0;
- // 发送指令
- 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);
- // 读取数据
- 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); // 计算比例系数
- 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]); // 计算比例系数 b[i] = volt[i] - k[i] * code[i]; // 计算偏移量 } }
- // 将电压转换为温度,根据具体传感器进行修改
- float voltage_to_temperature(float voltage)
- {
- float temperature = (voltage - 0.5) * 100; // 线性转换
- return temperature;
- }
- // 二阶低通巴特沃斯滤波器
- float butterworth_filter(float input)
- {
- float output = b0 * input + b1 * x[0] + b2 * x[1] - a1 * y[0] - a2 * y[1]; // 计算输出值
- // 更新状态变量
- x[1] = x[0]; // 将当前输入值保存到x[1]中,用于下一次迭代时计算b1
- x[0] = input; // 用当前输入值更新x[0]
- y[1] = y[0]; // 将当前输出值保存到y[1]中,用于下一次迭代时计算a1
- y[0] = output; // 用当前输出值更新y[0]
- return output;
- }
- // 模糊PID控制函数
- float fuzzy_pid_control(float setpoint, float process_value)
- {
- float e = setpoint - process_value; // 计算误差
- float ec_now = e - e_last; // 计算当前误差变化率
- // 计算当前权重
- float w_e = 0.5; // 误差权重
- float w_ec = 0.3; // 误差变化率权重
- float w_u = 0.2; // 控制量变化率权重
- // 计算模糊控制量
- ec[2] = ec[1]; ec[1] = ec[0]; ec[0] = ec_now; // 更新误差变化率数组
- u[2] = u[1]; u[1] = u[0]; // 更新控制量变化率数组
- 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; // 转换为电压
- float temperature = voltage_to_temperature(voltage); // 将电压转换为温度
- float filtered_temp = butterworth_filter(temperature); // 进行抗干扰滤波
- // 模糊PID控制
- float output = fuzzy_pid_control(setpoint, filtered_temp);
- // 输出控制信号
- // TODO: your code here
- }
- }
复制代码
该程序基于51单片机,使用巴特沃斯滤波器对采集到的温度数据进行抗干扰滤波,并使用模糊PID控制算法来实现温度控制。
在主函数中,我们首先进行了零点满度校正和多点线性
2023/4/22 11:11:34
继续
2023/4/22 11:12:00
校正,以提高ADC采样值的精度。在校正之后,程序进入了一个死循环中,不断地从ADC获取温度采样值,并进行滤波和控制。
抗干扰滤波部分使用了二阶低通巴特沃斯滤波器。该滤波器有五个参数:b0、b1、b2、a1、a2。其中,b0、b1、b2是滤波器输入状态变量与输出状态变量的系数,a1、a2是滤波器输出状态变量的系数。这些系数可以根据具体的要求进行调整,以达到不同的滤波效果。
模糊PID控制部分使用了模糊逻辑来处理误差、误差变化率和控制量变化率,以计算出控制量。该算法有四个参数:kp、ki、kd、w_e、w_ec、w_u。其中,kp、ki、kd是比例、积分、微分系数,w_e、w_ec、w_u是三个变量的权重系数。这些参数可以根据具体的需要进行调整,以达到更好的控制效果。
最后,程序通过输出控制信号实现对温度的控制。需要注意的是,在实际应用中,我们需要将控制信号转换为对应的电气信号,并控制温度调节器来实现温度的控制。
|
|