项目简介
pid在做调参方面非常常见,在要求不高的,成本较低的环境下,不用神经网络也能跑一个很好的效果,大量应用于各种地方,比如电机驱动啥的,其原理也比较简单。由于不涉及单独的外设,通过多功能调试助手来实现简单的单级PID调参操作。
实验内容:完成PID算法简单程序书写,通过串口调试助手显示
原理简介
PID:百度百科的介绍,在做小车等项目中常有遇到
单级框图如图所示
P代表误差,I代表积分,D代表微分
误差的作用是:当你向左时,给一个和你方向相反的力让你向右,在类似追逐点问题中,当在目标点右侧,故给向左侧的分力,体现为周期摆动。
微分的作用:只有分力是不足以平衡的,,类似于阻尼振动,最后会在目标点停下来
积分的作用:在给定恒力的条件下,无法达到目标点的位置,通过对误差的累积,当误差持续存在,积分则持续累积,从而达到消除误差的目的
其主要公式:
连续型:
在实际中连续型没法在mcu里面跑 所以通常都用离散型的,根据信号与系统知识,就是积分->累加,微分->差分,公式如下:
其中主要的参数为Kp,Ki,Kd,在具体应用中搭建好工程只需要对着三个参数进行调节即可,公式表述:
PID最主要的地方就是调参,本次实验通过PID串口调试助手,通过输出的波形进行调参。按键按下使得电位变化,观察PID波形的变化情况
更为复杂的串级PID,采用内环和外环的操作,本节不多讲,可以在下面参考文献找到
Cube配置
打开TIM6定时器,设置定时周期500ms,配置LED0,1;KEY0,1,打开定时器中断,中断优先级为2,打开串口1,设置中断优先级为0,最后生成工程。
工程代码
新建名为pid.c&pid.h的文件 代码如下:
//pid.h
#ifndef __BSP_PID_H
#define __BSP_PID_H
#include "stm32f1xx.h"
#include "usart.h"
#include <stdio.h>
#include <stdlib.h>
/*pid*/
typedef struct
{
float target_val;
float actual_val;
float err;
float err_last;
float Kp,Ki,Kd;
float integral;
}pid;
extern void PID_param_init(void);
extern void set_pid_target(float temp_val);
extern float get_pid_target(void);
extern void set_p_i_d(float p, float i, float d);
extern