摘要:ADS1292R是TI公司早在2012年就出产的一款医用级ADC芯片,它主要应用在医疗仪器(心电图ECG),可以监护患者以及和人护理和健身监视器。ADS1292R具有两个低噪声可编程增益放大器(PGA)和和两个高分别率模数转换器器(ADC),集成了心电采集所需要的部件,方便设备小型化。它的功耗极低,使得可以作为长时间监控成为可能。而且输入参考噪音低,共模抑制比高。足以进行心电采集。电赛很可能会让大家利用这款芯片做一个心电图检测仪,显示模块很可能就是大家所熟知的RGB大屏幕,同时这道题应该是信号题了。
心电信号和呼吸信号是人体的重要生物电信号。尤其是心电信号,它比其他生物电信号更直观,更具有规律性,它是反映心脏健康状况的重要依据。心电图是诊断和分析治疗心血管疾病的一个重要手段,在临床治疗中心电图得到广泛应用。但是常规心电图一般需要通过大型医疗场所,如医院、疗养院的心电图机采集数据获得,其获得途径较难、价格较高、耗时长等弊端阻碍了心电图机的进一步应用。今年大家经历了新冠疫情,所以出这种题目也是情理当中,毕竟学以致用,学了不能用,那学了又有何用?对吧。
这可芯片的引脚还不少,一共有32个引脚。当然做电赛大家肯定都是买的几百块钱的模块,肯定不会自己亲自动手焊接,而且买的模块只会把芯片所需要的通信引脚和电源引脚引出来。所以做硬件的也就节省了很多时间。当然节省的时间不是让你去休息的。你需要花大量的时间来研究数据手册,把外围电路优化好才能让软件更好地去写代码。
这里我简单的看一下数据手册,可能分析的不对,需要各位大显身手去开动你们聪明的大脑了。我们从1号到32号引脚讲讲它的引脚功能:
注意:
心电及呼吸信号采集前端是整个监护系统的核心部分,如果前端信号采集部分的电路出现问题,即使你的模块板子再好也不能得到你想要的输入信号,自然就GG。ECG 属于微弱的小信号,其幅值在 10μ V~5mV 之间,极易受到干扰,导致有用信号淹没在诸多噪声中。为了能有效地提取出有用信号,对信号采集硬件提出如下要求:
这两点是前端设计电路最重要的两点。
极片也是传感器的一种,其作用是将人体内的离子导电的位移电流转化为检测电路中的电子导电的传导电流,电极片作为检测电路输入前端,其性能也影响着检测电路的噪声、共模抑制比等,所以选择合适的电极片对整个系统的信号质量尤为重要。既然是比赛那就用学校的钱买最好的点电极片了,战术后仰!!!
下图1是官方数据手册中截取的,图二是对应的中文内部框图,图三是在网上多次看到的原理图。有些图用的人多了自然有他的道理,这个不必纠结。设计电路首先要遵从数据手册然后再在此电路的基础上进行修改。
注意:由于人体阻抗高达几KΩ 至几十KΩ,在心电信号采集时常常遇到信号误差大或者失真现象。心电信号除了易受外界干扰以外,人体内部器官之间、表皮之间都存在相互影响,甚至是人的情绪变化也会引起心电信号不稳定。
ADS1292R 可以实现双通道信号采集和模数转换,通道 1(IN1N 和 IN1P)为呼吸信号采集通道,IN3N 和 IN3P 为 ADS1292R 内部产生的32kHz 正弦电流信号的输出端。在正弦电流信号的输出电路中,可以在31号和32号引脚外加保护电阻,限制从 ADS1292R 流向人体的电流,同时还可以在电阻后加电容起到隔离流回人体的直流的作用(电阻和电容是串联)。在呼吸信号输入电路中,C2和 C7起到抑制流回人体的直流电流的作用。C1和 C6起到人体免受电路突发故障所引起的大电流伤害的作用。
心电信号极易受到 50Hz 工频干扰,这种干扰常以共模的形式出现。一般在生物电信号检测电路中,需要对消驱动电路即右腿驱动电路来消除这种共模干扰,从而提高系统的共模抑制比。
ADS1292R 片内集成了右腿驱动电路,这样有利于减小监护设备的体积,降低功耗。右腿信号由 RLDINV 端口输入至片内右腿驱动电路,设置 ADS1292R内部 RLD_SENS 寄存器,使片内右腿驱动电路的输出连至通道 2 以减少心电信号中共模干扰。官方公开的资料中并未给出片内右腿驱动电路的反相放大器中电阻阻值,其放大倍数未知,为保证整个电路的信号稳定、可靠,右腿驱动电路需要各位大佬根据系统需要外搭。
心电信号非常微弱,典型值仅为 1mV 左右。正常的心电信号大部分为 0.5~ 40Hz 的低频信号,而心电信号的总体范围为 0.05~100Hz。心电信号极易受到来自外界、人体自身以及电路的干扰,如基线漂移、工频干扰、肌电噪声等。干扰信号混杂于心电及呼吸信号中,导致有用信号畸变,有时有用信号会完全淹没在噪声里,故有用信号的特征值很难被提取。所以相应的滤波去噪处理是必要的。
常用的心电信号去噪方法有硬件降噪和软件滤波这两种。硬件降噪主要是通过搭建相应的电路来实现滤波功能,但这种硬件滤波电路不仅搭建调试难度大,而且增加了成本、体积和功耗。建议大家通过软件滤波,这对参加电赛的软件手来说肯定不难,智能车都搞过这点滤波的问题还能难道你这个大佬吗?对吧!
TI杯当然是建议用TI提供的板子—MSP430。如果你前期没有用过MSP430的板子也没有问题,用STM32也不是不可以。另外芯片也单片机通信的方式是SPI通信,我相信SPI通信大家都会,因为有的7针的OLED显示屏就是用的SPI通信,这点就不用多说了。
代码初始化需要配置寄存器,具体程序中已经注释的非常清楚,仅供参考啊!
void ads_Init(void)
{
uint8_t send_data[20], read_data[20];
ads_Reset(1); // 复位引脚置一,正常工作
osDelay(1000);
osDelay(100);
//指令:停止连续读数据模式
send_data[0]=ADS1292R_CMD_SDATAC;
while(HAL_OK!= HAL_SPI_TransmitReceive(&hspi1,send_data,read_data,1,1000));
osDelay(10);
//写配置寄存器2=0xa0,内部参考电压为2.42V
send_data[0] = ADS1292R_CMD_WREG_1(ADS1292R_REG_CONFIG2);
send_data[1] = ADS1292R_CMD_WREG_2(1);
send_data[2] = 0xa0;
while(HAL_OK!= HAL_SPI_TransmitReceive(&hspi1,send_data,read_data,3,1000));
osDelay(10);
//写配置寄存器1=0x01,连续转换模式,采样率为250
send_data[0] = ADS1292R_CMD_WREG_1(ADS1292R_REG_CONFIG1);
send_data[1] = ADS1292R_CMD_WREG_2(1);
send_data[2] = 0x01;
while(HAL_OK!= HAL_SPI_TransmitReceive(&hspi1,send_data,read_data,3,1000));
osDelay(10);
//写导联脱落检测寄存器=0xF0,正负极分别为70%和30%,该功能实际未使用
send_data[0] = ADS1292R_CMD_WREG_1(ADS1292R_REG_LOFF);
send_data[1] = ADS1292R_CMD_WREG_2(1);
send_data[2] = 0xF0;
while(HAL_OK!= HAL_SPI_TransmitReceive(&hspi1,send_data,read_data,3,1000));
osDelay(10);
//写通道1设置寄存器=0x30,设置增益为3,正常节点输入
send_data[0] = ADS1292R_CMD_WREG_1(ADS1292R_REG_CH1SET);
send_data[1] = ADS1292R_CMD_WREG_2(1);
send_data[2] = 0x30;
while(HAL_OK!= HAL_SPI_TransmitReceive(&hspi1,send_data,read_data,3,1000));
osDelay(10);
//写右腿驱动寄存器=0xEF,PGA的斩波频率为4分频,使能右腿驱动,关闭右腿驱动的脱落检测,通道2的右腿驱动负极和正极分别连接到通道2输入的负极和正极,通道1的右腿驱动负极和正极分别连接到通道1的负极和正极
send_data[0] = ADS1292R_CMD_WREG_1(ADS1292R_REG_RLD_SENS);
send_data[1] = ADS1292R_CMD_WREG_2(1);
send_data[2] = 0xEF;
while(HAL_OK!= HAL_SPI_TransmitReceive(&hspi1,send_data,read_data,3,1000));
osDelay(10);
//写脱落检测寄存器=0x0F,关闭通道1和2的电流方向检测,使能通道1和2的正负极脱落检测
//其实只使用了通道1,而且脱落检测实际上没有使用
send_data[0] = ADS1292R_CMD_WREG_1(ADS1292R_REG_LOFF_SENS);
send_data[1] = ADS1292R_CMD_WREG_2(1);
send_data[2] = 0x0F;
while(HAL_OK!= HAL_SPI_TransmitReceive(&hspi1,send_data,read_data,3,1000));
osDelay(10);
//写呼吸控制寄存器1=0xF2,使能呼吸调制解调电路,呼吸解调相位为135°,时钟为32KHz,内部时钟
send_data[0] = ADS1292R_CMD_WREG_1(ADS1292R_REG_RESP1);
send_data[1] = ADS1292R_CMD_WREG_2(1);
send_data[2] = 0xF2;
while(HAL_OK!= HAL_SPI_TransmitReceive(&hspi1,send_data,read_data,3,1000));
osDelay(10);
//写呼吸控制寄存器2=0x83,关闭偏置校准,呼吸控制频率为32KHz,右腿驱动参考信号为外部信号
send_data[0] = ADS1292R_CMD_WREG_1(ADS1292R_REG_RESP2);
send_data[1] = ADS1292R_CMD_WREG_2(1);
send_data[2] = 0x83;
while(HAL_OK!= HAL_SPI_TransmitReceive(&hspi1,send_data,read_data,3,1000));
osDelay(10);
ads_Start(1); //启动转换
osDelay(10);
//指令:连续读模式
send_data[0]=ADS1292R_CMD_RDATAC;
while(HAL_OK!= HAL_SPI_TransmitReceive(&hspi1,send_data,read_data,1,1000));
osDelay(10);
}
void ads_Get_Data(uint8_t* raw_data)
{
static uint8_t sendBuf[9]={
0,0,0,0,0,0,0,0,0};
HAL_SPI_TransmitReceive_DMA(&hspi1,sendBuf,raw_data,9);
}