电机应用-直流有刷电机(PID)

目录

自动控制系统

自动控制系统简介

开环控制系统

闭环控制系统

PID算法

PID简介

PID各环节作用

比例环节

积分环节

微分环节

PID离散公式

位置式PID公式

增量式PID公式

PID离散公式对比

PID算法代码实现

PID相关参数

PID算法函数实现

积分饱和问题

PID正点原子上位机

PID调参初体验

PID参数整定

采样周期的选择

PID参数整定方法

试凑法

临界比例法

一般调节法

正点原子PID上位机数据帧格式

代码实现

直流有刷电机速度环PID控制实验

速度闭环控制

直流有刷电机电流环PID控制实验

电流闭环控制

直流有刷电机位置环PID控制实验

位置闭环控制

直流有刷电机速度+位置双环PID控制实验

直流有刷电机电流+位置双环PID控制实验

直流有刷电机电流+速度双环PID控制实验

直流有刷电机三环PID控制实验



自动控制系统

自动控制系统简介

自动控制系统:用自动控制装置,对关键参数进行自动控制,使它在受到外界干扰而偏离正常状态时能够被自动地调节回到目标范围内。

开环控制系统

开环控制:输出只受系统输入控制,没有反馈回路,控制精度和抗干扰能力差。

如电风扇风力控制系统:

目标风力(输入)→控制电路→电机→扇叶转速→风力(输出)。

当时间久了,由于灰尘等积累,阻力变大,风力削弱,不再是目标风力。

闭环控制系统

闭环控制:引入反馈回路(一般为传感器采集输出值),利用输出和输入值的偏差对系统进行控制,避免偏离预定目标。

如大棚温控系统:

如直流有刷电机速度闭环控制系统:


PID算法

PID简介

PID是Proportional(比例)Integral(积分)Differential(微分)的首字母缩写,它是一种结合比例、积分和微分三个环节于一体的闭环控制算法

本质:根据输入的偏差值,按照比例、积分、微分的函数关系进行运算,运算结果用来控制输出。

PID各环节作用

比例环节

成比例的反应控制系统的偏差信号,即输出u与输入偏差e成正比,可以用来减小系统的偏差

1、Kp越大,系统响应越快,越快达到目标值。

2、Kp过大会使系统产生较大的超调和振荡,导致系统的稳定性变差。

3、仅有比例环节无法消除静态误差(系统控制过程趋于稳定时,目标值与实测值之间的偏差)。

产生静态误差的原因:输出u被外部影响抵消。

消除静态误差的方法:引入积分环节。

积分环节

对输入偏差e进行积分,只要存在偏差,积分环节就会不断起作用,主要用于消除比例环节带来的静态误差

1、Ki越大,消除静态误差的时间越短,越快达到目标值。

2、Ki过大会使系统产生较大的超调和振荡,导致系统的稳定性变差。

3、对于惯性较大的系统,积分环节动态响应较差,容易产生超调、振荡。

只要系统还存在偏差,积分环节就会不断地积累偏差。当系统偏差为0时,说明已经达到目标值,此时的累计偏差不再变化,但是积分环节依旧在发挥作用(此时往往作用最大),这就很容易产生超调的现象。因此,引入微分环节,提前减弱输出,抑制超调的发生。

微分环节

反应偏差量的变化趋势,根据偏差的变化量提前作出相应控制,减小超调,克服振荡。

1、Kd或者变化趋势越大,微分环节作用越强,对超调和振荡的抑制越强。

2、Kd过大会引起系统的不稳定,容易引入高频噪声。 

PID离散公式

PID计算公式有离散公式和连续公式,只是连续公式不利于机器计算,所以展开离散公式说明。

位置式PID公式

该公式的计算需要全部控制量参与,它的每一次输出都和过去的状态有关。

1、Uk直接对应对象的输出(位置),如果计算出现异常,对系统影响很大。

