这个板子是官方的开发板(贵死)
真贵啊,700 可以买个FPGA的板子玩了。。。
没办法,为了MCU的源码冲了。
便携脑电方案评测——信号采集及方案开发;
微弱电信号传感——毫伏级电信号监测性能评估及数据采集。
V3
V2.1
支持DC耦合和AC耦合输入模式配置; 就是一开始输入的开关
具有灵活的开关和接口选择实现电路配置;
妈的,只能说贵,就这点物料设计就100多,含泪挣我600,如果固件好,我就不说什么了。
我就看上这个GUI配置传感器了,我必须下面搓一个
在上面的一溜,就是控制通道开闭和增益以及滤波器的,好像就这样了
这个上位机的软件呢,我也得看看怎么个事
使用QT6写的,libwinpthread 是 Windows 上的 POSIX 线程库。在 Windows 平台上,POSIX 线程(Pthreads)是一种用于多线程编程的标准。libwinpthread 提供了对这些标准线程功能的支持,使得在Windows 上的应用程序能够更容易地移植和运行POSIX 线程。使用了多线程和OpenGL实现炫酷的效果。
我多线程不会啊!不会就不会了,不耽误我中午吃饭。
对一个用户来讲,他是不管你芯片有多好,他只看你的效果好不好,很肤浅的就是看一个可视化的图,他不懂滤波,就知道看图有没有什么毛刺。
而且一个芯片里面这么多的寄存器,固件里面一次写死也不好,尤其是你要当肯定比给别人用。OK,那就浅浅的来实现一下。
实现串口接收指令并通过SPI接口配置传感器的功能
初始化串口和SPI模块:在代码中初始化串口和SPI模块,配置它们的参数,包括波特率、数据位、停止位等。
代码语言:javascript复制// 串口初始化 HAL_UART_Init(&huart1);
// SPI初始化 HAL_SPI_Init(&hspi1);
接收串口指令:使用UART中断或轮询方式,从串口接收指令。当有数据到达时,需要解析接收到的数据以获取控制传感器的指令和参数。
代码语言:javascript复制// 串口接收
HAL_UART_Receive_IT(&huart1, rxBuffer, RX_BUFFER_SIZE);
在UART的回调函数中处理接收到的数据,解析指令:
代码语言:javascript复制void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
// 解析接收到的指令并执行相应的操作
parseAndExecuteCommand(rxBuffer);
// 重新启动串口接收
HAL_UART_Receive_IT(&huart1, rxBuffer, RX_BUFFER_SIZE);
}
配置SPI并发送数据到传感器:根据接收到的指令,配置SPI参数,并将相应的数据发送到传感器。
代码语言:javascript复制// SPI数据传输
HAL_SPI_Transmit(&hspi1, txBuffer, TX_BUFFER_SIZE, HAL_MAX_DELAY);
实现指令解析和传感器配置函数:编写函数来解析串口接收到的指令并配置传感器。
代码语言:javascript复制void parseAndExecuteCommand(uint8_t *command) {
// 解析指令并执行相应的操作
if (command[0] == 'C' && command[1] == 'F') {
// 配置传感器寄存器
configureSensorRegisters(command 2); // 传递参数部分
}
}
void configureSensorRegisters(uint8_t *parameters) {
// 根据参数配置传感器寄存器
// 将参数写入SPI缓冲区并通过SPI接口发送到传感器
}
一般是要写在中断里面,解析接收到的指令并执行相应的操作,然后重新启动中断,根据接收到的指令,配置SPI参数,并将相应的数据发送到传感器。
中断里面是来把要控制的操作取出来,然后使用SPI发出去
这些代码有点儿戏,让我来写一点工程化的东西。
不妨先写一个控制传感器的函数,通常会实现解析和处理传感器配置参数
函数检查接收到的命令是否以"CONFIGURE:"开头。如果是,它提取参数并调用configureSensorRegisters来处理和配置传感器。
函数是一个回调函数,当通过UART接收到字节时会执行。它收集接收到的字符,直到遇到换行或回车字符,表示命令的结束。然后,它使用parseAndExecuteCommand()处理接收到的命令。
因为是中断,里面也没有什么好写的
接下来看看电极分类
现在很多的都用音频接口来连接电极
这个是开发板上面的4个引脚
这个是在绘制的装配图,给了AD的封装
这个是TI的,可以看到在共模干扰这块还是优势大
两者参数各有高低,国产的偏置电流还小一些
这个LOGO还是有点意思的
这东西也会用在AED里面,你要这样说,我突然感觉AED就有技术含量了
OPA305这个型号奇奇怪怪的,一般没有中间的0,查了一下果然有猫腻。
就是没有305这个型号
它捕获治疗电极发出的ECG信号,运行ECG分析算法以识别可电击复律,并建议操作员是否需要除颤。
基本除颤器包含高压电源、存储电容器、可选电感器和患者电极。它能在存储电容器中产生电荷,形成潜在电流。电压越高,可能形成的电流就越大。
如果AED分析患者的ECG并探测到可电击复律,电容器将会充电,其中 Wc = 1/2CV^2c;而电容器电压 Vc(t) = Vc(0)e–t/RC,同时 R = R(lead) << R(chest)。按下电击按钮提供高压脉冲时,电流将开始流经身体以去极化大部分心肌细胞,从而重建协调收缩和正常心率。电流量由电容器和身体阻抗确定。
也就是说,其实是这个AED电流是实时的计算的
除颤能量需要经过经胸阻抗的衰减后才能到达心脏 。经胸阻抗测量是 AED 的重要功能之一。经胸阻抗 的大小一般在 25~200 Ω,影响经胸阻抗的因素有很多, 包括电极的类型和面积、电极板和皮肤间的接触状态等。经胸阻抗测量是 AED 最重要的功能之一,该功能可以使 AED 根据患者经胸阻抗大小实时调整除颤能量的 大小,同时可以对导联脱落、导联电极接触异常等危险 状况实现预警 。
目前的人体阻抗测量分析中,大多研究仍然采用经典三元等效电路模型,这个模型指出人体的等效阻抗主要是由细胞内电阻、细胞体液电阻以及细胞膜所形成的等效电容 C 三者组成的,目前多数市场在售的 AED 使用基于此原理的双电极恒流源激励电压测量的方法 在除颤前对患者进行经胸阻抗测量,具体做法是在电极连接完成后,AED 的恒流源激励电路向患者发送一个高频低压激励信号,随后信号检测电路检测经过经胸阻抗衰减的激励信号,通过计算得到患者的经胸阻抗信息。
目前该方法的不足之处在于需要对患者施加额外的电流激励,且需要额外的时间成本,有向患者施加不当除颤的风险。
除颤电流检测电路如图所示,出于除颤电流值较大的考虑,本系统选择通过电流互感器将除颤大电流线性转化为小电压进行数据采集,这样非接触式的测量方式可以保证测量的准确性和安全性,为防止在除颤电流检测时, 除颤峰值电流过大超出电流互感器的量程范围,本研究在除颤回路中串联 50 Ω 的机内补偿电阻 Rc 来防止除颤电流过大。
《2015 美国心脏协会 CPR 和 ECC 指南》指出,90%以上心脏骤停发生在医院之外,数据显示中国各大城市救护车到达现场最少要15-20分钟,在心脏骤停发生的四分钟内及时施救显得尤为重要,因此,AED体外除颤是目前心源性猝死抢救的最好办法。
AED的普及为何困难?
高成本,低投入,低使用
在发达国家,平均每十万人有用300台AED,如果中国想要达到这样的标准,那么420万台AED将要被投入使用,平均每一台AED,政府需要花20293元购买,此后每一年会产生580至1000元不等的耗材费用,直到2-5年后报废。这是一个高达874-900亿元的大市场。
然而,现实很骨感。到2020年,政府共为AED投入1亿元左右,2020年国家医疗卫生的总投入是19201.22亿元。假设每年销售额保持不变,要消化874-900亿的市场,大概还需要5个世纪。
贵啊
其实这个图就很简单的说明白了难点和原理,ECG可以精确的算出你什么时候需要电击,在电子学里面快速的放电的东西只有电容合适一些。
这里面的很多东西都是靠算法和稳定性的设计,太酷了。
给出代码:
代码语言:javascript复制#include "main.h"
#include "stdio.h"
#include "string.h"
UART_HandleTypeDef huart1;
SPI_HandleTypeDef hspi1;
#define RX_BUFFER_SIZE 50
#define TX_BUFFER_SIZE 50
uint8_t rxBuffer[RX_BUFFER_SIZE];
uint8_t txBuffer[TX_BUFFER_SIZE];
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_SPI1_Init(void);
void parseAndExecuteCommand(uint8_t *command);
void configureSensorRegisters(uint8_t *parameters);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_SPI1_Init();
HAL_UART_Receive_IT(&huart1, rxBuffer, 1);
while (1)
{
// Main application loop
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart == &huart1)
{
static uint8_t commandBuffer[RX_BUFFER_SIZE];
static uint8_t commandIndex = 0;
if (rxBuffer[0] == 'n' || rxBuffer[0] == 'r')
{
// End of command, process the received command
commandBuffer[commandIndex] = '