stm32+增量式pid+max6675 PWM温度控制
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温度控制相关推荐
- STM32增量式pid直流电机调速(内附源码)
目录 一. 1.硬件组成 2.模块分析 1.TB6612电机驱动模块 2.直流减速电机 3.电源稳压模块 二.接线 三.代码思路讲解(详见源码) 四.STM32cubmx配置 1.系统基础配置:(重要 ...
- 位置式Pid和增量式Pid的定义及应用
PID算法是一个典型的闭环控制系统.P.I.D,比例.积分.微分. 开环:输入量对输出量没有反馈作用: 闭环:输入量对输出量有反馈作用. 位置式Pid 位置式Pid就是位置闭环控制,位置闭环控制就是根 ...
- 零基础制作平衡小车【连载】8---位置式PID和增量式PID
上一节说的PID公式属于位置式PID,位置式PID控制的输出与整个过去的状态有关,用到了误差的累加值,而增量式PID的输出只与当前拍和前两拍的误差有关.就温控系统来说,位置式PID输出的结果就是PWM ...
- 增量式速度pid调节策略_增量式PID是什么?不知道你就落伍了
目录 1 什么是增量式PID? 2 举个例子 2.1 位置式PID 2.2 增量式PID 3 伪算法 4 C语言实现 5 总结 在之前一篇博客中( 简易PID算法的快速扫盲 )简单介绍了PID算法的基 ...
- 基于自适应算法和增量式PID算法的模拟直升飞机控制系统
基于自适应算法和增量式PID算法的模拟直升飞机控制系统 文章目录 基于自适应算法和增量式PID算法的模拟直升飞机控制系统 控制系统硬件 单片机系统 传感器系统介绍 直升机模拟系统介绍 系统模块介绍 A ...
- 位置式和增量式PID控制
PID控制是一个二阶线性控制器 定义:通过调整比例.积分和微分三项参数,使得大多数的工业控制系统获得良好的闭环控制性能. 优点 a. 技术成熟 b. 易被人们熟悉和掌握 c. 不需要建立数学模型 d. ...
- 学习笔记—增量式PID详细实现(C语言)
增量式PID指数字控制器的输出只是控制量的增量∆uk.当执行机构需要的控制量是增量,而不是位置量的绝对数值时,可以使用增量式PID控制算法进行控制. 1.公式推导: 增量式PID控制算法可以通过位置式 ...
- 增量式pid分析 及 参数整定
/************************************************************************** 函数功能:增量PI控制器 1.入口参数:编码器测 ...
- 位置式与增量式PID
1PID控制算法-----什么是PID PID 控制器以各种形式使用超过了 1 世纪,广泛应用在机械设备.气动设备 和电子设备.在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算 ...
最新文章
- F3PlotStrip
- 学历是铜牌,能力是银牌,人脉是金牌,思维是王牌——有感
- Android使用ConstraintLayout 加载RecyclerView数据显示不全
- 反光衣识别算法冠军方案总结(附源码)|极市打榜
- android edittext seterror,EditText之setError方法一二
- 蓝懿IOS委托模式代理模式
- Oracle 10g、11g :RAC关闭、启动、重启步骤
- android怎么让图片显示在button上面_opencv怎么样可以实时显示图片HSV值
- 利用Python实现黑客帝国代码雨,打造属于自己的黑客帝国
- x3850用uefi安装Linux7,X3850 X5在uEFI模式下无法安装Centos 6.2的解决办法
- 【SAP GUI Scripting】 入门系列(1)_基本设置
- 最全Android 11新特性概览
- 信用社pb通用记账_信用社会计记账采用的是()。A、收付实现制B、权责发生制C、借贷记账法D、单式记账法...
- 记录使用QRCode 显示并下载二维码图片
- 怎么将webm文件转换成MP4格式在手机上播放
- All flavors must now belong to a named flavor dimension. Learn more at https://
- iOS仿写有妖气漫画、视频捕获框架、启动页广告页demo、多种动画效果等源码...
- 联邦学习进阶之路升级打怪
- 自动驾驶决策规划算法第二章——Apollo EM Planner实践篇
- Windows10 Ubuntu18.04 双系统下修复GRUB引导(亲测当boot-repair工具无效时,该方法完美解决)