脑电信号处理系统的设计全文
第1章 绪论
1.1 引言
脑科学的研究是当今医学研究的热点之一,而安全无损伤性的脑研究和治疗手段更易为人们所青睐和接受。自从上世纪20年代发现人类大脑生物电活动(Berger 1929 年)以来,世界各国学者对脑电进行了大量的研究[1]。随着现代科学技术的发展,对脑电波的研究也有了不少的突破。脑电图已经广泛的应用于生物医学、军事医学、航天医学、生理学、心理学等研究领域。早期的工作发现脑电图记录有助于诊断癫痫和脑肿瘤。现在脑电图已经成为一项常规的临床检查,它对脑损伤、癫痫、检测觉醒、昏迷和脑死亡、理解和控制麻醉状态等疾病提供了诊断、预测、治疗等信息。但脑电信号显著的特点是信号极其微弱(幅值范围为 10μV-100μV),振幅不恒定。并且由于脑电电极,直流电源及人体其他信号的干扰,信号很不稳定[2]。虽然,目前所采用的机电式脑电图机和脑电地形图仪的应用比较广泛,但这类脑电系统均采用硬件控制,稳定性和可靠性相对比较低;另外,由于都是采用模拟信号处理,抗干扰性差、功能比较单一,硬件实现也比较的复杂,不利于对功能进行灵活的更动以满足临床诊断的需求。近些年来,随着数字信号处理技术的飞速发展,数字化技术在各行各业的渗透也越来越深入,采用数字化技术来实现原先需要借助模拟信号处理技术才能实现的系统功能,有非常多的优越性。数字化脑电系统就是在这一背景之下提出来的一种新型医疗仪器,具有比较高的临床应用价值。
1.2 国内外脑电仪器的发展及应用背景、目的及意义
1.2.1 国内外脑电仪器的发展及应用背景
脑电仪器是用于获取和观察被检测者脑电活动变化的仪器,对了解大脑的生理、病理状态具有重要意义。广泛用于大脑疾病的诊断、病损部位的定位、疗效的评价、预后的判断。因此在临床上有广泛的应用前景。数字化脑电系统是最近两年才出现的新型医疗仪器,是在原机电式脑电图机和脑电地形图仪的基础上发展起来的一种新型设备。脑电图是人脑头皮电位的记录。1934 年,英国最著名的神经生理学家、诺贝尔医学生理学奖获得者 Adrian 爵士及美国的 Davis 等人证实并应用于临床以后,正式提出脑电图这一名词[3]。人体头皮电位只有几十微伏,需放大十几万倍才能被记录到,如此微弱的脑电信号如何放大,一直是困扰技术人员的难题。而且外界干扰信号很难排除,尤其是工频电源信号的干扰更为突出。随着科技的发展,高精度、微型化的放大芯片的出现,使得脑电图机的测量精度和稳定性大幅提高。国外的产品,如美国和日本的脑电图机,抗干扰和稳定性都比较好,但价格昂贵,一般都在 20 万元以上,无笔描记式的脑电图机价格更高。它们使用的放大器都是采用高精度集成放大器,并有专用 CPU 控制。但这样的性能价格比是我国广大中小医院无法受的。国产脑电图机的内部控制都是采用小规模集成电路控制,所以稳定性和可靠性相对比较低。目前临床脑电波检查,其诊断价值仍不尽如人意。究其原因在于在诊断与大脑皮层有密切关系的高级神经活动时,往往难以应用空间分析技术。
现代空间分析技术法有三个重要的发展阶段,第一阶段是 Walter(1967)研究的脑电波平均频率谱的空间表示和 Bickford(1971)研究的脑电波的描记压缩成俯瞰图。这种方法采用了频率分析技术,在单一部位记录脑电波,分析其频率,并把记录在多导联的脑电波中的频率累积起来[4]。第二阶段是由 Rremond(1969)研制的脑波电压“时间—空间分布图”,即从某一时间点开始,随着时间的推移而记录导联中的一系列脑电波电位位置分布,把它们制成等电位图[5] 。第三阶段是二维显示[6]法显示头部某一区域或整个头部的电位分布,这是由 Lehmann(1976)和Ragot(1878)研制而成的。他们将实测到的电压值,应用函数原理推算出头部电极区间的未知电压值,利用这些电压值可作出类似于地形图等高线样的等电压地形图,即脑电地形图[6] 。
目前,描记式脑电图和脑电地形图还不能完全满足临床脑电检查的需要。描记式脑电图和脑电地形图检查都是一种静态短时间的检测,人脑电波的异常活动并不一定连续出现,有些是瞬间变化的。因而对一些偶发、短暂、阵发的或具有特征性的脑电活动,它们就显得无能为力了。近年来,随着计算机技术和大容量微形存贮技术的飞速发展,二十四小时动态脑电图已经面市,这一产品的出现,为临床提供了全信息脑电信号。动态脑电图(病人携带式脑电记录器)是集脑电放大、数模转换、数据保存为一体的微型脑电信号记录器,并与计算机软件技术相结合的一种最新技术产品。但它只是通过计算机将所记录到的脑电信号放出来,没有充分利用计算机的优势进行分析处理。脑电图和脑电地形图都是单一脑电信号的记录和分析,对许多神经科疾病的诊断未能提供足够的信息(如心电、眼动、呼吸和肌电等)。当前的科学研究往往是采用许多学科的研究方法去研究一门学科的对象,如何将心电、脑电、眼动、呼吸等生命体征信息有机地、实时地提供给临床医生,如何对精神分裂症、抑郁症、智能障碍、强迫症、恐怖症等神经精神科疾病提供更多的信息,将是今后此类设备发展的方向,与上述体征信息有关疾病的研究正在成为近年来医学工作者,特别是神经科医生研究的热门课题。数字脑电系统正是为了适应这一医学研究发展方向而研制的。
1.2.2 课题研究的目的及意义
本课题的目的是设计一脑电信号处理系统,该系统既能对脑电信号进行采集,又能对信号进行处理,这样能弥补传统的脑电仪器只对脑电信号采集显示,不进行处理的缺陷。此课题的完成,能对脑电信号进行简单的处理,如果使信号处理功能足够强大,能为临床和医学研究提供更多的大脑信息,有利于提高我们的医疗水平。
1.3 设计的任务及论文完成的主要工作
1.3.1 设计任务
采集来的脑电信号经放大、滤波之后还是模拟信号,若要将该脑电信号作为数据文件保存到计算机中,做进一步的分析,需要将模拟信号转换为数字信号。
本设计要求设计脑电信号采集控制器的设计,将采集到的脑电信号在计算机上实时显示,能对脑电信号完成软件滤波,完成硬件和软件的调试。
1.3.2 论文完成的主要工作
针对设计任务的要求,本论文完成的主要工作有:完成脑电信号采集控制器的设计;并通过串口通信将采集到的脑电信号传送到计算机,并在计算机上实时显示;完成脑
电信号采集控制器硬件电路的设计;并编写采集控制程序和串口通信程序,完成脑电信号显示及处理程序的设计。
1.4 设计的主要思想
脑电信号是一种微弱的生理信号,它具有医学信号的特点,只有µV级,而且频带为0.5-70Hz,所以对硬件的设计要求抗干扰能力强,才能使输出的信号易于观察,分析和处理。在硬件上主要用前置放大,滤波和干扰抑制电路对信号进行放大,滤波,再将模拟信号转换为数字信号送入计算机,便于用软件对信号进行处理。
1.5 本文的结构组成
本论文由五部分组成:
绪论:主要阐述脑电信号处理系统的发展现状,介绍设计研究背景,明确了设计任务,简单概述了设计思想,介绍本论文的组成。
第2章:根据脑电信号的特点,设计出脑电信号处理系统总体方案。通过比较选择采集控制器的元器件,确定控制器的硬件设计方案,提出脑电信号处理系统的软件设计方案。
第3章:根据选定的元器件的性能及设计要求,设计出采集控制器的电路原理图。
第4章:根据硬件构成和功能要求,设计出采集与传输程序和串口通信程序,编写脑电波的显示程序以及对脑电信号的处理程序,给出了相应的程序流程图。
第5章:调试程序及结论。
第2章 脑电信号处理系统总体方案设计
本章先介绍脑电信号的性质、特点,然后根据这些特点,针对任务要求设计出了脑电信号处理系统的总体方案。
2.1 脑电信号的特征分析
1. 信号弱
脑电信号非常微弱,只有μV级,且频率带为 0.5-70Hz,所以要求系统具有较高的灵敏度。而灵敏度越高,就越容易把干扰引入采集系统。
2. 强噪声背景
人体周围存在各种电子仪器,它们都会或多或少的产生电磁波,因此人体生物电会受到电磁场干扰,脑电也不例外。人体是个大电容,会感应出电场,特别是引入很大的工频干扰。另外某种生理参数的测量将受到其他参数的影响,这些都是噪声。
3. 随机性大
脑电信号是一种随机性很强的非平稳信号。人体系统在测量过程中不能停止运转,也不能拆卸,所以人体生物电的测量受外界影响很大,大多参数是随时间而变化的。人体体内各系统生理参数还要互相作用互相影响,因此呈现出很大的随机性。
2.2 脑电信号处理系统总体方案
脑电信号非常微弱,并且受到极强的干扰,要对脑电信号进行处理,为了获得准确的脑电信号,必须对采集的脑电信号进行前置放大,然后进行陷波去除50Hz工频干扰,将信号进行高通滤波,消除高频信号,再进行二级放大,将放大后的信号进行低通滤波,进行三级放大,为了有效抑制干扰,可以在三级放大前进行光电隔离。将三级放大后的脑电信号入模数转换器中,用单片机AT89C51对信号采集进行控制,然后利用单片机的串口进行通信将数据传送到PC机上,在PC机上将脑电信号波显示出来以及进行软件滤波处理。根据以上思想,设计了如图2-1所示的脑电信号处理系统原理框图,作为进一步设计的指导。
图2-1 脑电信号处理系统原理框图
本设计分为了两个部分,前半部分是完成脑电信号的拾取及前置放大和信号的预处理(由另一同学设计)。后半部分是完成脑电信号采集控制器的设计,采集控制程序和通信程序的设计,波形显示及处理程序的设计(在本文中体现)。
2.3 脑电信号采集控制器硬件方案的设计
脑电信号采集控制器部分由模数转换电路和单片机控制电路组成。如果选择不同的芯片,模数转换电路和单片机微控制器系统就可能有不同的实现方案,所以可以通过比较元器件的性能和价格来选取最优方案。
2.3.1 微控制器的选择
单片机控制电路主要用于控制AD对采集的脑电信号进行转换,同时利用单片机的串行口进行串行通信,将转换后的脑电信号发送到PC机上,便于后绪处理。
单片机有很多的种类和型号,不同种类和型号的单片机,它们的功能也是不同的,通常用的单片机有AT89C2051,C8051F206,AT89C51等。
C8051F206内置有AD转换器,12位分辨率,有32个通道,其转换速率可高达100ksps。有高速8051微控器内核,有21个失量中断源(标准 8051 只有 7 个中断源),256字节的内部数据RAM,8K的字节的FLASH。具有全双工硬件UART和SPI总线,具有复位功能,可用内外部时钟,工作在最大系统时钟频率 25MHz 时,它的峰值速度达到 25MIPS供电电压2.7V-3.6V。典型的工作电流10MA。C8051F206的性能比较好,但价格也比较高,在小型控制系统中用C8051F206有点浪费。
AT89C2051是美国ATMEL公司生产的低电压,高性能CMOS 8位单片机,片内含2k bytes的可擦除的只读程序存储器( EPROM)和128 bytes的随机存取数据存储器(RAM ),兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,15个I/O口线,两个16位定时/计数器,一个5向量两级中断结构,一个全双工串行通信口,内置一个精密比较器,内振荡器及时钟电路,空闲方式停止CPU的工作,但允许RAM,定时/计数器,串行通信口及中断系统继续工作。
图2-2为AT89C2051的DIP(双列直插)引脚配置。
图2-2 AT89C2051的引脚配置
AT89C2051价格较低,功能强。在小型控制系统中使用AT89C2051有较高的性价比。在脑电信号采集系统中,由于脑电信号是典型的低频信号,用单片机主要完成信号的模数转换和传输功能,所以用AT89C2051是非常合适的,但本设计中要进行串行通信,选用此芯片会资源不足。
AT89C51是美国ATMEL公司生产的低电压,高性能CMOS 8位单片机,片内含4k bytes的可擦除的只读程序存储器,128字节内部RAM, 32个I/O口线,两个16位定时计数器,一个5向量两级中断结构,一个全双工串行通信口,片内含有振荡器及时钟电路,掉电方式保存RAM的内容,但振荡器停止工作并禁其它所有部件工作直到下一个硬件复位,此芯片资源比较丰富,与AT89C2051价格也差不多,本设计采用此芯片。
图2-3为DIP-40型AT89C51的引脚配置。
图2-3 AT89C51的引脚配置
2.3.2 模数转换器的选择
ADC0832是一种具有8位分辨率、逐次逼近型的双通道A/D 转换芯片,其最高分辨可达 256 级5V单电源供电,芯片的模拟电压输入在0-5V之间。在250KHz时钟频率时,芯片转换时间仅为32µs,据有双数据输出可作为数据校验,以减少数据误差,转换速度快且稳定性能强。独立的芯片使能输入,使多器件挂接和处理器控制变的更加方便。通过DI数据输入端,可以轻易的实现通道功能的选择。ADC0832体积小,兼容性强,性价比高
。
ADC0832 DIP-8封装的引脚配置如图2-4所示
图2-4 ADC0832的引脚配置图
CS为片选端,低电平有效,CLK为串行时钟输入端;CH0,CH1为两路模拟信号输入端;DI为两路模拟输入选择输入端,DO为模数转换结果串行输出端;VCC/REF为正电源端和基准电压输入端。
ADC0809是CMOS单片型逐次逼近式的8位A/D转换器,具有转换起停控制端,转换时间为100μs,单+5V电源供电,模拟输入电压范围0~+5V,不需零点和满刻度校准,低功耗,约15mW,ADC0809可处理8路模拟量输入,且有三态输出能力,既可与各种微处理器相连,也可单独工作,输入输出与TTL兼容,本设计采用此芯片。
图2-5为DIP-40型ADC0809引脚配置图。
图2-5 ADC0809引脚配置图
IN0-IN7为8路模拟信号输入端;2-1-2-8是8路数字量输出端;A、B、C为3路地址输入线,用于选通8路模拟输入中的一路;ALE是地址锁存允许信号,输入高电平有效;START为 A/D转换启动信号,输入高电平有效;EOC为A/D转换结束信号,当A/D转换结束时,此端输出一个高电平;OE为数据输出允许信号,输入高电平有效;当A/D转换结束时,此端输入一个高电平,才能打开输出三态门,输出数字量;CLK为时钟脉冲输入端,要求时钟频率不高于640KHz;REF(+)、REF(-)为基准电压。
2.4 脑电信号处理系统软件方案的设计
将采集的脑电信号通过串行口送到PC机,要利用串行通信实现数据传输,必须编写串行通信程序,如果实现了单片机与PC机的串行通信,便可以成功的把采集的脑电数据传送到PC机上。要想将采集的脑电信号在PC机上实时的显示出来以及对脑电的处理,可以用VC编写一个用户界面程序,在定时器函数中用内存绘图的方式,将脑电波在内存中显示出来,然后将脑电波从内存拷贝到屏幕上,便能实现脑电信号的实时显示,编写数字滤波程序对脑电波进行滤波处理,包括高通和低通数字滤波处理。
2.5 小结
根据脑电信号的特点,设计了脑电信号处理系统的原理框图。本章着重介绍了脑电信号处理系统的采集控制器设计方法以及元器件的选择,脑电信号波形的实时显示的实现方法及对脑电波实现滤波处理。
第3章 脑电信号采集控制器模块设计
微弱的脑电信号在经过放大、滤波等处理后,消除了绝大部分的干扰信号,并且从微伏级放大到到0-5V的范围内。本设计中的脑电信号采集控制器主要完成脑电信号的采集[9],实现模数转换,利用串行通信来完成数据的传送。
3.1 采集控制器硬件的设计
经放大后达到0-5V内的脑电信号,符合AD转换器对输入信号的要求,可以通过AD转换器将脑电信号送到采集控制器中。要实现将采集的脑电信号在计算机上显示出来,必须要经过信号的采样和信号传输的底层处理技术。整个处理控制系统由模拟信号输入模块、数据输出模块和控制器模块组成。
3.1.1 采集控制器的设计方案一
模拟信号转换模块由串行模数转换器ADC0832来完成,数据输出模块由单片机AT89C2051的串行口[10]和MAX232ACPE芯片来完成。控制器模块还包括复位电路、振荡电路等,使处理器能正常运行的辅助模块。结合脑电信号的采集特点和电路元器件的使用要求,设计了如图3-1所示的脑电采集控制器的原理图[11]。
图3-1 脑电采集控制器原理图
本方案中,ADC0832将输入的信号转换为8位的数字信号之后,从DO端串行输出,输出的信号经单片机的串口发送到计算机上,至少需要两个串口才行,但AT89C2051只有一个全双工的串行口,如果用此方案,就必须用定时器来控制DO端的输出,程序会很麻烦,并且时序的精确性也不一定得到保证,因此本设计中不采用此方案。
3.1.2 采集控制器的设计方案二
在方案二中,采用了ADC0809和AT89C51单片机。ADC0809将模拟信号转换为数字信号之后,采用的是并行输出的方式,可以将输出量接到AT89C51的并口,用AT89C51的串口进行通信,送脑电数据到计算机。采集控制器的原理图如图3-2
图3-2 采集控制器原理图
人体脑电的频率在0-40Hz范围内,根据奈奎斯特采样定理,采样频率必须要在80Hz以上才能使所测信号不失真,采样频率设置为100Hz。
如图3-2示,AT89C51 的RST为复为按钮,在引脚上保持两个机器周期的高电平,单片机便可复位。RXD和TXD为串行口接收数据和发送数据脚,主要负责完成单片机与PC机的串行通信。TAL2和TAL1分别为片内振荡器反向放大器的输出端、输入端。振荡电路由晶振和外接2个30pF的电容便可实现。GND为电源地线引脚。第32-39引脚接A/D转换器的模数转换结果并行输出端,ALE通过二分频器与AD的时钟信号相连,控制AD转换器。T0和T1控制转换器的输出和转换启动信号,高电平有效。
VCC为ADC0809电源电压,+5V单电源供电。CLK为时钟信号,确定A/D转换器的转换时间。本设计只采集了一路脑电信号,A、B、C直接接地。D0-D7输出转换后的数字信号。
在本设计中,单片机的时钟产生方式采用内部时钟方式,内部时钟方式采用外接晶体加电容构成并联谐振回路。谐振回路的晶振可在1.2-24MHz间选择,本设计采用12MHz晶振,外加电容的取值对输出频率的稳定性和大小有影响,可以20-100pF间选择,选取典型值30pF输出频率的稳定性会比较好。
在串行通信中,RS-232C是技术比较成熟且常用的点对点的通信协议。为保证二进制数据能够正确传送和设备控制准确的完成,有必要使所使用的信号电平保持一致,为满足此要求, RS-232标准规定了数据和控制信号的电压范围。它的电平不是+5V和地,而是采用负逻辑,规定+3V-15V之间的任意电压代表逻辑“0”,(3V)-(15V)间的任意电压代表逻辑“1”电平。为了完成单片机与计算机的通信功能,中间需要一个合适的接口芯片,来完成电平的转换,保证信号电平的一致性。本设计采用比较常用的MAX232。其引脚如图3-3所示
图3-3 MAX232引脚配置说明
MAX232为RS-232收发器,简单易用, +5 V单电源供电,仅需外接5个1μF的电容即可完成从TTL电平到RS-232电平的转换。
AT89C51是脑电信号采集系统处理器的核心部分。脑电信号经前置的信号调理电路处理后,由微伏级信号放大到0-5V范围内的模拟信号。ADC0809的输入范围也被设置为0-5V的范围。模拟脑电信号经ADC0809并行转换后形成的数字信号,再由单片机的串口经MAX232送到计算机并作进一步的处理。
3.2 小结
本章通过对设计方案的比较,确定了采集控制器的硬件电
路,设计采用了价格便宜并行模数转换器ADC0809和小型的与MCS-51系列兼容的小型单片机AT89C51组成的硬件结构,不仅实用而且性价比高。其核心是信号采集控制器的硬件设计。
第4章 脑电信号处理系统软件设计
根据硬件电路的要求,设计了信号采集与传输程序,串口通信程序,波形显示及处理程序。
4.1 基于AT89C51的串行通信
脑电信号经信号调理电路处理后要经过模数换后才能到计算机作进一步的处理。而且采集到的脑电信号要显示在计算机上,因此要进行串口通信程序的设计。
RS-232C是最常用的串口标准,用来实现数据通信设备(DCE)和数据终端设备(DTE)间进行数据传输。RS-232C标准适用于DCE和DTE间的串行二进制通信,最高数据速率为20Kbps。RS-232C标准电缆长度为15米。本设计按照RS-232C协议标准进行常用的点对点的串口通信。
串行通信是指数据一位一位按顺序传送的通信方式,它的突出优点是只需要一对传送线,这样就大大降低了传送成本,特别适用于远距离传送,其缺点是传送速度低[12]。
脑电信号采集系统利用AT89C51与PC机进行通信,其通信方式为串行通信,本设计采用单工配置,允许数据向一个方向传送。
串行通信有异步通信和同步通信两种基本通信方式。在异步通信中,数据是一帧一帧传送的。在其帧格式中,一个字符有四个组成部分:起始位、数据位、奇偶校验位和停止位。在本设计中,字符包含1个起始位,8个数据位,没有奇偶校验位,一个结束位。起始位“0”信号占用一位,用来通知接收设备一个待接收的字符开始到来。线路上在不传送字符的时间应保持“1”。接收端不但检测线路的状态,若连续为“1”以后又检测到“0”,就知道发来一个新的字符,应马上准备接收。
AT89C51的串行口是全双工的UART,它可以同时接收和发送数据,是使用特殊寄存器内的SBUF寄存器及SCON串行控制寄存器[13],如表4-1所示。
表4-1 SCON 逻辑表
SM0 SM1 SM2 REN TB8 RB8 TI RI
RI:接收中断标志位,在模式0下,当第8位结束时,硬件会将其设为1;在其他模式下,在停止位的一半时由硬件设定,此位必须由软件清除。
TI:发送中断标志位,在模式0下,当第8位结束时,硬件会将其设为1;在其他模式下,在停止位的开始时由硬件设定,此位必须由软件清除。
RB8:在模式2或3时,发送的第9位数据放入此位,在模式I时,若SM2=0,则RB8为接收到的停止位,模式0时,RB8没有作用。
TB8:在模式2或3时,发送时的第9位数据由软件控制。
REN:由软件设定或清除,以决定是否接收串行输入数据,REN=1接收,REN=0发送。
SM2:当串行口为模式2或3时,使能多处理器通信的功能。在模式2或3时,如果SM2=1,则当接收到第9为数据为0时,RI不动作。在模式1时,若SM2=1,当接收到的停止位不正确时,RI也不动作,在模式0时,SM2必须为0。
SM0, SM1为串行口模式选择,串行口有4种工作模式,模式1在这里作为脑电信号的串行发送设置。
4.2 数据采集与通信程序设计
脑电信号采集系统的软件设计包括两部分,一部分是嵌入于89C51的软件设计,其主要完成信号的采集和传输;另一部分是在PC机上运行的软件设计,其主要是完成和单片机的通信[14]和信号显示及处理。先介绍采集与传输程序的设计。
本部分软件包括定时器的初始化设置,脑电信号的采集,写AD配置字和串口通信模块。程序初始化包括系统自检和参数设置部分,系统自检是指系统对自身硬件的诊断过程,它可以及时发现系统的故障,采取处理措施。本系统采用上电自检的方法。一般基于对CPU的信任,不对其进行检查,只要对其它的检查通过,就认为CPU工作正常。单片机AT89C51的数据采集模块主要指1路脑电信号的采集,脑电信号采集采用查询工作方式,当采集完一个数据时就进行串行通信发送给PC机。程序流程如图4-1示。
图4-1 脑电信号采集与传输流程
串行通信模块的功能是把单片机所采集到的数据通过RS-232传输给计算机,其串行口工作在模式1,波特率为9600bps,一位起始位,数据为8位,无奇偶校验,一位停止位,其特征与PC机里使用的串行通信协议是一致的,定时器T1作为RS-232的波特率发生器使用,其工作在方式2。参照图4-1所示的程序流程,设计了信号采集和传输程序。
串口的操作可以分同步和异步两种操作方式,无论哪种操作方式,一般对串口的操作都通过打开串口,配置串口,读/写串口和关闭串口四个步骤来完成。
1、打开串口
用API函数CreateFile来打开,在函数中要设定打开串口的名称,指定串口访问的类型和属性等。在本设计中,串口访问类型为读写均可,属性为异步通信。
2、配置串口
在打开串口设备句柄后,需要对串口进行一些初始化设置。通过一个DCB结构来进行。DCB结构包含了诸如波特率、数据位数、奇偶校验和停止位数等信息。在本设计中,波特率为9600bps,一个起始位,数据位8,无奇偶校验,一位停止位。在查询或配置串口的属性时,都要用DCB结构来作为缓冲区。在打开串口后,可以调用GetCommState函数来获取串口的初始配置。程序还需要设置I/O缓冲区的大小和超时。用I/O缓冲区来暂存串口输入和输出的数据。如果通信的速率较高,则应该设置较大的缓冲区。调用SetupComm函数可以设置串行口的输入和输出缓冲区的大小。
在用ReadFile和WriteFile读写串行口时,要设置超时。超时的作用是在指定的时间内没有读入或发送指定数量的字符,ReadFile或WriteFile的操作仍然会结束。在设计程序时,要想实现绝对的实时,那是不可能的。只要将读写串口超时设置的尽可能小,但同时要能够完成读写操作,这样能够最大可能的接近实时通信。在本设计中,读写超时都设置为100毫秒。在读/写串口之前,还要用PurgeComm()函数清空缓冲区。
3、读/写串口
串口的读/写操作是使用ReadFile和WriteFile函数对串口进行读/写。
4、关闭串口
在串口读/写操作完后,要关闭串口,关闭串口可以用串口句柄作为参数调用CloseHandle函数即可。
理解了串口的工作原理以及编程时如何对串口进行操作,根据以上步骤,对串口进行读/写,来收发采集的脑电信号,程序流程如图4-2所示
图4-2 串口通信程序流程图
4.3 脑电波形的显示
在经过串口通信把采集的脑电信号数据传送到PC机上后,为了观察到脑电信号以及对脑电信号进行处理,必须将脑电信号显
示出来。将脑电信号数据波形化,首先要从存储数据的区域把数据读出来,然后再利用绘画函数将其绘制在屏幕上,因为采集的脑电波是动态波形,如果直接将其绘制在屏幕上。有可能会有抖动现象的出现,所以可以先在内存中绘画,然后将绘好的图拷贝到屏幕上,便可以消除抖动现象。程序的实现流程如图4-3
图4-3 波形显示程序流程图
自定义波形绘制函数主要完成将数据绘制成波形的功能,其流程如图4-4
图4-4 波形绘制函数程序流程图
4.4 脑电波信号的处理
脑电波是处于一定的频带范围内的信号波形,由于其它生理信号的干扰,采集来的波形中有其它波形,而脑电波的主要频带集中在0.5-40Hz,所以可以用两个滤波器对其进行滤波,一个是截止频率为40Hz的低通滤波器,另一个是截止频率为0.5Hz的高通滤波器。
4.4.1 低通数字滤波器的设计
脑电信号一般都集中在40Hz频率以下的范围内,所以低通滤波器的截止频率应设为40Hz,阻带的边界频率设为50Hz,最小阻带衰耗为 10dB,采样频率设为256Hz,低通滤波器的设计过程如下:
先要确定滤波器的阶数。频率范围(T=1/f =1/256) [0, /T]=[ ]。把相关频率范围归一化到[0, ]。因此:
截止频率: ωp = 40×2π /256 = 5π /16 (4-1)
阻带频率: ωs = 50×2π /256 = 25π /64 (4-2)
为了采用双线性变换,需将上面两个频率分别进行预畸变,得到
(4-3)
(4-4)
根据滤波器理论ε=1,所以:
(4-5)
阶数N为:
(4-6)
我们取 N 为 4,即四阶低通滤波器。
通过查表,可以得到四阶归一化巴特沃思滤波器的系统函数为:
(4-7)
(4-8)
将 代入上面的系统函数,即式(4-8)得去归一化滤波器的系统函数:
= (4-9)
最后,将s’=(z-1)/(z+1)代入(4-9)式变换得z域得:
= (4-10)
低通数字滤波器的程序实现流程如图4-5
图4-5 低通滤波器程序流程图
4.4.2 高通数字滤波器的设计
根据脑电信号的最低频率一般为 0.5Hz,设置高通滤波器的截止频率为0.5Hz,采用 4 阶滤波器。
通过查表,可以得到四阶归一化巴特沃思滤波器的系统函数为:
H(s)=
=
= (4-11)
截止频率: ωp = 0.5×2π /256 = π /256 (4-12)
将频率进行预畸变,得到:
(4-13)
根据滤波器的频率变换理论,将s =ω'p /s'代入 (4-13),得去归一化滤波器的系统函数:
H(s’)=
= (4-14)
最后,将s' = (z -1)/(z +1)代入式(4-14)变换到z域得:
H(z)= (4-15)
=
高通数字滤波器的程序实现流程与低通数字滤波器的流程差不多,只是在计算采样输出值时采用的计算公式不同而已。
4.5 小结
本章首先讲了基于单片机AT89C51的串口通信,设计了程序流程,接着设计了脑电波形的显示,以流程图的方式说明了如何实现程序,将脑电波显示在屏幕上,然后设计了数字滤波器对波形进行简单的滤波处理,包括低通数字滤波和高通数字滤波,并以流程图方式说明了程序的实现。
第5章 软件的调试
调试是设计的关键部分,调试可以检验设计的正确性和是否达到设计要求。
5.1 脑电信号采集与传输程序的调试
在按流程图编写完程序后,对本程序进行了调试,但一开始调试程序并没有调试成功,调试器报错说是试图去定义一个已定义过的标号,还有一个就是说没有找到代码段地址,如下图5-1所示
图5-1 未通过的程序调试图
但经检查,标号定义又没有错,于是又查阅资料,同时也请教同学帮忙,最后才得以解决,原来可能是Keil的编译器不认识所定义的标号,于是又在标号前加上了一个”-”才调试通过。如下图5-2所示
图5-2 通过的程序调试图
5.2 串口通信程序的调试
本串口程序是用VC编写的,在调试串口程序时,也出了几个错误。其中最严重的一个错误是对话框中加入了静态文本框,用于显示接收的数据,但没有将它加入到对框类的成员变量中去,在调试时出现了未定义变量的错误。经过修改,程序得以调通。因为在调试程序时没有将串口线与单片机和PC相接,程序没有检测到串口,所以在点串口通信菜单后会出现打开串口失败的提示,点接收按钮也会出现写串口失败的提示,表明程序能完成串口的检测并对串口进行读写操作。如图5-3和图5-4所示。
图5-3 打开串口失败提示
图5-4 串口通信程序界面
图5-5 提示写串口失败
5.3 脑电波形显示程序调试
在用VC编好波形显示程序后,对程序进行了调试,出现了很多问题,如函数未定义,变量没有定义,某函数不是类的成员函数等。如下图5-6所示
图5-6 未通过程序调试图
按照错误提示,发现了函数DrawWave()是CShowWave类的一个成员函数,没有在类的头文件中进行说明,在类的头文件中的公有函数中加了DrawWave()的申明后,经调试,有关函数没有定义和联队数中的相关变量没有定义没有了。但还是有个错是调用了库函数中数学函数,没有在文件中将math.h文件包含在源程序中,将此头文件加入后,所有的错误都调试通了。但是点击工具栏里的显示波形按钮,发现没有波形显示出来,也没有出现对话框,后来经过认真的思考和分析之后,才发现没有将波形显示按钮和对话框关联起来,于是又在文档类的实现文件中加入了模式对话框,才将波形显出来。通过的程序调试图如图5-7
图5-7 通过的程序调试图
将脑电信号波形在计算机上显示出来,波形显示结果如图5-8所示。
图5-8 波形显示结果
5.4 脑电波处理程序调试
脑电信号的频带为0.5-40Hz,所以高通滤波器的截止频率为0.5Hz,低通滤波器的截止频为40Hz,对信号进行低通和高通数字滤波,结果如图5-9所示。
(a) 低通数字滤波后的效果
(b) 高通数字滤波后的效果
图5-9 数字滤波处理后的脑电波
5.5 小结
本章主要讲了采集和传输控制程序,串口通信程序,波形显示程序和波形
处理程序的调试和在调试中遇到的问题,以及问题是如何解决的,通过调试程序,基本达到了设计的要求。
总 结
本设计借助于模数转换器,单片机,串口通信等方面的技术,对脑电信号进行采集控制和传输,同时用VC编程实现了波形的实时显示及简单的后绪处理。在设计之初,由于对单片机的认识不是很深,对模数转换器的转换原理没有搞清楚,在设计时就没有考虑到资源是否够用,所以出现了方案一中的错误,在经过老师的讲解之后,重新选择元器件,设计出了可行的方案二。但是本设计却还存在着不少缺陷,由于受模数转换器ADC0809的影响,脑电信号采集的通道数最多只有8路模拟信号,而本设计只采集了一路信号,实际应用中难以满足要求,同时本设计采用串口通信技术,所以信号的传输速率不是很高。该设计软件部分只是对脑电信号的显示和滤波处理,处理功能很少,对在实际中的要求很难满足。
由于本人知识水平有限,设计中还存在有许多不足,望老师给予指正,同时本人也希望在以后继续完善本设计,使本设计的处理功能更加强大,以便在条件成熟时能够应用到实际中去。
致 谢
在这次毕业设计过程中,有许多老师和同学都给予了我很大的帮助,在此我表示衷心的感谢,我首先想感谢我的导师韩雪梅老师、李俊国老师,感谢导师给了我一个的良好锻炼机会,感谢他们对本论文的选题、研究工作及论文撰写过程中给我的悉心指导和鼓励。同时也要感谢蔡波老师给予我的帮助。正是在他们的关心、帮助下,我的毕业设计才顺利完成。
我也要感谢四年来给我默默传授知识的所有老师,感谢他们对我无私的教诲和帮助,是在他们的辛勤培育下我才有了今天的成绩;同时我也要感谢李实同学、王显付同学给予我的帮助,才使我的设计工作开展得如此顺利,把四年的理论与实践进行了一次完美的结合。
还有和我在实验室一起做毕业设计的同学们,感谢王显付、李实、颜雄、韩俊等同学,有了他们在生活和学习上对我的帮助,使我愉快的完成了本科阶段的学习,这四年的生活会成为我一生中最难忘的时光。
最后,还要感谢我的家人,来自家庭的温暖、关爱和支持,是我不断前进的动力源泉。
这次设计是我毕业前的最后一次练兵,每一位老师、同学给予我的帮助将会让我受益终身!
我再次真诚地感谢他们!!!
参考文献
[1] 张明岛,陈兴时等.脑诱发电位学[M].上海科技教育出版社,1995.
[2] 谭郁玲,侯沂等.临床脑电图与脑地形学[M].人民卫生出版社,1997.
[3] 李经纬,程之范. 中国医学百科全书.医学史分卷[M].上海科技出版社,1987.
[4] 沈风麟,陈和晏.生物医学信号处理[M].中国科学技术大学出版社,1999.
[5] Gath, the tracking of rapid dynamic changes in seizure EEG[J],IEEE Trans biomed Eng,1992.
[6] Morisisa T M,et al, BEAM in Psychiatry[M].Washington D.C American Psychiatric Press, 1984.
[7] 逢玉台,干建华,孙传焙.ADC0832在湿度数据采集中的应用[J].西安通信学院学报,2004:3(5):46-48.
[8] 郑国君.8位串行A/D转换器ADC0832[J].电子世界,2002,9:44-45.
[9] 肖忠样.数据采集原理[M].西北工业大学出版社,2001.
[10] 王幸之,钟爱琴,王雷等.AT89系列单片机原理与接口技术[M].北京航空航天人学出版社,2004.
[11] 李春胜.基于脑电的脑—计算机接口技术硬件实现方法的研究[D].东北大学硕士学位论文,2002.
[12] 汀春华.数字式肌电假肢控制系统的研究[D].大连理工大学硕士学位论文,2003.
[13] 吴金戌,沈庆阳,郭庭吉. 8051单片机实践与应用[M].清华大学出版社,2002.
.Clinical Neurophysiology,2002,113 (1):767-791.
附 录
附录Ⅰ
源程序代码及注释:
;═════════════════════════════════════
;信号采集与传输程序:
CK EQU P1.4 ; 定义时钟
DO EQU P1.5 ; 转换输出端
DI EQU P1.6 ; 配置输入端
CS EQU P1.7 ; 片选端
ORG 0000H ;主程序入口
AJMP MAIN ;转到主程序
ORG 0040H ;主程序入口
MAIN: MOV TMOD,#20H ;T1选取方式2, 8位计数
NOP ;空闲
MOV TH1,#0FDH ; 选择波特率为9600bps
NOP
MOV TL1,#0FDH ;
NOP
SETB TR1 ;启动定时器
NOP ;
MOV SCON,#040H ; 选择串口方式1,10位异步通信格式
NOP
_SEND: MOV SBUF,A ;发送AD采集来的数据
CLR CS ;片选
NOP
MOV A, #03H ;配置AD为单输入端
MOV R0,#03H ;送3个位
_WR: CLR CK;
RRC A ;
MOV DI,C ;开始配置AD
SETB CK;
DJNZ R0,_WR
CLR CK
NOP
SETB CK
MOV R0,#8 ; 循环8次
_RD: CLR CK
MOV C,DO
RLC A
SETB CK
DJNZ R0,_RD
SETB CS
NOP
_WAIT: JNB T1,_WAIT ;等待发送完毕
CLR T1
NOP
SJMP _SEND ;继续发送
END
//═════════════════════════════════════
//串口通信模块程序
//串口初始化:
BOOL CSerialcomm::OnInitDialog()
{ CDialog::OnInitDialog();
// TODO: Add extra initialization here
hCom=CreateFile("COM1",//COM1口
GENERIC_READ|GENERIC_WRITE, //允许读和写
0, //独占方式
NULL,
OPEN_EXISTING, //打开而不是创建
1, //异步方式
NULL);
if(hCom==(HANDLE)-1)
{ AfxMessageBox("打开COM失败!");
return FALSE;
}
SetupComm(hCom,100,100); //输入缓冲区和输出缓冲区的大小都是1024
COMMTIMEOUTS TimeOuts;
//设定读超时
tervalTimeout=MAXDWORD;
talTimeoutMultiplier=0;
talTimeoutConstant=0;
//在读一次输入缓冲区的内容后读操作就立即返回,
//而不管是否读入了要求的字符。
//设定写超时
otalTimeoutMultiplier=100;
otalTimeoutConstant=500;
SetCommTimeouts(hCom,&TimeOuts); //设置超时
DCB dcb;
GetCommState(hCom,&dcb);
te=9600; //波特率为9600
ze=8; //每个字节有8位
=NOPARITY; //无奇偶校验位
ts=ON
ESTOPBITS; //1个停止位
SetCommState(hCom,&dcb);
PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
//发送模块程序:
void CSerialcomm::OnSend()
{ // TODO: Add your control notification handler code here
// TODO: Add your control notification handler code here
//串行半双工,帧11位,1个起始位(0),8个数据位,2个停止位(1)
//如:读仪表显示的瞬时值,主机发送:DC1 AAA BB ETX
//其中:DC1是标准ASCII码的一个控制符号,码值为11H(十进制的17)
//在通讯协议中,DC1表示读瞬时值
//AAA是从机地址码,也就是通讯地址
//BB为通道号,读瞬时值时该值为01
//ETX也是标准ASCII码的一个控制符号,码值为03H
//在通讯协议中,ETX表示主机结束符
char lpOutBuffer[7];
memset(lpOutBuffer,'\0',7); //前7个字节先清零
lpOutBuffer[0]='\x11'; //发送缓冲区的第1个字节为DC1
lpOutBuffer[1]='0'; //第2个字节为字符0(30H)
lpOutBuffer[2]='0'; //第3个字节为字符0(30H)
lpOutBuffer[3]='1'; // 第4个字节为字符1(31H)
lpOutBuffer[4]='0'; //第5个字节为字符0(30H)
lpOutBuffer[5]='1'; //第6个字节为字符1(31H)
lpOutBuffer[6]='\x03'; //第7个字节为字符ETX
//从该段代码可以看出,仪表的通讯地址为001
DWORD dwBytesWrite=7;
COMSTAT ComStat;
DWORD dwErrorFlags;
BOOL bWriteStat;
ClearCommError(hCom,&dwErrorFlags,&ComStat);
bWriteStat=WriteFile(hCom,lpOutBuffer,dwBytesWrite,& dwBytesWrite,NULL);
if(!bWriteStat)
{ AfxMessageBox("写串口失败!");
}
}
//接收模块程序:
void CSerialcomm::OnReceive()
{ // TODO: Add your control notification handler code here
char str[100];
memset(str,'\0',100);
DWORD wCount=100;//读取的字节数
BOOL bReadStat;
bReadStat=ReadFile(hCom,str,wCount,&wCount,NULL);
if(!bReadStat)
AfxMessageBox("读串口失败!");
PurgeComm(hCom, PURGE_TXABORT|
PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
m_disp=str;
UpdateData(FALSE);
}
//═════════════════════════════════════
//脑电信号显示程序:
//绘波形模块函数:
void CShowWave::DrawWave(CDC *pDC)
{ CRect rect;
CString str;
int i;
int m_left,m_top,m_right,m_bottom;
int m_Interval = (m_High - m_Low)/10;
if (m_Interval < 1) m_Interval = 1;
// 获取绘制坐标的文本框
Candy* pWnd = GetDlgItem(IDC_COORD);
pWnd->GetClientRect(&rect);
pDC->Rectangle(&rect);
m_left = +10;
m_top = +10;
m_right = -10;
m_bottom = -20;
int m_IntervalPan = (m_right - m_left)/11;
if (m_IntervalPan < 1 ) m_IntervalPan =1;
// 创建画笔对象
CPen* pPenRed = new CPen;
// 红色画笔
//pPenRed->CreatePen(PS_SOLID,1,RGB(255,0,0));
// 创建画笔对象
CPen* pPenBlue = new CPen;
// 蓝色画笔
pPenBlue->CreatePen(PS_SOLID,1,RGB(0,0, 255));
// 创建画笔对象
CPen* pPenGreen = new CPen;
// 绿色画笔
pPenGreen->CreatePen(PS_DOT,1,RGB(0,255,0));
// 选中当前红色画笔,并保存以前的画笔
CGdiObject* pOldPen = pDC->SelectObject(pPenRed);
// 绘制坐标轴
pDC->MoveTo(m_left,m_top);
// 垂直轴
pDC->LineTo(m_left,m_bottom);
// 水平轴
pDC->LineTo(m_right,m_bottom);
// 写X轴刻度值
for(i=0;i<10;i++)
{ //(_T("%d"),m_Min+i*m_Interval);
(_T("%d"),m_Low+i*m_Interval);
pDC->TextOut(m_left+i*m_IntervalPan,m_bottom+3,str);
}
//(_T("%d"),m_Max);
(_T("%d"),m_High);
pDC->TextOut(m_left+10*m_IntervalPan,m_bottom+3,str);
// 绘制X轴刻度
for (i = m_left; i < m_right-20; i += 5)
{ if ((i & 1) == 0)
{ // 10的倍数
pDC->MoveTo(i + 10, m_bottom);
pDC->LineTo(i + 10, m_bottom+4);
}
else
{ // 10的倍数
pDC->MoveTo(i + 10, m_bottom);
pDC->LineTo(i + 10, m_bottom+2);
}
}
// 绘制Y轴箭头
pDC->MoveTo(m_right-5,m_bottom-5);
pDC->LineTo(m_right,m_bottom);
pDC->LineTo(m_right-5,m_bottom+5);
// 绘制X轴箭头
pDC->MoveTo(m_left-5,m_top+5);
pDC->LineTo(m_left,m_top);
pDC->LineTo(m_left+5,m_top+5);
// 绘制Y轴网格 选择绿色画笔
pDC->SelectObject(pPenGreen);
int iTemp = (m_bottom - m_top)/5;
for (i = 1 ;i <= 5 ;i++)
{ pDC->MoveTo(m_left,m_bottom - i*iTemp);
pDC->LineTo(m_right,m_bottom - i*iTemp);
}
//数组赋值
if(m_now<1024)
{ m_now++;
}
else
{ m_now = 0;
}
for(i = m_Low;i<m_High;i++)
{ //m_lCount[i]=(rand()%10+rand()%100+rand()%1000)%1024;
m_lCount[i] = (int)(sin(i-m_now)*204);
}
int xTemp;
int yTemp;
// 更改成蓝色画笔
pDC->SelectObject(pPenBlue);
for (i = m_Low; i <= m_High; i=i+3)
{ xTemp = m_left+(i-m_Low)*m_IntervalPan/m_Interval;
yTemp = m_bottom/2 - (int) (m_lCount[i] * m_bottom / 1024);
if (yTemp < m_top) yTemp = m_top;
if((xTemp >=m_left)&&(xTemp <=m_right))
{ pDC->MoveTo(xTemp, m_bottom/2);
pDC->LineTo(xTemp, yTemp);
}
}
// 恢复以前的画笔
pDC->SelectObject(pOldPen);
delete pPenRed;
delete pPenBlue;
delete pPenGreen;
return;
}
//波形显示模块程序:
void CShowWave::OnTimer(UINT nIDEvent)
{// TODO: Add your message handler code here and/or call default
CRect rect;
// 获取绘制坐标的文本框
Candy* pWnd = GetDlgItem(IDC_COORD);
//获得对话框上的picture的窗口句柄
pWnd->GetClientRect(&rect);
// 指针
pDC = pWnd->GetDC();
pWnd->Invalidate();
pWnd->UpdateWindow();
//内
存绘图
CBitmap memBitmap;
CBitmap* pOldBmp = NULL;
//创建内存绘图设备
CompatibleDC(pDC);
CompatibleBitmap(pDC,,);
pOldBmp = Object(&memBitmap);
(,,,,pDC,0,0,SRCCOPY);
//自定义绘图函数,
DrawWave(&memDC);
//把内存绘图拷贝到屏幕
pDC->BitBlt(,,,,&memDC,0,0,SRCCOPY);
Object(pOldBmp);
DC();
Object();
CDialog::OnTimer(nIDEvent);
}
//═════════════════════════════════════
//波形处理程序:
//低通滤波程序:
void CLFiltre::lfilter(float *data ,long len)
{ int i;
float *data_t;
// 输入,输出临时缓冲区;
float xv[5], yv[5];
//滤波器增益
float GAIN=4.72016e+01;
//输出采样值;
double out;
//初始化输出缓冲区;
for(i=0;i<5;i++)
yv[i]=0;
data_t=data;
//读取当前采样值
xv[4] = *data_t / GAIN;
xv[0] = xv[4]; xv[1] = xv[4];
xv[2] = xv[4]; xv[3] = xv[4];
for(i=0;i<len;i++)
{ data_t++;
xv[0] = xv[1]; xv[1] = xv[2];
xv[2] = xv[3]; xv[3] = xv[4];
xv[4] = float(*data_t) / GAIN;
//更新状态;
yv[0] = yv[1]; yv[1] = yv[2];
yv[2] = yv[3]; yv[3] = yv[4];
//计算输出采样值;
out =(xv[0] + xv[4]) + 4 * (xv[1] + xv[3]) + 6 * xv[2]+(-0.0678 * yv[0])+ ( 0.4355 * yv[1]) +( -1.1780 * yv[2]) + ( 1.4713 * yv[3]);
yv[4] =(float) out;
*data_t=yv[4];
}
}
//高通滤波处理程序:
void CHFilter::hfilter(float *data ,long len)
{ int i;
float *data_t;
// 输入,输出临时缓冲区;
float xv[5], yv[5];
//滤波器增益
float GAIN=1.0162;
//输出采样值;
double out;
//初始化输出缓冲区;
for(i=0;i<5;i++)
yv[i]=0;
data_t=data;
//读取当前采样值
xv[4] = *data_t / GAIN;
xv[0] = xv[4]; xv[1] = xv[4];
xv[2] = xv[4]; xv[3] = xv[4];
for(i=0;i<len;i++)
{ data_t++;
xv[0] = xv[1]; xv[1] = xv[2];
xv[2] = xv[3]; xv[3] = xv[4];
xv[4] = float(*data_t) / GAIN;
//更新状态;
yv[0] = yv[1]; yv[1] = yv[2];
yv[2] = yv[3]; yv[3] = yv[4];
//计算输出采样值;
out =(xv[0] + xv[4]) - 4 * (xv[1] + xv[3]) + 6 * xv[2]+(-0.9684 * yv[0])+ ( 3.9048 * yv[1]) +( -5.9043 * yv[2]) + ( 3.9679 * yv[3]);
yv[4] =(float)out;
*data_t=yv[4];
}