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 稳定**
