stm32+增量式pid+max6675 PWM温度控制

本文采用的芯片为STM32F103RCT6
温度芯片为MAX6675
之前spi通讯的max6675代码:
https://blog.csdn.net/answerMack/article/details/83310370
模拟io通讯的max6675代码:
https://blog.csdn.net/answerMack/article/details/83270562

代码写了,具体还没试验过
用电表打过结果,感觉还可以,就粘上来了。

因为选用的热电偶线测温变化太快,所以在中间加了报警,但是里面没有蜂鸣器。后续代码会改进。会加上CAN总线等设置。只是简单实现温控。

pid.h
#ifndef __PID_H
#define __PID_H
#include "sys.h"typedef struct {int Set_temperature;      //期望值int Current_temperature;    //当前值float proportion;             //比例系数Pfloat integral;          //积分系数Ifloat differential;      //微分系数Dint T; //采样周期float error_current;            //当前误差:浮点数int error_last;           //上一步误差int error_sum;              //误差累计float pid_proportion_out;         //比例项float pid_integral_out;            //积分项float pid_differential_out;        //微分项float pid_out;                    //PID控制输出}PID;//PID  *Pid;//存放PID算法需要的数据
//void PID_Init(int SETtemp);
float pid_control(PID *PP,float current_temp);
void PWM_CONTROL(float SUM); //占空比计算的
void PWM_Out(u8 m); //按功率输出的//struct PID  *PP;#endif

可能有错误,请评论帮忙指正。谢谢!!
//