2、全量计算,要对偏差e进行累加,计算量大。

3、在不带积分部件的对象中可以得到很好效果,例如电液伺服阀、温控设备等。

增量式PID公式

该公式的计算并不需要一直累计偏差,它的输出与近三次的偏差有很大的关系。

1、增量式PID计算的是相对上一次输出的增量,即Uk = Uk-1 + △Uk。

2、增量只与近三次的偏差有关,计算出现异常对系统工作影响较小。

3、计算量少,实时性相对较好。

PID离散公式对比

位置式增量式

1、全量计算,计算量大

2、计算出现异常,对系统影响大

3、适用于不带积分部件的对象

1、增量计算,计算量少

2、计算出现异常,对系统影响较小

3、适用于本身带积分部件的对象

PID算法代码实现

PID相关参数

typedef struct
{
    __IO float SetPoint;        /* 目标值 */
    __IO float ActualValue;     /* 期望值 */
    __IO float SumError;        /* 累计偏差 */
    __IO float Proportion;      /* 比例系数P */
    __IO float Integral;        /* 积分系数I */
    __IO float Derivative;      /* 微分系数D */
    __IO float Error;           /* Error[1] */
    __IO float LastError;       /* Error[-1] */
    __IO float PrevError;       /* Error[-2] */
}PID_TypeDef;

PID算法函数实现

1、PID初始化函数:初始化PID相关的参数(清零),设置PID系数值。

2、PID闭环控制函数:实现位置式、增量式PID控制算法。

3、TIM6更新中断函数:调用PID闭环控制函数,计算后返回输出(期望值)。

4、PID上位机调试函数:实现上位机和开发板之间的通讯,进行PID调参。

积分饱和问题

在位置式PID中,如果长时间无法达到目标值,累计偏差(积分)就会变得很大,此时系统的响应就很慢了。

解决方法:

1、优化PID曲线

2、规避可预见的偏差

3、进行积分限幅


PID正点原子上位机

PID调参初体验

硬件接线:开发板串口1→USB转TTL→电脑。

1、纯比例环节

2、比例+积分环节

3、比例+积分+微分环节

PID调参软件:正点原子PID调试助手

PID参数整定

采样周期的选择

采样周期指的是PID控制中实际值的采样时间间隔,其越短,效果越趋于连续,但对硬件资源的占用也越高。

选择范围:

        理论:香农采样定理。该定理可以用来确定采样周期可选择的最大值,当采样周期超出了这个最大的允许范围,我们所得到的信号就会失真,也就无法较好地还原信号。

        经验:实际值突变能力。

PID参数整定方法

理论计算整定法工程整定法
数学模型试凑法、临界比例法、一般调节法

无论哪种方法所得到的参数,都需要在实际运行中根据经验进行调整与完善。

PID参数调节效果:

        比例系数:调节作用快,系统一出现偏差,调节器立即将偏差放大输出。

        积分系数:积分系数的调节会改变输入偏差对于系统输出的影响程度。积分系数越大,消除静态误差的时间越短,但是过大的积分系数则会导致系统出现超调现象,这在具有惯性的系统中尤为明显。

        微分系数:微分系数的调节是偏差变化量对于系统输出的影响程序。微分系数越大,系统对于偏差量的变化越敏感,越能提前响应,进而抑制超调,但是过大的微分系数则会让整个系统出现振荡。

试凑法

内容:结合系统的具体情况以及经验,先试凑几组合理的PID系数,同时需要观察系统的曲线变化,确定每一个系数对于整个系统曲线的大致影响,然后再根据具体的曲线进行调整。

调节思路:

1、先是P,再I,最后D。

2、按纯比例系数整定比例系数,使其得到比较理想的调节过程曲线,然后再把比例系数缩小1.2倍左右,将积分系数从小到大改变,使其得到较好的调节过程曲线。

3、在这个积分系数下重新改变比例系数,再看调节过程曲线有无改善。

