学期内综合实验作品,虽然有点烂。。也许作者不适合上985
总的来说很简单,MSP430只需要完成一个AD转换和串口发送的任务,剩下的扔给MATLAB处理。
对于心电信号的采集,用的是AD8232套件。(下图来自于商家给的手册)
右边插口用套件连接身体部位(这里用的是一次性氯化银医用电极,淘宝上20多块钱一大包),左边除了GND和3.3V和MSP430相连后(当然其他单片机也一样),OUTPUT就能够直接输出一个放大后的心电信号(芯片内置的有放大器)
F连接的位置还有待商榷,商家给的说明也不太一致,有说连的小腹左侧,也有说连右腿的。不过是小问题。
至于剩下的LO-和LO+是用于脱落检测的,作者水平有限就没用、、
MSP430配置好ADC10的输出端口,将OUTPUT输出与其相连即可。
具体的方案是:用G2553的定时器Timer_A产生一个200Hz的输出(用Output Mode)来控制AD转换,让ADC10每1s等间隔采样200个数据。
UART的波特率设置成9600,每采集完一个数据后就立即发送。(所以是在ADC的中断里写的串口发送)
当然,串口一次只能发送8位数据,而ADC转换结果是10位,所以最后分成了两次发送。(计算了所需时长,是OK的)
具体这样实现(应该不是最好的):
void UART_send(unsigned short data)
{
unsigned short temp1=0,temp2=0;
temp1 = data>>8; //temp1是高2位
temp2= data-temp1*0x100; //temp2是剩下的8位
UCA0TXBUF=temp1;
while(UCA0STAT&UCBUSY); //UART忙
UCA0TXBUF=temp2;
while(UCA0STAT&UCBUSY);
}
之后就是MATLAB的问题了。
MATLAB的serial()函数系列在2019b版本后不再被推荐使用,改成了serialport()函数,据说之后用serial可能会报错什么的。。
虽然但是,新旧两个版本的函数语法都差不多,下面给一段例子。
delete(instrfind);
Baudrate=9600;
s=serialport('COM5',Baudrate);
flush(s);
a=read(s,5,'uint8');
delete(s);
flush()可以用来清空缓冲区的数据,不然接收到的可能就是之前转换未被读取的电压值而不是当下时刻的值。。
MATLAB appdesigner做一个简单的APP也肥肠简单。学会串口操作之后就可以基本上没什么问题地复现波形了。
如果你想要把数据弄到Workspace里,可以尝试assignin函数:
·assignin('base','Voltage',voltage);
srds,这玩意性能好像不太行,很容易卡。
建议采集一定数量的数值之后再统一画图,不要每采集一个点画一个图,不然必然卡爆。
这边是1s钟画一个图,有时候依然卡、、
之后闲的没事情做,顺带测试了一下警告窗口的功能、、感觉对于软件专业的同学来说这种东西非常重要。用户就是上帝、、
try
dis_com=serialport(COM1,Baudrate1,'Timeout',3);
msp_com=serialport(COM,Baudrate,'Timeout',5);
Screen_Init(app,dis_com);
catch
questdlg('Can''t open the port',...
'Error',...
'Yes','Yes');
delete(app.UIFigure);
return;end
顺带一提心率的测量,基本上是网上找的资源,然后弄过来测试了一下,发现能行,就串起来用了。在外面写好.m文件之后直接在app里调用即可。
下面给一个波形很糟糕的例子的处理(测量时长15秒)。感觉效果一般般,适不适用于所有场合也不确定,多多见谅、、
其实就是本人信号与系统学的和shi一样,滤波什么的窗函数什么的那些已经完全看不懂、、还得找时间去复习、、
上面识别结果用的是findpeaks()函数,推荐根据实际情况自定义检测阈值。后面小小地取相邻几个峰的平均就可以算出心率啦。。(当然上面那些图在app里不展示,只是平常测试的时候看看而已)
顺带提一嘴,上面GUI界面共有两个串口设置,其实还有一个使是用去给USART-GPU串口屏发命令的。
这个东西上手很容易,得也非常有趣,这次只是简简单单做了一个小东西,可以同时显示一些波形什么的,,效果见下:
差不多就这样。对于ECG,还有小波变换或者神经网络的更高级的东西去识别,甚至能够搞定其他的特征峰值什么的、、作者大学是个混子,水平有限、、加上很懒,就只搞了以上的东西、、
奥利给!