本帖最后由 zeshoufx 于 2022-11-8 22:02 编辑
ARM DSP库控制函数包括了经典的PID控制,PID控制在工程领域运用广泛,本文就ARM的PID函数进行测试。
测试方案:将ADC采集结果作为控制目标,ADC与DAC连接,DAC作为被控对象。目标参考值为ADC 2678,打印输出,导入MATLAB。
ADC和DAC设置函数:
#include "dsp_test.h"
#include "systick.h"
arm_pid_instance_f32 S; //定义PID结构体
float ref=2678./4095*3.3; //ADC参考目标值:2678
void ad_da_init(void)
{
//时钟配置
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_AF);
rcu_periph_clock_enable(RCU_ADC0);
rcu_periph_clock_enable(RCU_DAC);
rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV12);
//接口配置
gpio_init(GPIOA,GPIO_MODE_AIN,GPIO_OSPEED_50MHZ,GPIO_PIN_4);
gpio_init(GPIOA,GPIO_MODE_AIN,GPIO_OSPEED_50MHZ,GPIO_PIN_6);
//ADC输入配置
adc_special_function_config(ADC0,ADC_CONTINUOUS_MODE,ENABLE);
adc_data_alignment_config(ADC0,ADC_DATAALIGN_RIGHT);
adc_channel_length_config(ADC0,ADC_REGULAR_CHANNEL,1);
adc_regular_channel_config(ADC0,0,ADC_CHANNEL_6,ADC_SAMPLETIME_55POINT5);
adc_external_trigger_config(ADC0,ADC_REGULAR_CHANNEL,DISABLE);
adc_enable(ADC0);
delay_ms(1);
adc_calibration_enable(ADC0);
//DAC输出配置
dac_trigger_source_config(DAC0,DAC_TRIGGER_SOFTWARE);
dac_trigger_enable(DAC0);
dac_wave_mode_config(DAC0,DAC_WAVE_DISABLE);
dac_output_buffer_enable(DAC0);
dac_enable(DAC0);
//PID参数初始化
S.Kd=0;
S.Ki=16;
S.Kp=100;
arm_pid_init_f32(&S,1);
}
volatile float adc_get=0.;
void dsp_test(void)
{
float32_t pid_num=0.;
pid_num=arm_pid_f32(&S,ref-adc_get); //PID处理,输入为误差信号
if(pid_num>=4095)
{
pid_num=4095;
}
dac_data_set(DAC0, DAC_ALIGN_12B_R, (u16)pid_num);
dac_software_trigger_enable(DAC0);
adc_software_trigger_enable(ADC0,ADC_REGULAR_CHANNEL);
if(adc_flag_get(ADC0,ADC_FLAG_EOC))
{
adc_flag_clear(ADC0,ADC_FLAG_EOC);
adc_get = adc_regular_data_read(ADC0)/4095.*3.3;
}
printf("%f %d %d\r\n",adc_get,(u16)pid_num,adc_regular_data_read(ADC0));
}
主函数:
/*!
\file main.c
\brief led spark with systick, USART print and key example
\version 2014-12-26, V1.0.0, firmware for GD32F10x
\version 2017-06-20, V2.0.0, firmware for GD32F10x
\version 2018-07-31, V2.1.0, firmware for GD32F10x
\version 2020-09-30, V2.2.0, firmware for GD32F10x
*/
#include "bitband.h"
#include "led.h"
#include "systick.h"
#include "print.h"
#include "dsp_test.h"
u16 mem_infor[2]={0};
u32 uid[3]={0};
int main(void)
{
systick_set(96);
led_init();
print_config(9600);
get_mem_infor(&mem_infor[0],&mem_infor[1]);
printf("GD32F103VKT6 Flash Size=%dKB,Sram Size=%dKB...\r\n",mem_infor[1],mem_infor[0]);
get_uid(uid);
printf("GD32F103VKT6 UID=%d%d%d...\r\n",uid[0],uid[1],uid[2]);
ad_da_init();
while(1)
{
dsp_test();
delay_ms(100);
}
}
测试结果:
测试专栏: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仿真后,获得较优的参数,效果可能更好。
|