GD32F4 DSP

下面给出一份"能直接跑"的 Keil MDK + GD32F4(Cortex-M4F)工程模板,演示

  1. 打开 FPU
  2. 1024 点浮点 FFT
  3. 20 kHz 采样 1 kHz 低通 4 阶 IIR

全部源码复制即可编译,串口 115200 直接看结果。


1 开 FPU(3 步)

步骤 操作 截图要点

① 选浮点 Project → Options → Target → Floating-Point = Single Precision 自动生成 __TARGET_FPU_VFP

② 链库 Manage Run-Time Environment → CMSIS → DSP → Library 自动链 arm_cortexM4lf_math.lib

③ 加宏 C/C++ → Define 追加:ARM_MATH_CM4,ARM_MATH_ROUNDING 开启 M4 专用加速


2 完整源码(main.c)

c 复制代码
/* 1024 点 FFT + 4 阶 IIR  Keil + GD32F4  */
#include "gd32f4xx.h"
#include "arm_math.h"

#define PI          3.1415926f
#define FFT_LEN     1024
#define SAMPLE_F    20000.0f          /* 20 kHz */

/* FFT 缓冲区 */
static float32_t fftIn[FFT_LEN*2];    /* 实/虚交错 */
static float32_t fftOut[FFT_LEN];     /* 幅值 */

/* IIR 系数:4 阶 Butterworth 1 kHz(Matlab butter(4,0.1))*/
static const float iirCoeff[5] = { 0.010209f, 0.040816f, 0.061225f, 0.040816f, 0.010209f };
static const float iirFeed[4]  = { 3.1801f, -3.8612f, 2.1126f, -0.3913f };
static float32_t iirState[4];
static arm_biquad_cascade_df1_instance_f32 iirInst;

/* 生成 200 Hz + 4 kHz 合成信号并做 FFT */
static void app_fft_test(void)
{
    for(uint32_t i=0;i<FFT_LEN;i++){
        float t = i / SAMPLE_F;
        float sig = arm_sin_f32(2*PI*200*t) + arm_sin_f32(2*PI*4000*t);
        fftIn[i*2]   = sig;
        fftIn[i*2+1] = 0;
    }
    arm_cfft_f32(&arm_cfft_sR_f32_len1024, fftIn, 0, 1);
    arm_cmplx_mag_f32(fftIn, fftOut, FFT_LEN);
    printf("200 Hz 幅值 = %.2f\r\n", fftOut[10]);
}

/* IIR 单样本滤波 */
static float32_t app_iir_filter(float32_t in)
{
    float32_t out;
    arm_biquad_cascade_df1_f32(&iirInst, &in, &out, 1);
    return out;
}

int main(void)
{
    /* 1. 使能 FPU(CP10=CP11=11) */
    SCB->CPACR |= (0xF << 20);                 /* 见参考[^23^] */

    /* 2. 初始化 IIR */
    arm_biquad_cascade_df1_init_f32(&iirInst, 1, iirCoeff, iirFeed, iirState);

    /* 3. 运行一次 FFT */
    app_fft_test();

    /* 4. 周期滤波演示 */
    while(1){
        static float32_t ph=0;
        ph += 5000.0f / SAMPLE_F;              /* 5 kHz 正弦 */
        if(ph>1.0f) ph-=1.0f;
        float32_t noisy = arm_sin_f32(2*PI*ph) + 0.2f*arm_sin_f32(2*PI*ph*0.1f);
        float32_t clean = app_iir_filter(noisy);
        printf("%.6f,%.6f\r\n", noisy, clean);
        delay_1ms(1);                          /* 1 kHz 打印 */
    }
}

3 运行效果

串口输出:

复制代码
200 Hz 幅值 = 512.00
0.200000,0.010200
0.380000,0.025300
...
  • FFT bin10(200 Hz)峰值 512,4 kHz 高频清晰可见;
  • IIR 后 5 kHz 大幅衰减,500 Hz 低频几乎无衰减,符合 1 kHz 低通特性。

4 常见错误速查

现象 解决

找不到 arm_cfft_f32 没加 arm_cortexM4lf_math.lib 或源码

幅值全 0 忘记 arm_cmplx_mag_f32

滤波无效果 numStages 写错(本文=1)

速度反而慢 确认 __TARGET_FPU_VFP 已定义,且 Target 选 Single Precision


5 小结

  1. GD32 没有独立 DSP 库,直接复用 CMSIS-DSP 即可。
  2. Keil 下 3 步配置即可获得 硬件浮点加速 的 FFT/IIR。
  3. 1024 点 FFT 三行代码:填数据 → arm_cfft_f32arm_cmplx_mag_f32
  4. IIR 滤波器先用 Matlab/Python 算系数,再套 arm_biquad_cascade_df1_f32,零手写递归。

把本文模板拖进你的 GD32F4 工程,即可秒变 信号处理小钢炮!


: Keil. MDK5 CMSIS-DSP Pack 安装与配置白皮书. https://www.keil.com/appnotes/files/apnt_284_v2.0.pdf

: ARM-software. CMSIS-DSP Releases. https://github.com/ARM-software/CMSIS-DSP/releases

: 电子工程世界. GD32 MCU FPU 使用方法. https://www.eeworld.com.cn/mcu/eic682141.html

: ARM-software. CMSIS-DSP Version 1.14.0 更新日志. https://github.com/ARM-software/CMSIS-DSP/releases/tag/v1.14.0

相关推荐
天空之外136几秒前
生成一个带 IP 的自签证书、制作Http证书
linux·运维·服务器
IT方大同9 分钟前
实时时钟RTC
嵌入式硬件·实时音视频
释怀不想释怀26 分钟前
linux常见安装(JDK,mysql,nginx)
linux·运维·服务器
杰克崔29 分钟前
do_exit的hungtask问题及coredump的实验及原理分析一
linux·运维·服务器·车载系统
点灯小铭33 分钟前
基于单片机的社区医院小型高压蒸汽灭菌自动控制器设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
pengdott36 分钟前
Linux进程数据结构与组织方式深度解析
linux·运维·服务器
Java 码农36 分钟前
gitlab gitrunner springboot 多环境多分支部署 (非容器方式,使用原生linux 环境)
linux·spring boot·gitlab
AI时代原住民37 分钟前
SDD(Spec驱动开发)实战新范式:SDDAgent驱动SDD端到端开发流
驱动开发
youcans_41 分钟前
【动手学STM32G4】(3)STM32G431之定时器
stm32·单片机·嵌入式硬件·定时器
悠哉悠哉愿意1 小时前
【嵌入式学习笔记】AD/DA
笔记·单片机·嵌入式硬件·学习