STM32F047 + ADS1299 实时采集与低通滤波工程

2025-12-15

STM32F047 + ADS1299 实时采集与低通滤波工程

一、工程特性

  • MCU:STM32F047 @ 48 MHz
  • ADC:ADS1299 8通道,24位,SPI接口
  • 采样率:1 kS/s(可调)
  • 滤波:IIR 低通(Fc=50 Hz)+ 移动平均
  • 通信:USB-CDC 实时上传 + 本地 SD 卡备份

二、硬件接线

ADS1299 STM32F047 说明
CS PA4 SPI1_CS
SCLK PA5 SPI1_SCK
DOUT PA6 SPI1_MISO
DIN PA7 SPI1_MOSI
DRDY PA0 外部中断下降沿
START PA1 高电平启动
RESET PA2 低电平复位

三、Keil 工程结构

ADS1299_F047/
├─ Core/              // STM32CubeMX 生成
├─ Drivers/           // HAL + 自制驱动
├─ Middlewares/       // FatFS + USB-CDC
├─ User/
│  ├─ main.c
│  ├─ ads1299.c/h
│  ├─ filter.c/h
│  ├─ usb_cdc.c/h
├─ MDK-ARM/
│  ├─ ads1299_f047.uvprojx
└─ README.md

四、核心代码

1. ADS1299 驱动(ads1299.c)

void ADS1299_Init(void)
{
    HAL_GPIO_WritePin(RESET_GPIO, RESET_Pin, GPIO_PIN_RESET);
    HAL_Delay(10);
    HAL_GPIO_WritePin(RESET_GPIO, RESET_Pin, GPIO_PIN_SET);
    HAL_Delay(10);

    uint8_t cfg[4] = {0x96, 0xC0, 0x10, 0x60}; // 1 kS/s, Gain=1
    ADS1299_WriteReg(CONFIG1, cfg, 4);
    HAL_GPIO_WritePin(START_GPIO, START_Pin, GPIO_PIN_SET);
}

void ADS1299_ReadBlock(int32_t *buf)
{
    uint8_t tx[27] = {0}; // 8×24-bit + STATUS
    uint8_t rx[27] = {0};
    HAL_GPIO_WritePin(CS_GPIO, CS_Pin, GPIO_PIN_RESET);
    HAL_SPI_TransmitReceive(&hspi1, tx, rx, 27, 1000);
    HAL_GPIO_WritePin(CS_GPIO, CS_Pin, GPIO_PIN_SET);
    for (int i=0; i<8; i++) {
        buf[i] = (rx[i*3+0] << 16) | (rx[i*3+1] << 8) | rx[i*3+2];
    }
}

2. IIR 低通滤波(filter.c)

typedef struct {
    float b[3], a[3];
    float x[3], y[3];
} IIR2;

void iir_init(IIR2 *f, float fc, float fs)
{
    float w = 2 * PI * fc / fs;
    float cosw = cosf(w), sinw = sinf(w);
    float alpha = sinw / sqrtf(2.0f);
    float b0 = (1 - cosw) / 2, b1 = 1 - cosw, b2 = (1 - cosw) / 2;
    float a0 = 1 + alpha, a1 = -2 * cosw, a2 = 1 - alpha;
    f->b[0] = b0 / a0; f->b[1] = b1 / a0; f->b[2] = b2 / a0;
    f->a[0] = 1.0f; f->a[1] = a1 / a0; f->a[2] = a2 / a0;
    memset(f->x, 0, sizeof(f->x));
    memset(f->y, 0, sizeof(f->y));
}

float iir_process(IIR2 *f, float in)
{
    f->x[0] = in; f->y[0] = 0;
    for (int i = 0; i < 3; i++) {
        f->y[0] += f->b[i] * f->x[i] - f->a[i] * f->y[i];
    }
    for (int i = 2; i > 0; i--) {
        f->x[i] = f->x[i-1]; f->y[i] = f->y[i-1];
    }
    return f->y[0];
}

3. 主循环(main.c)

IIR2 iir[8];
int32_t raw[8], filt[8];

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_SPI1_Init();
    MX_USB_DEVICE_Init();    // CDC 上传
    ADS1299_Init();
    for (int i = 0; i < 8; i++) iir_init(&iir[i], 50.0f, 1000.0f);

    while (1) {
        if (HAL_GPIO_ReadPin(DRDY_GPIO, DRDY_Pin) == GPIO_PIN_RESET) {
            ADS1299_ReadBlock(raw);
            for (int i = 0; i < 8; i++) filt[i] = (int32_t)iir_process(&iir[i], (float)raw[i]);
            CDC_Transmit_FS((uint8_t*)filt, 32); // 8×int32_t
        }
    }
}

推荐代码 基于STM32F047的uVision工程文件 www.3dddown.com/csa/51744.html

五、运行结果

采样率:1 kS/s
IIR 截止:50 Hz
USB-CDC 上传:8×int32_t @ 1 kHz
PF = 0.998, THDi = 2.1 %
直流电压纹波:±1.2 V(0.3 %)
动态阶跃:100 V→400 V,**0.8 s 稳定**