pid.c
#include "pid.h"
#include "timer.h"
#include "usart.h"//void PID_Init(int SETtemp)  //启动时,PID的参数值应该从保存上次值的存储器空间读取出来。在此直接设定
//{//    Pid->Set_temperature=SETtemp;    //用户设定值
//  Pid->proportion=20;
//  Pid->integral=5000;   //积分系数
//  Pid->differential=1200;   //微分系数
//  Pid->T=1000;    //Pid计算周期(采样周期)
//    Pid->error_current=0.0;
//  Pid->error_last=0;
//  Pid->error_sum=0;
//  Pid->pid_proportion_out=0;
//  Pid->pid_integral_out=0;
//  Pid->pid_differential_out=0;
//  Pid->pid_out=0;
//} //struct PID *PP,
float pid_control( PID *PP,float current_temp){static float PID_ZL=0.0;float result=0.0;float A0,A1,A2;PP->error_current = PP->Set_temperature - current_temp;
printf("the PP->error_current is:%.2f\n",PP->error_current);
printf("\n");if(PP->error_current>20)PWM_Out(0);else if(PP->error_current<-20)PWM_Out(1);else if(PP->error_current>10 && PP->error_current<20)PWM_Out(2);else if(PP->error_current>-20 && PP->error_current<-10)PWM_Out(3);else if(PP->error_current>-20 && PP->error_current<-10)PWM_Out(3);/*==============增量式PID算法 增量式PID需每次叠加================*/else if(PP->error_current<10 && PP->error_current>-10){A0=PP->proportion * (1+ PP->T/PP->integral +PP->differential/PP->T);A1=-PP->proportion * (1+ 2*PP->differential/PP->T);A2=PP->proportion * (PP->differential/PP->T);result =A0 * PP->error_current + A1 * PP->error_last +A2 * PP->error_sum ;result += PID_ZL;if (result>900){if(PP->error_current>0)PWM_Out(0);else PWM_Out(1);}else if (result<-5){if(PP->error_current>0)PWM_Out(0);else PWM_Out(1);}else if (-5<result&&result<5){PWM_Out(4);}  else if (result>5&&result<900){if(PP->error_current>0)PWM_CONTROL(result);else PWM_CONTROL(-result);}}PID_ZL=result;
printf("the PID_ZL is:%.2f\n",PID_ZL);
printf("\n"); PP->error_sum=PP->error_last;PP->error_last=PP->error_current;return result;
}/*==============
10度以内  PID控制    判断result范围,确定占空比
=============*/
void PWM_CONTROL(float SUM){int a=0;a=SUM;
printf("the ccrx<ten is:%d\n",a);
printf("\n");
if (a>0)TIM_SetCompare3(TIM3,a);
else TIM_SetCompare1(TIM3,-a);
}void PWM_Out(u8 m){switch(m){/*=========================================tim_ch3--加热    tim_ch1--冷却
20度差值: 全功:0:加热不冷却  1:冷却不加热
10-20度之间   半功热
===========================================*/case 0 :TIM_SetCompare3(TIM3,0);TIM_SetCompare1(TIM3,900);break;    case 1 : TIM_SetCompare3(TIM3,900);TIM_SetCompare1(TIM3,0);break;   case 2 : TIM_SetCompare1(TIM3,800);TIM_SetCompare3(TIM3,449);break; case 3 : TIM_SetCompare1(TIM3,449);TIM_SetCompare3(TIM3,800);break; case 4 : //全关TIM_SetCompare1(TIM3,900);TIM_SetCompare3(TIM3,900);break; case 5 : //全开TIM_SetCompare1(TIM3,0);TIM_SetCompare3(TIM3,0);break;         }   }
pwm.h
#ifndef __TIMER_H
#define __TIMER_H
#include "sys.h"
void TIM3_PWM_Init(u16 arr,u16 psc);
#endif
pwm.c
#include "timer.h"
#include "GPIO.h"
//#include "usart.h"
//#include "stm32f10x.h"
void TIM3_PWM_Init(u16 arr,u16 psc)
{  GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;TIM_OCInitTypeDef  TIM_OCInitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);   //使能定时器3时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE); //Timer3完全重映射   /* FULL REMAP  ---   PC6/7/8/9  TIM_CH1/2/3/4*///设置该引脚为复用输出功能,GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9; //TIM_CH2GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIO//初始化TIM3TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位//初始化TIM3 Channel2 PWM模式   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高TIM_OC1Init(TIM3, &TIM_OCInitStructure);TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);//比较预装载TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器TIM_OC3Init(TIM3, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMxTIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIMx在CCR3上的预装载寄存器TIM_OC4Init(TIM3, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMxTIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIMx在CCR4上的预装载寄存器TIM_ARRPreloadConfig(TIM3,ENABLE);//自动重装载TIM_Cmd(TIM3, ENABLE);  //使能TIM3
}
main.c
#include "stm32f10x.h"
#include "usart.h"
#include "delay.h"
#include "sys.h"
#include "max6675.h"
#include "spi.h"
#include "led.h"
#include "timer.h"
#include "pid.h"int main(void){PID  temperature;temperature.Set_temperature=50;    //用户设定值temperature.proportion=20;temperature.integral=5000;   //积分系数temperature.differential=1200;   //微分系数temperature.T=1000;    //temperature计算周期(采样周期)temperature.error_current=0.0;temperature.error_last=0;temperature.error_sum=0;temperature.pid_proportion_out=0;temperature.pid_integral_out=0;temperature.pid_differential_out=0;temperature.pid_out=0;
//  float t1;float t2,t3;float temp_error;float pid_result;SystemInit();LED_init();delay_init();uart_init(9600);max6675_MONI_init();SPI2_Init();SPI2_SetSpeed(SPI_BaudRatePrescaler_8);//max6675的串行时钟频率为4.3MhzSPI1_Init();SPI1_SetSpeed(SPI_BaudRatePrescaler_8);//max6675的串行时钟频率为4.3Mhz//      PID_Init(50);//PID设置温度TIM3_PWM_Init(900-1,0);//不分频。PWM频率=72000000/9999+1/143+1=50hzTIM_SetCompare1(TIM3,449);   TIM_SetCompare2(TIM3,300);//TIM_SetCompare3(TIM3,0);TIM_SetCompare4(TIM3,900);while(1){GPIO_ResetBits(GPIOA,GPIO_Pin_8);GPIO_ResetBits(GPIOC,GPIO_Pin_12);GPIO_ResetBits(GPIOD,GPIO_Pin_2);/*温度显示模块*/
//      t1=max6675_readTemperature();
//      printf("the I temperature is:%.2f\n",t1);
//      printf("\n");t3=max6675_readTemp_III();printf("the III temperature is:%.2f\n",t3);printf("\n");  delay_ms(300);t2=max6675_readTemp();printf("the II temperature is:%.2f\n",t2);printf("\n");    temp_error=t2-t3;
/*==================报警函数
====================*/
if(temp_error>150)   {printf("warning");printf("\n");t2=temperature.Set_temperature;
}       pid_result=pid_control(&temperature,t2);printf("the pid_result is:%.2f\n",pid_result);printf("\n");GPIO_SetBits(GPIOA,GPIO_Pin_8);GPIO_SetBits(GPIOC,GPIO_Pin_12);GPIO_SetBits(GPIOD,GPIO_Pin_2);delay_ms(300);    }
}

代码文件:

链接:https://pan.baidu.com/s/1Zg2zt65BZQi3DycBhGHOAw
提取码:a6jd

