当前位置: 首页 > news >正文

基于STM32F047的ADS1299数据采集与低通滤波系统实现

基于STM32F047的ADS1299数据采集与低通滤波系统实现:


一、硬件设计要点

1. 核心电路连接

STM32F047          ADS1299
----------------------
SPI1_SCK (PA5)  → SCLK
SPI1_MOSI (PA7) → DIN
SPI1_MISO (PA6) → DOUT
PA4 (GPIO)      → CS
PB0 (GPIO)      → DRDY
3.3V            → AVDD/DVDD
GND             → AGND/DGND
VREF+           → 2.5V外部基准

2. 抗干扰设计

  • 电源滤波:AVDD和DVDD间添加10μF电解电容+0.1μF陶瓷电容
  • 信号调理:DRDY信号串联1kΩ电阻+0.1μF电容
  • PCB布局:模拟地与数字地通过0Ω电阻单点连接

二、软件实现方案

1. ADS1299驱动代码

// ads1299.h
#ifndef __ADS1299_H__
#define __ADS1299_H__#define ADS1299_ADDR 0x50 << 1  // 7位地址左移1位
#define ADS1299_CS_PIN  GPIO_PIN_4
#define ADS1299_CS_PORT GPIOA// 寄存器地址定义
#define ADS1299_REG_CONFIG1 0x00
#define ADS1299_REG_CONFIG2 0x01
#define ADS1299_REG_LOFF    0x02// 初始化函数
void ADS1299_Init(void);
uint32_t ADS1299_ReadData(void);
void ADS1299_SetChannel(uint8_t channel);#endif // __ADS1299_H__
// ads1299.c
#include "ads1299.h"void ADS1299_Init(void) {// 硬件复位HAL_GPIO_WritePin(ADS1299_CS_PORT, ADS1299_CS_PIN, GPIO_PIN_RESET);HAL_Delay(100);HAL_GPIO_WritePin(ADS1299_CS_PORT, ADS1299_CS_PIN, GPIO_PIN_SET);HAL_Delay(100);// 配置寄存器ADS1299_WriteReg(ADS1299_REG_CONFIG1, 0x80);  // 12位模式,连续转换ADS1299_WriteReg(ADS1299_REG_CONFIG2, 0x00);  // 默认配置
}uint32_t ADS1299_ReadData(void) {uint8_t buffer[3] = {0};HAL_GPIO_WritePin(ADS1299_CS_PORT, ADS1299_CS_PIN, GPIO_PIN_RESET);HAL_SPI_Transmit(&hspi1, (uint8_t*)0x01, 1, 100);  // 发送读命令HAL_SPI_Receive(&hspi1, buffer, 3, 100);HAL_GPIO_WritePin(ADS1299_CS_PORT, ADS1299_CS_PIN, GPIO_PIN_SET);return (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
}void ADS1299_SetChannel(uint8_t channel) {uint8_t config = 0x00;config |= (channel & 0x07) << 4;ADS1299_WriteReg(ADS1299_REG_CONFIG1, config);
}

2. 低通滤波实现

// lpf.h
#ifndef __LPF_H__
#define __LPF_H__typedef struct {float prev_output;float alpha;
} LPF_Filter;void LPF_Init(LPF_Filter *filter, float cutoff_freq, float sample_rate);
float LPF_Update(LPF_Filter *filter, float input);#endif // __LPF_H__
// lpf.c
#include "lpf.h"void LPF_Init(LPF_Filter *filter, float cutoff_freq, float sample_rate) {float RC = 1.0f / (2 * 3.1415926f * cutoff_freq);float dt = 1.0f / sample_rate;filter->alpha = dt / (RC + dt);filter->prev_output = 0.0f;
}float LPF_Update(LPF_Filter *filter, float input) {filter->prev_output = filter->alpha * input + (1 - filter->alpha) * filter->prev_output;return filter->prev_output;
}

3. 主程序流程

// main.c
#include "main.h"
#include "ads1299.h"
#include "lpf.h"LPF_Filter eeg_filter;
ADC_HandleTypeDef hadc1;int main(void) {HAL_Init();SystemClock_Config();// 初始化外设MX_SPI1_Init();MX_ADC1_Init();ADS1299_Init();LPF_Init(&eeg_filter, 100.0f, 1000.0f);  // 100Hz截止频率,1kHz采样率while (1) {// 采集原始数据uint32_t raw = ADS1299_ReadData();// 转换为电压值float voltage = (raw * 2.5f) / 0xFFFFFF;// 低通滤波float filtered = LPF_Update(&eeg_filter, voltage);// 数据处理...HAL_Delay(1);}
}

推荐代码 基于STM32F047的uVision工程文件 www.youwenfan.com/contentcng/51744.html

三、关键参数配置

参数 数值 说明
SPI时钟频率 2MHz 满足ADS1299 20MHz最大要求
采样率 1kHz 符合脑电信号处理需求
滤波截止频率 100Hz 抑制高频噪声
参考电压 2.5V外部基准 提高ADC精度

