你会使用ARM官方的PID控制吗?

[复制链接]
2279|14
 楼主| zeshoufx 发表于 2022-11-8 21:53 | 显示全部楼层 |阅读模式
本帖最后由 zeshoufx 于 2022-11-8 22:02 编辑

ARM DSP库控制函数包括了经典的PID控制,PID控制在工程领域运用广泛,本文就ARM的PID函数进行测试。

测试方案:将ADC采集结果作为控制目标,ADC与DAC连接,DAC作为被控对象。目标参考值为ADC 2678,打印输出,导入MATLAB。

ADC和DAC设置函数:
  1. #include "dsp_test.h"
  2. #include "systick.h"

  3. arm_pid_instance_f32 S;                //定义PID结构体
  4. float ref=2678./4095*3.3;        //ADC参考目标值:2678

  5. void ad_da_init(void)
  6. {
  7.         //时钟配置
  8.         rcu_periph_clock_enable(RCU_GPIOA);
  9.         rcu_periph_clock_enable(RCU_AF);
  10.         rcu_periph_clock_enable(RCU_ADC0);
  11.         rcu_periph_clock_enable(RCU_DAC);
  12.         
  13.         rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV12);
  14.         
  15.         //接口配置
  16.         gpio_init(GPIOA,GPIO_MODE_AIN,GPIO_OSPEED_50MHZ,GPIO_PIN_4);
  17.         gpio_init(GPIOA,GPIO_MODE_AIN,GPIO_OSPEED_50MHZ,GPIO_PIN_6);
  18.         
  19.         //ADC输入配置
  20.         adc_special_function_config(ADC0,ADC_CONTINUOUS_MODE,ENABLE);
  21.         adc_data_alignment_config(ADC0,ADC_DATAALIGN_RIGHT);
  22.         adc_channel_length_config(ADC0,ADC_REGULAR_CHANNEL,1);
  23.         adc_regular_channel_config(ADC0,0,ADC_CHANNEL_6,ADC_SAMPLETIME_55POINT5);
  24.         adc_external_trigger_config(ADC0,ADC_REGULAR_CHANNEL,DISABLE);
  25.         
  26.         adc_enable(ADC0);
  27.         delay_ms(1);
  28.         adc_calibration_enable(ADC0);
  29.         
  30.         //DAC输出配置
  31.         dac_trigger_source_config(DAC0,DAC_TRIGGER_SOFTWARE);
  32.         dac_trigger_enable(DAC0);
  33.         dac_wave_mode_config(DAC0,DAC_WAVE_DISABLE);
  34.         dac_output_buffer_enable(DAC0);
  35.         
  36.         dac_enable(DAC0);
  37.         
  38.         //PID参数初始化
  39.         S.Kd=0;
  40.         S.Ki=16;
  41.         S.Kp=100;

  42.         arm_pid_init_f32(&S,1);
  43. }



  44. volatile float adc_get=0.;

  45. void dsp_test(void)
  46. {
  47.          
  48.         float32_t pid_num=0.;
  49.         
  50.         pid_num=arm_pid_f32(&S,ref-adc_get);        //PID处理,输入为误差信号

  51.         if(pid_num>=4095)
  52.         {
  53.                 pid_num=4095;
  54.         }
  55.     dac_data_set(DAC0, DAC_ALIGN_12B_R, (u16)pid_num);
  56.       
  57.     dac_software_trigger_enable(DAC0);
  58.         
  59.         adc_software_trigger_enable(ADC0,ADC_REGULAR_CHANNEL);
  60.         if(adc_flag_get(ADC0,ADC_FLAG_EOC))
  61.         {
  62.                 adc_flag_clear(ADC0,ADC_FLAG_EOC);
  63.                 adc_get = adc_regular_data_read(ADC0)/4095.*3.3;
  64.         }
  65.         
  66.         printf("%f        %d        %d\r\n",adc_get,(u16)pid_num,adc_regular_data_read(ADC0));
  67. }