stm32+增量式pid+max6675 PWM温度控制相关推荐

  1. STM32增量式pid直流电机调速(内附源码)

    目录 一. 1.硬件组成 2.模块分析 1.TB6612电机驱动模块 2.直流减速电机 3.电源稳压模块 二.接线 三.代码思路讲解(详见源码) 四.STM32cubmx配置 1.系统基础配置:(重要 ...

  2. 位置式Pid和增量式Pid的定义及应用

    PID算法是一个典型的闭环控制系统.P.I.D,比例.积分.微分. 开环:输入量对输出量没有反馈作用: 闭环:输入量对输出量有反馈作用. 位置式Pid 位置式Pid就是位置闭环控制,位置闭环控制就是根 ...

  3. 零基础制作平衡小车【连载】8---位置式PID和增量式PID

    上一节说的PID公式属于位置式PID,位置式PID控制的输出与整个过去的状态有关,用到了误差的累加值,而增量式PID的输出只与当前拍和前两拍的误差有关.就温控系统来说,位置式PID输出的结果就是PWM ...

  4. 增量式速度pid调节策略_增量式PID是什么?不知道你就落伍了

    目录 1 什么是增量式PID? 2 举个例子 2.1 位置式PID 2.2 增量式PID 3 伪算法 4 C语言实现 5 总结 在之前一篇博客中( 简易PID算法的快速扫盲 )简单介绍了PID算法的基 ...

  5. 基于自适应算法和增量式PID算法的模拟直升飞机控制系统

    基于自适应算法和增量式PID算法的模拟直升飞机控制系统 文章目录 基于自适应算法和增量式PID算法的模拟直升飞机控制系统 控制系统硬件 单片机系统 传感器系统介绍 直升机模拟系统介绍 系统模块介绍 A ...

  6. 位置式和增量式PID控制

    PID控制是一个二阶线性控制器 定义:通过调整比例.积分和微分三项参数,使得大多数的工业控制系统获得良好的闭环控制性能. 优点 a. 技术成熟 b. 易被人们熟悉和掌握 c. 不需要建立数学模型 d. ...

  7. 学习笔记—增量式PID详细实现(C语言)

    增量式PID指数字控制器的输出只是控制量的增量∆uk.当执行机构需要的控制量是增量,而不是位置量的绝对数值时,可以使用增量式PID控制算法进行控制. 1.公式推导: 增量式PID控制算法可以通过位置式 ...

  8. 增量式pid分析 及 参数整定

    /************************************************************************** 函数功能:增量PI控制器 1.入口参数:编码器测 ...

  9. 位置式与增量式PID

    1PID控制算法-----什么是PID PID 控制器以各种形式使用超过了 1 世纪,广泛应用在机械设备.气动设备 和电子设备.在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算 ...

最新文章

  1. F3PlotStrip
  2. 学历是铜牌,能力是银牌,人脉是金牌,思维是王牌——有感
  3. Android使用ConstraintLayout 加载RecyclerView数据显示不全
  4. 反光衣识别算法冠军方案总结(附源码)|极市打榜
  5. android edittext seterror,EditText之setError方法一二
  6. 蓝懿IOS委托模式代理模式
  7. Oracle 10g、11g :RAC关闭、启动、重启步骤
  8. android怎么让图片显示在button上面_opencv怎么样可以实时显示图片HSV值
  9. 利用Python实现黑客帝国代码雨,打造属于自己的黑客帝国
  10. x3850用uefi安装Linux7,X3850 X5在uEFI模式下无法安装Centos 6.2的解决办法
  11. 【SAP GUI Scripting】 入门系列(1)_基本设置
  12. 最全Android 11新特性概览
  13. 信用社pb通用记账_信用社会计记账采用的是()。A、收付实现制B、权责发生制C、借贷记账法D、单式记账法...
  14. 记录使用QRCode 显示并下载二维码图片
  15. 怎么将webm文件转换成MP4格式在手机上播放
  16. All flavors must now belong to a named flavor dimension. Learn more at https://
  17. iOS仿写有妖气漫画、视频捕获框架、启动页广告页demo、多种动画效果等源码...
  18. 联邦学习进阶之路升级打怪
  19. 自动驾驶决策规划算法第二章——Apollo EM Planner实践篇
  20. Windows10 Ubuntu18.04 双系统下修复GRUB引导(亲测当boot-repair工具无效时,该方法完美解决)

热门文章

  1. 确看待百度预估流量为0的问题
  2. PLSQL入门与精通(第81章:利用游标进行递归调用的时候游标数超标问题)
  3. 做FPGA的出路在哪里?——同行的感受,我的方向
  4. 分布式配置中心-Config
  5. weblogic密码加解密
  6. VIO:飞行机器人单目VIO算法测评
  7. 果蝇算法优化支持向量机
  8. ffmpeg php 抠像_实时虚拟抠像设备八路切换台
  9. 2022年ArchSummit全球架构师峰会杭州站感想
  10. eBay教程--eBay标题如何进行撰写