找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1662|回复: 2
收起左侧

自整定PID温控51单片机STM32程序源码 PCB原理图资料

  [复制链接]
ID:859423 发表于 2023-6-11 15:01 | 显示全部楼层 |阅读模式
全新热偶自整定PID温控51芯片 STM32单片机都有

STM32单片机原理图和PCB文件:
51hei.png 51hei.png

51单片机原理图和PCB文件:
51hei.png
51hei.png


部分51单片机程序:
  1. int pid_calc(float set_temp ,float now_temp )// pid计算  set_temp 为设定的温度  now_temp  代表实际输入的当前温度值  0 - 100的输出值
  2. {
  3. Error = set_temp - now_temp;                 // 偏差
  4. if(( Error < max_value_error  ) && ( Error > (min_value_error)  ))//只有在一定的温差范围内才pid计算
  5.     {   
  6.     SumError += Error;
  7.     dError    = LastError - PrevError;   // 当前微分
  8.     PrevError = LastError;
  9.     LastError = Error;
  10.     temp_pid  =  (int)((Proportion * Error) + (Integral * SumError) + (Derivative * dError));   
  11.     //temp_pid  =  (int)(temp_pid * 0.5) ;//输出比例控制
  12.         }
  13. else//只有开关作用
  14.     {
  15.     if( Error >= max_value_error )//远大于当前温度,加热
  16.         {
  17.         temp_pid = 100;
  18.         //temp_pid = 80;
  19.                 }
  20.     else if( Error <= (min_value_error) )//远小于当前温度,不加热
  21.         {
  22.         temp_pid = 0;
  23.         }
  24.     }
  25. if( temp_pid < 0 )
  26.     {
  27.     temp_pid = 0;
  28.     }
  29. else if( temp_pid > 100 )
  30.     {
  31.     temp_pid = 100;
  32.     }
  33. return temp_pid;
  34. }


  35. void pid_con(void)//由计算结果控制输出
  36. {

  37. //适用于 pwm
  38. //每200ms根据结果改变一次输出电压的值
  39. if( pwm_con_time_flag == 1)
  40.         {
  41.         pwm_con_time_flag = 0;
  42.         
  43.         //lcd_s_12864_light_1;delay_ms(10);lcd_s_12864_light_0;//test

  44.         //set_pwm_value(40 + (uchar)(pid_result * (((float)(237-40))/100.0)) );
  45.         set_pwm_value(40 + (uchar)(pid_result * 1.97) );//跟上面这句话等价
  46.         
  47.         }

  48. }


  49. void pid_pro(void)//pid 自整定及控制输出 ppppppppppppppppppppppppppppp
  50. {
  51. //每200ms获得一次温度
  52. if( get_now_temp_flag == 1)//200ms秒获得一次温度
  53.         {
  54.         get_now_temp_flag = 0;
  55.         
  56.         //lcd_s_12864_light_1;delay_ms(10);lcd_s_12864_light_0;//test

  57.         PV_value = read_max6675_temper();
  58.         }

  59. if     ( pid_tune_flag == 1 )//自整定阶段  完毕之后转成pid控制
  60.         {
  61.         //自整定ok后自动转为pid阶段
  62.         //自整定失败的情况下 让基本参数恢复默认值

  63.         if( pid_self_sec_flag == 1 )//自整定过程  0.2秒1次
  64.                 {
  65.                 pid_self_sec_flag = 0;
  66.                 dis_tune_once_flag = 1;//0.2秒显示1次基本信息
  67.                 //lcd_s_12864_light_0;delay_ms(10);lcd_s_12864_light_1;//test

  68.                 pid_self_time_sec++;
  69.                 if(pid_self_time_sec > (3600*3)) // 如果总的自整定时间大于了3/5=0.6个小时,则说明整定失败
  70.                         {
  71.                         pid_self_time_sec = 0;                        
  72.                         //lcd_s_12864_light_0;delay_ms(10);lcd_s_12864_light_1;//test
  73.                         LcmClear();//清屏
  74.                         comm_dis_once_flag    = 1;
  75.                         special_dis_once_flag = 1;
  76.                         pid_tune_flag = 0;//那么将自动退出自整定过程 同时采用默认值  进入pid阶段
  77.                         KC = 1.0;//临界比例系数  初始默认的值
  78.                         TC = 40; //振荡周期    初始默认的值

  79.                         }

  80.                 if(( pid_self_first_status_flag == 1) || ( pid_self_first_status_flag == 0))//0 设定温度 低于 当前温度  //1设定温度 高于 或者 等于  当前温度  启动加热
  81.                         {

  82.                         //lcd_s_12864_light_0;delay_ms(10);lcd_s_12864_light_1;//test

  83.                         //基本on/off控制
  84.                         if( SV_value >= PV_value )//启动加热
  85.                                 {
  86.                                 cool_ack_counter = 0;
  87.                                 hot_ack_counter++;
  88.                                 if(hot_ack_counter > 3)//连续3次都是一样的结果 说明确定 SV_value >= PV_value
  89.                                         {
  90.                                        
  91.                                         ssr_con_1;
  92.                                         //pwm_con_1;//一旦pwm参与将不能通过操作io的形式控制该口线
  93.                                         set_pwm_value(237);//全速加热

  94.                                         if(once_add_1_flag == 0)
  95.                                                 {
  96.                                                 once_add_1_flag = 1;
  97.                                                 zero_across_counter++;
  98.                                                 
  99.                                                 //lcd_s_12864_light_0;delay_ms(10);lcd_s_12864_light_1;//test
  100.                                                 
  101.                                                 if(zero_across_counter == 3 )
  102.                                                         {
  103.                                                         TIME_LOW = pid_self_time_sec - 3;//此时的时间不是最低温度对应的时间
  104.                                                         }
  105.                                                 }
  106.                                         }
  107.                                 }
  108.                         else//当前温度 大于 设定温度 停止加热
  109.                                 {
  110.                                 
  111.                                 //lcd_s_12864_light_0;delay_ms(10);lcd_s_12864_light_1;//test
  112.                                                                
  113.                                 hot_ack_counter = 0;
  114.                                 cool_ack_counter++;
  115.                                 if(cool_ack_counter > 3)
  116.                                         {
  117.                                         ssr_con_0;
  118.                                         set_pwm_value(40);//不加热
  119.                                         if(once_add_1_flag == 1)
  120.                                                 {
  121.                                                 once_add_1_flag = 0;
  122.                                                 zero_across_counter++;
  123.                                                 if(zero_across_counter == 3 )
  124.                                                         {
  125.                                                         TIME_LOW = pid_self_time_sec - 3;//此时的时间不是最低温度对应的时间
  126.                                                         }
  127.                                                 }
  128.                                         }
  129.                                 }

  130.                         //最低温度 出现在 zero_across_counter = 3 的阶段
  131.                         //最高温度 出现在 zero_across_counter = 4 的阶段
  132.                         if((zero_across_counter == 3 ) || (zero_across_counter == 4 ))
  133.                                 {                                
  134.                                 pid_self_calc_buffer[k_pid_self_counter] = PV_value;
  135.                                 k_pid_self_counter++;
  136.                                 if(k_pid_self_counter > 3)//0--3 共4个元素
  137.                                         {
  138.                                         k_pid_self_counter = 0;
  139.                                         enable_calc_min_max_flag = 1;
  140.                                         }
  141.                                 if(enable_calc_min_max_flag == 1)//只要有4个值,就可以计算了 后面来的值覆盖了前面的值
  142.                                         {
  143.                                         //去掉最小值 最大值 取剩下2个值的平均值
  144.                                         sum_temp = 0.0;  //先清0
  145.                                         min_temp = 1024.0;
  146.                                         max_temp = 0.0;
  147.                                                 
  148.                                         for(k_max_min = 0; k_max_min < 4; k_max_min++ )
  149.                                                 {                                                
  150.                                                 if(pid_self_calc_buffer[k_max_min] <= min_temp)
  151.                                                         {
  152.                                                         min_temp = pid_self_calc_buffer[k_max_min];
  153.                                                         }
  154.                                                 if(pid_self_calc_buffer[k_max_min] >= max_temp)
  155.                                                         {
  156.                                                         max_temp = pid_self_calc_buffer[k_max_min];
  157.                                                         }                                                
  158.                                                 sum_temp = (sum_temp + pid_self_calc_buffer[k_max_min]);
  159.                                                 }
  160.                                         sum_temp =  sum_temp - min_temp - max_temp ;
  161.                                        
  162.                                        
  163.                                         //pid_self_first_status_flag = 1 时 最低温度出现在3阶段
  164.                                         //pid_self_first_status_flag = 0 时 最低温度出现在4阶段
  165.                                         if(pid_self_first_status_flag == 1)
  166.                                                 {
  167.                                                 if(zero_across_counter == 3 )//最低温度
  168.                                                         {
  169.                                                         aver_temp = (sum_temp/2.0);                                       
  170.                                                         if( aver_temp <= T_LOW )
  171.                                                                 {
  172.                                                                 T_LOW = aver_temp;
  173.                                                                 }                                
  174.                                                         }
  175.                                                 else if(zero_across_counter == 4 )//最高温度
  176.                                                         {
  177.                                                         aver_temp = (sum_temp/2.0);
  178.                                                         if( aver_temp >= T_Hight )
  179.                                                                 {
  180.                                                                 T_Hight = aver_temp;
  181.                                                                 }
  182.                                                         }
  183.                                                 }
  184.                                         else if(pid_self_first_status_flag == 0)
  185.                                                 {
  186.                                                 if(zero_across_counter == 4 )//最低温度
  187.                                                         {
  188.                                                         aver_temp = (sum_temp/2.0);                                       
  189.                                                         if( aver_temp <= T_LOW )
  190.                                                                 {
  191.                                                                 T_LOW = aver_temp;
  192.                                                                 }                                
  193.                                                         }
  194.                                                 else if(zero_across_counter == 3 )//最高温度
  195.                                                         {
  196.                                                         aver_temp = (sum_temp/2.0);
  197.                                                         if( aver_temp >= T_Hight )
  198.                                                                 {
  199.                                                                 T_Hight = aver_temp;
  200.                                                                 }
  201.                                                         }
  202.                                                 }
  203.                                         }
  204.                                 }
  205.                         else if(zero_across_counter == 5 )//4次过0 则说明出现了振荡 整定成功
  206.                                 {
  207.                                 zero_across_counter = 0;                                
  208.                                 pid_tune_flag = 0;//进入pid阶段
  209.                                 //pid_tune_flag = 1;//test
  210.                                 TIME_Hight = pid_self_time_sec - 3;//此时的时间不是最高温度对应的时间
  211.                                 LcmClear();//清屏
  212.                                 comm_dis_once_flag    = 1;
  213.                                 special_dis_once_flag = 1;                                
  214.                                 //dis_4_line_as_null();//清除最后一行的内容
  215.                                 //计算 T_Hight T_LOW TIME_Hight TIME_LOW 这4个值
  216.                                 //根据以上4个值  KC 与 TC 的值便会计算出来
  217.                                 
  218.                                 KC = 12.7/(T_Hight - T_LOW);
  219.                                 KC = 5.0 * KC;//因为是0.2s一次 所以扩大5倍
  220.                                 TC = 1 * (TIME_Hight - TIME_LOW);//如果记录了 最低温度 与 最高温度对应的时间 那么沿用这个公式:TC = 2 * (TIME_Hight - TIME_LOW);
  221.                                 }
  222.                         }
  223.                 //显示具体的值  测试用
  224.                 //dis_pid_self_value(); //test
  225.                 }
  226.         }
  227. else if( pid_tune_flag == 0 )//pid 阶段  默认开机进入此阶段
  228.         {
  229.         //0 算出 临界增益 KC 及 振荡周期 TC
  230.         // KC = (4*d)/(3.14*A)  ---> d = 5(输出幅值) ; A = 记录的温度最高值与最低值的差值的0.5倍 即:(T_Hight - T_LOW)*0.5
  231.         // KC = (4*5)/(3.14*((T_Hight - T_LOW)*0.5)) = 40/3.14/(T_Hight - T_LOW) =  12.7/(T_Hight - T_LOW)
  232.         // KC = 12.7/(T_Hight - T_LOW)
  233.         // TC = 2 * (TIME_Hight - TIME_LOW) ---> 2 * ( 高点温度对应时间 - 低点温度对应时间 )
  234.         // TC = 2 * (TIME_Hight - TIME_LOW)
  235.         //1 算出 具体的比例系数 积分秒数 微分秒数
  236.         //Proportion = 0.6*KC
  237.         //I_value    = 0.5*TC
  238.         //D_value    = 0.125*TC
  239.         //2 算出具体的 比例带 积分系数 微分系数
  240.         //P_value     = (1/Proportion)*100
  241.         //Integral          = Proportion/I_value = (0.6*KC)/(0.5*TC)
  242.         //Derivative  = Proportion*D_value = (0.6*KC)*(0.125*TC)  
  243.         //3显示用的3个变量的值
  244.         //P_value     = (1/Proportion)*100  百分比
  245.         //I_value     = 0.5*TC                                秒
  246.         //D_value     = 0.125*TC                        秒
  247.         //4pid计算用的3个变量的值
  248.         //Proportion  = 0.6*KC
  249.         //Integral          = Proportion/I_value = (0.6*KC)/(0.5*TC)
  250.         //Derivative  = Proportion*D_value = (0.6*KC)*(0.125*TC)  
  251.         
  252.         //KC = 21.4;//test
  253.         //TC = 471;//test
  254.         
  255.         if(enable_pid_sec_flag == 1)//进入pid时,0.2秒计算1次
  256.                 {
  257.                 enable_pid_sec_flag = 0;
  258.                
  259.                 //lcd_s_12864_light_0;delay_ms(10);lcd_s_12864_light_1;//test

  260.                 if(KC > 1666.0 )
  261.                         {
  262.                         KC = 1666.0;//对应 比例带为 0.1%
  263.                         }
  264.                 else if(KC < 0.5 )
  265.                         {
  266.                         KC = 0.5;//对应 比例带为 200.0%
  267.                         }
  268.                 if(TC > 7200 )
  269.                         {
  270.                         TC = 7200;
  271.                         }
  272.                 else if(TC < 8 )
  273.                         {
  274.                         TC = 8;
  275.                         }
  276.                
  277.                 Proportion  = 0.6*KC;//先算 比例系数
  278.                
  279.                 P_value     = ((1/Proportion)*100);     //比例带  百分比
  280.                 I_value     = (int)(0.5*TC);                        //积分    秒
  281.                 D_value     = (int)(0.125*TC);                        //微分    秒
  282.                 //限幅处理
  283.                 if(P_value > 200.0)
  284.                         {
  285.                         P_value = 200.0;
  286.                         }
  287.                 else if(P_value < 0.0)
  288.                         {
  289.                         P_value = 0.0;
  290.                         }
  291.                 if(I_value > 3600)
  292.                         {
  293.                         I_value = 3600;
  294.                         }
  295.                 else if(I_value < 0)
  296.                         {
  297.                         I_value = 0;
  298.                         }
  299.                 if(D_value > 900)
  300.                         {
  301.                         D_value = 900;
  302.                         }
  303.                 else if(D_value < 0)
  304.                         {
  305.                         D_value = 0;
  306.                         }
  307.                
  308.                 Proportion  = 0.6*KC;
  309.                 Integral        = (0.6*KC)/(0.5*TC);
  310.                 Derivative  = (0.6*KC)*(0.125*TC);
  311.                
  312.                 pid_result = pid_calc(SV_value,PV_value);
  313.                 }
  314.         
  315.         pid_con();//根据上一步的结果控制输出
  316.         
  317.         }

  318. }
复制代码

下载:
STM32单片机程序+原理图.7z (1.59 MB, 下载次数: 87)

评分

参与人数 2黑币 +55 收起 理由
mashuiyou + 5 共享资料的黑币奖励!
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:277290 发表于 2023-6-12 08:22 | 显示全部楼层
有空研究一下,谢谢分享!
回复

使用道具 举报

ID:230225 发表于 2023-6-21 08:17 | 显示全部楼层
mashuiyou 发表于 2023-6-12 08:22
有空研究一下,谢谢分享!

谢谢分享!下载学习下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表