4、如有改善,可将原整定的比例系数减少,改变积分系数,这样多次的反复,就可得到合适的比例系数和积分系数。

5、如果存在外界的干扰,系统的稳定性不好,可把比例、积分系数适当减小,使系统足够稳定。

6、如果系统存在小幅度超调,可以将整定好的比例系数和积分系数适当减小,增大微分系数,以得到超调量最小、调节作用时间最短的系统曲线。

临界比例法

内容:在闭环的控制系统里,将调节器置于纯比例作用下,从小到大逐渐调节比例系数,直到系统曲线出现等幅振荡,再根据经验功能计算参数。

调节思路:

1、将积分、微分系数置零,比例度取适当值,平衡操作一段时间,使控制系统按纯比例作用的方式投入运行。

2、慢慢地增大比例系数,细心观察曲线的变化情况。如果控制过程的曲线波动是衰减的,则把比例系数继续增大;如果曲线波动是发散的,则应把比例系数减小,直至曲线波动呈等幅振荡,此时记下临界比例系数&K和临界振荡周期Tk的值。

3、根据记下的比例系数和周期,采用经验公式,计算调节器的参数。

参与控制的环节KpKiKd
P&K/200
PI&K/2.2Kp / (0.833 * Tk)0
PID&K/1.7Kp / (0.5 * Tk)0.125 * Tk * Kp

一般调节法

内容:振荡一般的PID控制系统。

调节思路:

1、首先将积分、微分系数置零,使系统为纯比例控制。控制对象的值设定为系统允许的最大值的60%~70%,接着逐渐增大比例系数,直至系统出现振荡;此时再逐渐减小比例系数,直至系统振荡消失,然后记录此时的比例系数,并设定系统的比例系数为当前值的60%~70%。

2、确定比例系数后,设定一个较小的积分系数,然后逐渐增大积分系数,直至系统出现振荡;此时再逐渐减小积分系数,直至系统振荡消失,然后记录此时的积分系数,并设定系统的积分系数为当前值的55%~65%。

3、微分系数一般不用设定,为0即可。若系统出现小幅度振荡,并且通过PI环节无法优化,这可以采用与确定比例、积分系数相同的方法,微分系数取系统不振荡时的30%左右。

4、系统空载、带载联调,再对PID参数进行微调,直至满足要求。

正点原子PID上位机数据帧格式

数据帧采用CRC16的校验方式,数据帧如下:

帧头数据类别数据域校验和帧尾
0XC51字节。如电机速度、温度等。0~32字节2字节(CRC16-MODBUS校验)0x5C

具体需要查看正点原子PID调试助手通讯协议手册。

代码实现

底层代码: 

1、串口1初始化函数:初始化串口1,开启中断接收,用于上位机通信。

2、内存初始化函数:在指定的地址初始化一段内存(清零)。

3、CRC16校验函数:对帧头、数据类别、数据域进行校验。

4、上位机数据解析函数:解析上位机下发的数据,存进指定的结构体中。

5、数据上传函数:上传指定的数据到上位机。        

应用层代码:

1、初始化调试函数:调用内存初始化底层函数,初始化所需的内存。

2、PID数据上传函数:上传PID参数,设置PID目标值数据同步。

3、一系列数据上传函数:调用底层函数上传函数,上传电流值、电压值等。

4、PID参数接收函数:接收上位机设置的PID参数值。

5、命令接收函数:接收上位机下发的命令,例如电机运行、刹车。

6、速度范围设置函数:限制电机目标速度的范围以及速度的最大突变值。

开发板→上位机枚举上位机→开发板枚举

1、数据类别

2、故障类型

3、电机状态

4、电机类型

1、数据类别

2、下发控制指令

3、下发控制模式

单片机协议发送包长度最大37字节。

单片机协议接收包长度最大17字节。


直流有刷电机速度环PID控制实验

速度闭环控制

