Для подключения этой библиотеки нужно поставить галочку напротив DSP в менеджере библиотек в keil.

В самом файле проекта перед подключением необходимо указать на каком ядре построен МК.
#define ARM_MATH_CM3
Затем подключить
#include "arm_math.h"
После этого мы можем использовать функции CMSIS-DSP. Нас интересует фун-ции PID Motor Control.
Эти функции подразделяются на группы функций работающие с типом данных q15, q31, f32. Тип данных q15, q31 fixed point,
f32 float point.
Алгоритм работы можно посмотреть там где описание библиотеки DSP. http://arm-software.github.io/CMSIS_5/DSP/html/group__PID.html
Вот сама функция на СИ
CMSIS_INLINE __STATIC_INLINE float32_t arm_pid_f32(
arm_pid_instance_f32 * S,
float32_t in)
{
float32_t out;
/* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */
out = (S->A0 * in) +
(S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]);
/* Update state */
S->state[1] = S->state[0];
S->state[0] = in;
S->state[2] = out;
/* return to application */
return (out);
}
вот структура типов данных которая заполняется перед использованием функции
typedef struct
{
float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */
float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */
float32_t A2; /**< The derived gain, A2 = Kd . */
float32_t state[3]; /**< The state array of length 3. */
float32_t Kp; /**< The proportional gain. */
float32_t Ki; /**< The integral gain. */
float32_t Kd; /**< The derivative gain. */
} arm_pid_instance_f32;
Тут Kp-пропорциональный коэффициент, Ki-интегральный коэффициент, Kd-дифференциальный коэффициент; float32_t state[3]; это /* Update state */ S->state[1] = S->state[0]; S->state[0] = in; S->state[2] = out;
Перед заполнением структуры данных функции её нужно для начала объявить
/* ARM PID Instance, float_32 format */ arm_pid_instance_f32 PID;
Затем можно заполнить структуру данных требуемыми параметрами
/* Set PID parameters */
/* Set this for your needs */
PID.Kp = PID_PARAM_KP; /* Proporcional */
PID.Ki = PID_PARAM_KI; /* Integral */
PID.Kd = PID_PARAM_KD; /* Derivative */
Проинициализировать функцию
/* Initialize PID system, float32_t format */
arm_pid_init_f32(&PID, 1);
И теперь можно использовать функцию вычисления ПИД регулятора
duty = arm_pid_f32(&PID, pid_error);
Где PID — указатель на структуру данных;
pid_error — сигнал ошибки, рассогласования (тип переменной float), объявлен в начале программы;
duty — это значение с выхода фун-ции;
Для борьбы с эффектом windup в пид регуляторах — это когда управляющее значение с выхода пид регулятора не может обеспечить устранения рассоглосования между измереными значениями и заданными, в результате чего копится интегральная составляющая и при изменении (уменьшении) заданного значения ПИД регулятор может продолжительное время не реагировать на это входное значение.


с anti windup
if (duty > max_PID) {
duty = max_PID;
PID.state[2] = max_PID;
} else if (duty < min_PID) {
duty = min_PID;
PID.state[2] = min_PID;
}
max_PID — максимальное выходное значение с ПИД;
min_PID — минимальное значение c ПИД регулятора.
материал в интернете с использованием этой фун-ции.