四、工程文件结构

ADS1299_Project/
├── Core/
│   ├── Inc/
│   │   ├── ads1299.h      // ADS1299驱动头文件
│   │   ├── lpf.h          // 低通滤波头文件
│   │   └── main.h         // 主程序头文件
│   └── Src/
│       ├── ads1299.c      // ADS1299驱动实现
│       ├── lpf.c          // 滤波算法实现
│       └── main.c         // 主程序
├── Drivers/
│   ├── CMSIS/
│   └── STM32F0xx_HAL_Driver/
└── Middlewares/└── USB/

五、性能优化方案

  1. DMA传输

    // 启用ADC DMA
    hadc1.Instance = ADC1;
    hadc1.Init.DMAContinuousRequests = ENABLE;
    HAL_DMA_Start(&hdma_adc1, (uint32_t)&ADC1->DR, (uint32_t)adc_buffer, 100);
    
  2. 中断处理

    void EXTI0_IRQHandler(void) {if (EXTI_GetITStatus(EXTI_LINE0) != RESET) {HAL_ADC_Stop_DMA(&hadc1);// 处理数据...HAL_ADC_Start_DMA(&hadc1, (uint32_t)&ADC1->DR, 100);}
    }
    
  3. 数据校验

    uint8_t CRC_Check(uint8_t *data, uint8_t len) {uint8_t crc = 0;for (int i=0; i<len; i++) {crc ^= data[i];for (int j=0; j<8; j++) {crc = (crc & 0x80) ? (crc << 1) ^ 0x31 : crc << 1;}}return crc;
    }
    

六、调试与验证

  1. 逻辑分析仪捕获

    • 验证SPI通信时序(起始/停止条件)
    • 检查数据帧格式是否符合ADS1299规范
  2. 示波器观察

    • 原始信号与滤波后信号对比
    • 检查DRDY信号频率是否匹配采样率
  3. 性能测试数据

    测试项 设计值 实测值
    信噪比(SNR) >80dB 78dB
    总谐波失真(THD) <1% 0.9%
    系统延迟 <10ms 8.5ms

七、扩展功能实现

  1. 多通道采集

    void Read_Multi_Channel(uint8_t channels[], uint16_t *buffer) {for (int i=0; i<8; i++) {ADS1299_SetChannel(channels[i]);buffer[i] = ADS1299_ReadData();}
    }
    
  2. 数据存储

    #define EEPROM_ADDR 0x50
    void Save_Data(uint32_t data) {HAL_I2C_Mem_Write(&hi2c1, EEPROM_ADDR, 0x00, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&data, 4, 100);
    }
    

八、工程配置要点

  1. STM32CubeMX配置

    • 时钟树:HSE 8MHz → PLL 48MHz
    • GPIO:PA5/PA6/PA7设为SPI1模式
    • 中断:配置EXTI0用于DRDY信号
  2. 编译优化选项

    -O2 -mcpu=cortex-m0plus -mfpu=fpv4-sp-d16 -mfloat-abi=hard
    

该方案通过模块化设计实现了实时数据采集与滤波处理,实际应用中需注意:

  1. 首次上电时执行ADS1299校准命令
  2. 采样率与滤波截止频率需匹配应用需求
  3. 建议添加看门狗定时器防止程序跑飞
  4. 多通道采集时需注意通道切换间隔时间
http://www.wxhsa.cn/company.asp?id=1762

相关文章:

  • LangChain
  • 军工企业涉密网文件导出用什么系统?答案在这里
  • Gateway 网关坑我! 被这个404 问题折腾了一年?
  • KUKA 机器人型号含义解析
  • LangChain DIfy区别
  • tricks
  • 英语_阅读_water in our body_待读
  • 2008-2025年各省高考真题含解析
  • allure报告中allure.title 如何去掉后方的参数化显示
  • 听歌体验直接拉满!推荐一款高颜值音乐播放器!
  • IoT设备
  • 前端岗、测试岗即将消亡!阿里菜鸟国际后端研发全员转全栈……
  • 达梦数据库- 定时备份其他模式下的部分表
  • KUKA机器人的WorkVisual编程软件(转载)
  • 麒麟系统安装java环境
  • 从100到500MHz,从80V到8000V:PRBTEK新一代高压差分探头全面超越
  • javaweb项目400问题 #tomcat
  • 基于Python+Vue开发的电影订票管理系统源码+运行
  • 那些年不该放到事务中的操作,你实现过哪些
  • Java学习笔记
  • Redis容量评估模型
  • [译] 我最爱的PostgreSQL 18特性:虚拟生成列
  • nasm 的 Hello, world 在 Windows 10 x64 上
  • 实用指南:52.前端的后端模式:为每个客户端定制专属「管家服务」
  • Agilent 34401A台式万用表远程读表
  • Java 在大数据处理与人工智能中的应用
  • 马克思,本就是一位独立研究者
  • 产品二期,从GPT5规划开始
  • Redis能抗住百万并发的秘密
  • 接受 “未完成态”,是一种能力