#include "./pid/pid.h" #include "./led/bsp_led.h" #include "./GeneralTim/bsp_GeneralTim.h" PID pid; //存放PID算法所需要的数据 uint16_t pw; uint16_t save_buff[9000] = {0}; //保存数据缓存 extern volatile uint16_t Step_Auto; extern volatile uint32_t PID_cool_cnt; extern volatile uint32_t PID_heat_cnt; extern volatile uint16_t pid_self_first_status_flag; //标志位 extern volatile uint16_t PID_Deal,PID_auto_Deal; extern volatile uint16_t zero_across_counter; extern volatile uint16_t k_pid_self_counter; extern volatile uint16_t CCR4_Val; extern volatile uint16_t kkk; void PID_Calc() //pid计算 { float DelEk; float out; if (PID_Deal == 1) { pid.Ek=pid.Sv-pid.Pv; //得到当前的偏差值 pid.SEk+=pid.Ek; //历史偏差总和 DelEk=pid.Ek-pid.Ek_1; //最近两次偏差之差 pid.Pout=pid.Kp*pid.Ek; //比例输出 pid.Iout=pid.Ki*pid.SEk; //积分输出 pid.Dout=pid.Kd*DelEk; //微分输出 out= pid.Pout+ pid.Iout+ pid.Dout; kkk++; if(out>255) { kkk=0; pid.SEk=0; } if(out>255) { pid.OUT=255; } else if(out<0) { pid.OUT=0; } else { pid.OUT=out; } pid.Ek_1=pid.Ek; //更新偏差 // printf ( "\r\n%.1f\r\n",out); PID_out(); } } void PID_out() //输出PID运算结果到负载---每1ms被调用1次 { uint16_t kk; if (pid.Pv>pid.Sv)//当前温度大于用户设定温度 { CCR4_Val=100; GENERAL_TIM_Init(); } else { kk=100-pid.OUT*100/255; CCR4_Val=kk; GENERAL_TIM_Init(); // printf ( "\r\n%3d\r\n",kk); } } void PID_auto()//继电器反馈法自整定pid参数 { uint8_t i = 0; float KC = 0; float TC = 0; float V_temp = 0,min_temp = 0,max_temp = 0; float TIME_Hight=0,TIME_LOW=0; //第一步进入比较初始温度 确定此时温度处于哪种情况 if (PID_auto_Deal== 0) { /******************************************************************************************************/ PID_Deal = 0;//退出pid //程序第一次进入 查看对比当前温度和设定温度 if(pid.Pv < pid.Sv1)//当前温度低于设定温度 { PID_heat_cnt++; //热 PID_cool_cnt = 0; if(PID_heat_cnt >= 3)//连续3次结果 { CCR4_Val=0;//加热 GENERAL_TIM_Init(); if(Step_Auto == 0) { Step_Auto = 1; zero_across_counter++; // printf ( "\r\n1"); } } } else//当前温度 大于 设定温度 停止加热 { PID_cool_cnt++; PID_heat_cnt = 0; if(PID_cool_cnt > 3) { CCR4_Val=100; //不加热 GENERAL_TIM_Init(); if(Step_Auto == 1) //设定温度高于当前温度 { Step_Auto = 0; zero_across_counter++; } } } if(PID_heat_cnt >= 65535)//连续3次结果 { PID_heat_cnt=65535; } if(PID_cool_cnt >= 65534)//连续3次结果 { PID_cool_cnt=65534; } /*****************开始计算强行振荡的周期和幅值****************************/ if((zero_across_counter == 3 ) || (zero_across_counter == 4 )) { save_buff[k_pid_self_counter] = pid.Pv; k_pid_self_counter++; if(k_pid_self_counter >=9000) { k_pid_self_counter = 0; } } else if(zero_across_counter == 5 )//5次过0 则说明出现了振荡 整定成功 { PID_Deal = 1; PID_auto_Deal = 1; zero_across_counter = 0; max_temp=save_buff[0]; min_temp=save_buff[0]; for(i = 0;i < k_pid_self_counter;i++) { if(save_buff[i] >= max_temp) { max_temp = save_buff[i]; TIME_LOW=i; } if(save_buff[i] <= min_temp) { min_temp = save_buff[i]; TIME_Hight=i; } } V_temp = max_temp - min_temp; //最大减最小就是幅值 KC = 127/V_temp; //如果记录了 最低温度 与 最高温度对应的时间 那么沿用这个公式:TC = 2 * (TIME_Hight - TIME_LOW); TC = k_pid_self_counter; //TC =2 * (TIME_Hight - TIME_LOW); pid.Kp = 0.6*KC; pid.Ki = (0.6*KC)/(0.5*TC)/10; pid.Kd = (0.6*KC)*(0.125*TC)/60; printf ( "\r\n整定成功"); } } } 复制#include "stm32f10x.h" #include "core_cm3.h" #include "./systick/bsp_SysTick.h" #include "./led/bsp_led.h" #include "./usart/bsp_usart.h" #include "./ds18b20/bsp_ds18b20.h" #include "./pid/pid.h" #include "./timer/timer.h" #include "./AdvanceTim/bsp_AdvanceTim.h" #include "./GeneralTim/bsp_GeneralTim.h" volatile uint32_t time = 0; // ms 计时变量 volatile uint32_t time2 = 0; // ms 计时变量 float TM1,TM2; volatile uint8_t ucDs18b20Id[8]; volatile uint16_t Step_Auto; volatile uint32_t PID_cool_cnt; volatile uint32_t PID_heat_cnt; volatile uint16_t pid_self_first_status_flag; //标志位 volatile uint16_t PID_Deal,PID_auto_Deal; volatile uint16_t zero_across_counter; volatile uint16_t k_pid_self_counter; volatile uint16_t CCR4_Val; volatile uint16_t kkk; //volatile uint16_t save_buff[9000] = {0}; void delay(); void PID_Init() { pid.Sv=30; //用户设定温度 pid.OUT0=1; zero_across_counter=0; PID_cool_cnt=0; PID_heat_cnt=0; PID_Deal=0; PID_auto_Deal=0; pid_self_first_status_flag = 0; k_pid_self_counter=0; if( pid.Pv <= pid.Sv) //设定温度高于当前温度 { pid.Sv1=(pid.Sv-pid.Pv)/2+pid.Pv; pid.Sv1=(pid.Sv-pid.Pv)/2+pid.Pv; pid.Sv1=(pid.Sv-pid.Pv)/2+pid.Pv; pid.Sv1=(pid.Sv-pid.Pv)/2+pid.Pv; pid.Sv1=(pid.Sv-pid.Pv)/2+pid.Pv; } // CCR4_Val=100; // PID_auto_Deal=1; // PID_Deal=1; // pid.Sv=30; // pid.Kp=38.0999985; // pid.Ki=0.21666673; // pid.Kd=2.8575; } /** * [url=home.php?mod=space&uid=247401]@brief[/url] 主函数 * @param 无 * @retval 无 */ int main(void) { delay(); CCR4_Val=50; ADVANCE_TIM_Init(); GENERAL_TIM_Init(); /* 配置SysTick 为1us中断一次 */ SysTick_Init(); // /* 端口初始化 */ // LED_GPIO_Config();//初始化了PB1口 USART_Config(); //初始化串口1 printf("\r\n this is a ds18b20 test demo \r\n"); while( DS18B20_Init() ) printf("\r\n no ds18b20 exit \r\n");//初始化DS18B20,不初始化就等待这里? printf("\r\n ds18b20 exit \r\n"); DS18B20_ReadId(ucDs18b20Id); TM1=DS18B20_GetTemp_MatchRom ( ucDs18b20Id ); pid.Pv=TM1; PID_Init(); //参数初始化 pid.Sv1=28; while(1) { printf ( "\r\n%.1f",TM1); // 打印通过 DS18B20 序列号获取的温度值 Delay_ms(10); TM1=DS18B20_GetTemp_MatchRom ( ucDs18b20Id ); pid.Pv=TM1;//当前温度 pid.Pv=TM1;//当前温度 PID_auto(); PID_Calc(); //pid计算 // printf ( "\r\n%.1f",TM1); // 打印通过 DS18B20 序列号获取的温度值 // Delay_ms(1000); // if ( time >= 10 ) /* 10 * 1 ms = 10ms 时间到 */ // { // time = 0; // TM1=DS18B20_GetTemp_MatchRom ( ucDs18b20Id ); // pid.Pv=TM1;//当前温度 // } // if ( time2 >= 1000 ) /* 1000 * 1 ms = 1s 时间到 */ // { // time2 = 0; // pid.Pv=TM1;//当前温度 // PID_auto(); // PID_Calc(); //pid计算 // } } } void delay(void) { int i; for(i=0; i<10000000; i++) ; }
#include "stm32f10x.h" #include "core_cm3.h" #include "./systick/bsp_SysTick.h" #include "./led/bsp_led.h" #include "./usart/bsp_usart.h" #include "./ds18b20/bsp_ds18b20.h" #include "./pid/pid.h" #include "./timer/timer.h" #include "./AdvanceTim/bsp_AdvanceTim.h" #include "./GeneralTim/bsp_GeneralTim.h" volatile uint32_t time = 0; // ms 计时变量 volatile uint32_t time2 = 0; // ms 计时变量 float TM1,TM2; volatile uint8_t ucDs18b20Id[8]; volatile uint16_t Step_Auto; volatile uint32_t PID_cool_cnt; volatile uint32_t PID_heat_cnt; volatile uint16_t pid_self_first_status_flag; //标志位 volatile uint16_t PID_Deal,PID_auto_Deal; volatile uint16_t zero_across_counter; volatile uint16_t k_pid_self_counter; volatile uint16_t CCR4_Val; volatile uint16_t kkk; //volatile uint16_t save_buff[9000] = {0}; void delay(); void PID_Init() { pid.Sv=30; //用户设定温度 pid.OUT0=1; zero_across_counter=0; PID_cool_cnt=0; PID_heat_cnt=0; PID_Deal=0; PID_auto_Deal=0; pid_self_first_status_flag = 0; k_pid_self_counter=0; if( pid.Pv <= pid.Sv) //设定温度高于当前温度 { pid.Sv1=(pid.Sv-pid.Pv)/2+pid.Pv; pid.Sv1=(pid.Sv-pid.Pv)/2+pid.Pv; pid.Sv1=(pid.Sv-pid.Pv)/2+pid.Pv; pid.Sv1=(pid.Sv-pid.Pv)/2+pid.Pv; pid.Sv1=(pid.Sv-pid.Pv)/2+pid.Pv; } // CCR4_Val=100; // PID_auto_Deal=1; // PID_Deal=1; // pid.Sv=30; // pid.Kp=38.0999985; // pid.Ki=0.21666673; // pid.Kd=2.8575; } /** * [url=home.php?mod=space&uid=247401]@brief[/url] 主函数 * @param 无 * @retval 无 */ int main(void) { delay(); CCR4_Val=50; ADVANCE_TIM_Init(); GENERAL_TIM_Init(); /* 配置SysTick 为1us中断一次 */ SysTick_Init(); // /* 端口初始化 */ // LED_GPIO_Config();//初始化了PB1口 USART_Config(); //初始化串口1 printf("\r\n this is a ds18b20 test demo \r\n"); while( DS18B20_Init() ) printf("\r\n no ds18b20 exit \r\n");//初始化DS18B20,不初始化就等待这里? printf("\r\n ds18b20 exit \r\n"); DS18B20_ReadId(ucDs18b20Id); TM1=DS18B20_GetTemp_MatchRom ( ucDs18b20Id ); pid.Pv=TM1; PID_Init(); //参数初始化 pid.Sv1=28; while(1) { printf ( "\r\n%.1f",TM1); // 打印通过 DS18B20 序列号获取的温度值 Delay_ms(10); TM1=DS18B20_GetTemp_MatchRom ( ucDs18b20Id ); pid.Pv=TM1;//当前温度 pid.Pv=TM1;//当前温度 PID_auto(); PID_Calc(); //pid计算 // printf ( "\r\n%.1f",TM1); // 打印通过 DS18B20 序列号获取的温度值 // Delay_ms(1000); // if ( time >= 10 ) /* 10 * 1 ms = 10ms 时间到 */ // { // time = 0; // TM1=DS18B20_GetTemp_MatchRom ( ucDs18b20Id ); // pid.Pv=TM1;//当前温度 // } // if ( time2 >= 1000 ) /* 1000 * 1 ms = 1s 时间到 */ // { // time2 = 0; // pid.Pv=TM1;//当前温度 // PID_auto(); // PID_Calc(); //pid计算 // } } } void delay(void) { int i; for(i=0; i<10000000; i++) ; }
收藏1 举报
本版积分规则 发表回复 回帖并转播 回帖后跳转到最后一页
23
1607
2
扫码关注 21ic 官方微信
扫码关注嵌入式微处理器
扫码关注电源系统设计
扫码关注21ic项目外包
扫码浏览21ic手机版
本站介绍 | 申请友情链接 | 欢迎投稿 | 隐私声明 | 广告业务 | 网站地图 | 联系我们 | 诚聘英才
京公网安备 11010802024343号