主函数:
  1. /*!
  2.     \file    main.c
  3.     \brief   led spark with systick, USART print and key example

  4.     \version 2014-12-26, V1.0.0, firmware for GD32F10x
  5.     \version 2017-06-20, V2.0.0, firmware for GD32F10x
  6.     \version 2018-07-31, V2.1.0, firmware for GD32F10x
  7.     \version 2020-09-30, V2.2.0, firmware for GD32F10x
  8. */



  9. #include "bitband.h"
  10. #include "led.h"
  11. #include "systick.h"
  12. #include "print.h"
  13. #include "dsp_test.h"

  14. u16 mem_infor[2]={0};
  15. u32 uid[3]={0};


  16. int main(void)
  17. {
  18.     systick_set(96);
  19.         led_init();
  20.         
  21.         print_config(9600);
  22.         
  23.         get_mem_infor(&mem_infor[0],&mem_infor[1]);
  24.         printf("GD32F103VKT6 Flash Size=%dKB,Sram Size=%dKB...\r\n",mem_infor[1],mem_infor[0]);
  25.         get_uid(uid);
  26.         printf("GD32F103VKT6 UID=%d%d%d...\r\n",uid[0],uid[1],uid[2]);
  27.         
  28.         ad_da_init();
  29.         
  30.     while(1)
  31.         {
  32.                 dsp_test();
  33.                 delay_ms(100);
  34.     }
  35. }



测试结果:

测试专栏:B站
ARM DSP库 PID控制测试 - 哔哩哔哩 (bilibili.com)
https://www.bilibili.com/read/cv19572818?spm_id_from=333.999.0.0
测试视频:B站
ARM单片机PID控制测试——基于DSP库_哔哩哔哩_bilibili
https://www.bilibili.com/video/BV1sd4y1w755/?spm_id_from=333.999.0.0&vd_source=bd87efa6e82a7807416b49f807f9fb1f

测试说明:由于演示PID参数是随便填写的,效果不一定是最佳的,大家可以通过MATLAB仿真后,获得较优的参数,效果可能更好。


测试结果

测试结果

PID

PID
Diyer123 发表于 2022-11-9 19:29 | 显示全部楼层
光PID计算公式没什么……
有参数自整定就实用了
 楼主| zeshoufx 发表于 2022-11-9 20:10 | 显示全部楼层
Diyer123 发表于 2022-11-9 19:29
光PID计算公式没什么……
有参数自整定就实用了

是的,,参数自整定是一个研究方向的
tpgf 发表于 2022-12-3 08:51 | 显示全部楼层
PID控制器(比例-积分-微分控制器)是一个在工业控制应用中常见的反馈回路部件,由比例单元P、积分单元I和微分单元D组成。
nawu 发表于 2022-12-3 09:06 | 显示全部楼层
PID控制的基础是比例控制;积分控制可消除稳态误差,但可能增加超调;微分控制可加快大惯性系统响应速度以及减弱超调趋势。
aoyi 发表于 2022-12-3 10:29 | 显示全部楼层
PID参数自整定控制仪可选择外给定(或阀位)控制功能。可取代伺服放大器直接驱动执行机构(如阀门等)。
zljiu 发表于 2022-12-3 10:53 | 显示全部楼层
PID适用于需要进行高精度测量控制的系统,可根据被控对象自动演算出最佳PID控制参数。
gwsan 发表于 2022-12-3 12:01 | 显示全部楼层
PID控制器简单易懂,使用中不需精确的系统模型等先决条件
OKAKAKO 发表于 2022-12-3 13:20 | 显示全部楼层
PID控制其实在电机驱动控制应用的还是挺多的,精准算法也有好多需要研究的
tfqi 发表于 2022-12-3 13:23 | 显示全部楼层
感觉pid控制的难点就在于参数非常不好确定
chenjun89 发表于 2022-12-3 18:12 来自手机 | 显示全部楼层
免费开源不?若果是的话可以用。
Jacquetry 发表于 2022-12-21 17:31 | 显示全部楼层
PID控制的基础是比例控制
星辰大海不退缩 发表于 2022-12-22 16:34 | 显示全部楼层
PID控制在控制算法领域用的其实还是挺多的,PID算法也算是比较经典
jf101 发表于 2022-12-24 13:24 | 显示全部楼层
自动控制原理里面对PID讲解的还是比较透彻的,一般就是用各种算法和方程对不同输入达到稳定的算法,当然PID算法对于电机控制还是应用比较广泛的
czy90 发表于 2023-1-12 09:19 | 显示全部楼层
感谢分享。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

67

主题

1991

帖子

15

粉丝
快速回复 在线客服 返回列表 返回顶部