PID控制流程:

代码实现步骤:

1、PID参数结构体:定义一个速度闭环的PID参数结构体变量。

2、初始化PID参数:把目标值、期望值、累计偏差清零,配置PID系数。

3、设置目标速度:在主函数中通过按键、上位机设置目标速度。

4、PID闭环控制:在TIM6的更新中断回调里进行PID计算,限制占空比。


直流有刷电机电流环PID控制实验

电流闭环控制

PID控制流程: 

代码实现步骤:

1、PID参数结构体:定义一个电流闭环的PID参数结构体变量。

2、初始化PID参数:把期望值、累计偏差清零,配置目标值、PID系数。

3、实际电流滤波:在ADC1中断回调函数中对实际电流进行滤波。

4、设置目标电流:在主函数中通过按键、上位机设置目标电流。

5、PID闭环控制:在TIM6的更新中断回调里进行PID计算,限制占空比。


直流有刷电机位置环PID控制实验

位置闭环控制

通过编码器当前的计数总值来反映电机的位置。 

PID控制流程:

代码实现步骤:

1、PID参数结构体:定义一个位置闭环的PID参数结构体变量。

2、初始化PID参数:把目标值、期望值、累计偏差清零,配置PID系数。

3、设置目标位置:在主函数中通过按键、上位机设置目标位置。

4、PID闭环控制:在TIM6的更新中断回调里进行PID计算,限制占空比。


直流有刷电机速度+位置双环PID控制实验

双环控制中,外环控制的是优先考虑对象,内环用于对控制效果进行优化。

PID控制流程:

代码实现步骤:

1、PID参数结构体:定义位置、速度闭环的PID参数结构体变量。

2、初始化PID参数:把目标值、期望值、累计偏差清零,配置PID系数。

3、设置目标位置:在主函数中通过按键、上位机设置目标位置。

4、PID闭环控制:在TIM6的更新中断回调里进行PID双环计算,限制输出。

Tips:双环控制时,外环PID参数调节幅度不能太大,这对于整个曲线的影响很大。 


直流有刷电机电流+位置双环PID控制实验

双环控制中,外环控制的是优先考虑对象,内环用于对控制效果进行优化。

PID控制流程:

代码实现步骤:

1、PID参数结构体:定义位置、电流闭环的PID参数结构体变量。

2、初始化PID参数:把目标值、期望值、累计偏差清零,配置PID系数。

3、设置目标位置:在主函数中通过按键、上位机设置目标位置。

4、PID闭环控制:在TIM6的更新中断回调里进行PID双环计算,限制输出。

Tips:双环控制时,外环PID参数调节幅度不能太大,这对于整个曲线的影响很大。 


直流有刷电机电流+速度双环PID控制实验

双环控制中,外环控制的是优先考虑对象,内环用于对控制效果进行优化。

PID控制流程:

代码实现步骤:

1、PID参数结构体:定义速度、电流闭环的PID参数结构体变量。

2、初始化PID参数:把目标值、期望值、累计偏差清零,配置PID系数。

3、设置目标速度:在主函数中通过按键、上位机设置目标速度。

4、PID双环控制:在TIM6的更新中断回调里进行PID双环计算,限制输出。

Tips:双环控制时,外环PID参数调节幅度不能太大,这对于整个曲线的影响很大。 


直流有刷电机三环PID控制实验

PID控制流程:

代码实现步骤:

1、PID参数结构体:定义位置、速度、电流闭环的PID参数结构体变量。

2、初始化PID参数:把目标值、期望值、累计偏差清零,配置PID系数。

3、设置目标速度:在主函数中通过按键、上位机设置目标位置。

4、PID双环控制:在TIM6的更新中断回调里进行PID三环计算,限制输出。

<think>好的,我现在要解决用户在IAR编译器中遇到的错误:“incomplete type is not allowed”。首先,我需要理解这个错误的含义和常见原因。根据我的知识库,这个错误通常发生在代码中使用了未完全定义的类型,比如结构体或联合体声明了但未定义,或者前向声明了某个类型但没有提供完整的定义。 首先,我应该检查用户代码中是否有结构体或联合体的声明但没有定义的情况。比如,如果有一个结构体声明为`struct MyStruct;`,但没有后续的完整定义,那么在需要该结构体大小或成员的地方,编译器就会报这个错误。这时候,需要用户补全结构体的定义,包括成员变量。 其次,检查是否在头文件中只声明了类型而没有包含定义。例如,如果在头文件中使用前向声明,但在使用该类型的源文件中没有包含实际的定义头文件,这也会导致错误。此时,需要确保在使用类型的地方包含了正确的头文件,或者将前向声明替换为完整的定义。 另外,还要考虑typedef的问题。如果用户使用了typedef创建别名,但原始类型未完全定义,同样会引发错误。例如,`typedef struct MyStruct MyType;`之后,如果尝试使用MyType但MyStruct尚未定义,就会出错。需要确保在使用typedef之前,原始类型已经被完整定义。 此外,数组声明中的类型不完整也是一个常见原因。比如声明数组时,如果元素类型未完全定义,编译器无法确定数组的大小,导致错误。需要检查数组声明中的类型是否已经完整定义。 可能还有其他情况,比如在C和C++混合编程时,如果没有正确使用extern "C",或者在头文件中遗漏了必要的包含,也可能导致类型不完整。需要用户检查这些方面。 接下来,我需要将这些可能的原因整理成清晰的解决步骤,并给出具体的代码示例,帮助用户理解如何修改。同时,根据用户提供的引用内容,虽然引用[1]和引用[2]是关于其他错误的,但用户可能希望看到类似的结构,即分点说明解决方案,并引用相关资源。 最后,生成相关问题,帮助用户进一步了解可能相关的编译错误,比如类型未定义、前向声明问题等。这样用户可以有更全面的认识,预防其他类似错误的发生。</think>### IAR编译器错误'incomplete type is not allowed'解决方案 该错误表示代码中使用了**未完全定义的类型**,编译器无法确定其内存布局或成员信息。以下是具体原因及解决方法: #### 1. 结构体/联合体未定义完整 若声明了结构体但未定义成员,在实例化时会报错: ```c struct MyStruct; // 前向声明不完整 struct MyStruct var; // 错误:使用未完成类型 ``` **解决方案**:补全类型定义 ```c struct MyStruct { int id; char name[20]; }; ``` #### 2. 头文件包含缺失 当跨文件使用类型时,需确保定义可见: ```c // file.h struct Data; // 前向声明 // file.c struct Data { // 实际定义 int value; }; ``` **解决方案**:在使用该类型的文件中包含定义头文件 ```c #include "file.c" // 包含实际定义 ``` #### 3. typedef别名问题 使用typedef时原始类型必须完整: ```c typedef struct Node NodeT; // 前向声明 NodeT* ptr; // 允许指针声明 NodeT instance; // 错误:不完整类型 ``` **解决方案**:先完成类型定义再typedef ```c struct Node { int data; struct Node* next; }; typedef struct Node NodeT; ``` #### 4. 数组声明不完整 数组元素类型必须完全定义: ```c struct Element; struct Element arr[10]; // 错误:元素类型未定义 ``` **解决方案**: ```c struct Element { int type; float value; }; struct Element arr[10]; // 合法 ``` #### 调试建议 1. 在IAR工程中搜索错误行号定位问题代码 2. 使用Go to Definition功能追踪类型定义 3. 检查所有头文件包含链 4. 确认没有循环依赖的头文件 编译器需要知道类型的完整信息才能: - 计算sizeof大小 - 分配内存空间 - 访问成员变量 - 进行类型对齐 [^1]: 类似类型转换错误可参考浮点转整型的类型适配问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值