随着电子技术的发展,打印机已经广泛应用于各个领域,成为各种智能数字仪器的重要数据输出手段。其中,热敏打印机以其体积小、重量轻、可靠性高、打印字符清晰、无噪音、送纸均匀等独特特点越来越受欢迎,率先成为心电图机等小型医疗仪器。
以作者所在课题组研制的12导联同步心电图机为例,介绍了应用以普通52单片机为主控芯片的串行热敏打印机实现各种心电图打印,并重点介绍了12导联同步打印的程序实现方案。
1系统硬件设计
系统配有内置数码打印机,主要由热敏打印头(W216-QS)和步进电机组成。W126-QS点阵热敏打印头的打印数据采用串行输入,不仅包含C-MOS集成芯片组成的1728移位寄存器,还包含高密度厚膜工艺制作的发热元件。这些加热元件由锁存和开关晶体管驱动,可以在热敏打印纸上产生1728个点,对应的打印宽度为216mm,分辨率为8dot/mm,热敏打印头所需的打印数据为串行数据,数据传输遵循SPI口的通信协议。系统采用端口线模拟SPI的工作模式与打印头通信,电路如图1所示。
考虑到52单片机内部RAM为256字节,系统还扩展了一个HM628128,用于存储12路心电数据和中间转换结果。
2系统软件编写
数字打印的两个关键问题:如何将心电数据转换成打印数据;如果数据输出到数字打印机。通常的方法是将数据转换后输出到打印机进行打印。从而节省存储空间;缺点是程序实现复杂,通用性差(不同打印方式的数据输出程序不一样),系统功能不易扩展,数据转换输出要考虑打印点的位置,每次输出数据都要调用一次程序,增加了系统开销。软件中不采用这种方法。而是在内存中打开一个216字节的打印缓冲区,热敏打印头的1728个点对应2168位数据。每一次,要打印的第一行数据被转换,然后输出。这样在数据转换时只需要考虑打印位置和方式,输出程序只需要逐位输出216字节的数据,输出子程序只需要在每次打印第一行数据时调用一次,减少了系统开销。缺点是占用系统资源,在12导联同步打印中尤为明显。
程序实现了三种打印模式:两次打印12导联数据,每次同步垂直打印6导联和12导联(打印效果如图2所示)。在每个打印程序中,模拟SPI端口用于向数字打印机的子程序发送打印数据。区别在于如何将心电数据转换成打印数据。
2.1 I/O端口线模拟SPI端口。
SPI(串行外设接口)总线串口是摩托罗拉公司提出的同步串行外设接口。它通过四条线路进行通信:时钟线(SPKCLK)、数据输出线(SPIMISO)、数据输出线(SPIMOSI)和片选线(CS)。串并/并串转换通过SPIDAT寄存器完成。它主要工作在主从式系统中,一个主设备可以有多个从设备,主设备通过片内选线控制总线冲突,使得同一时间只有一个从设备可以与从设备交换数据。
系统中使用的串行热敏阵列打印机采用SPI时序进行数据传输,而常见的52单片机没有SPI口,所以采用I/O口线来模拟SPI时序。考虑到系统中作为主设备的MCU总是发送数据,而作为唯一从设备的数码打印机总是接收数据,所以只需要用port线模拟SPI口的时钟线(SPIKCLK)和数据输出线(SPIMOSI),程序模拟SPIDAT完成并串转换。如前所述,打印头打印的数据点数为1728,分辨率为8mm/mV,对应216字节的数据。因此,从内部RAM中分配216字节的空间作为打印缓冲区。程序依次从缓冲区读取数据,在模拟时钟线的控制下,将并行数据转换成的串行数据逐位送到打印机的移位寄存器。之后,发送LATCH锁存信号和打印头加热脉冲选通,这样就可以在热敏打印纸上打印一行心电图。SPI仿真程序如下:
输出:
现场保护
LCALL INTRAM初始化内部打印缓冲区
MOV R0,# Dat _ BuffR0被初始化为缓冲器的最后一个地址。
DAT_OUT:
MOV A,@ R0从缓冲区读取数据
MOV R7,# 08HR7被初始化以控制并行/串行数据转换。
续CHG:
RRC A;ACC循环右移实现并串转换。
Pv1.3,c向打印机发送串行数据
SETB p 1.1;模拟SPI时钟
nototherwiseprovided(for)除非另有规定
CLR P1.1
CHG的DJNZ R7判断1字节数据是否被转换。
DEC R0寻址下一个字节
CJNE R0,#15H,DAT _ OUT判断是否所有数据都被转换。
CLR P1.2产生数据锁存信号
nototherwiseprovided(for)除非另有规定
SETB P1.2
nototherwiseprovided(for)除非另有规定
CLR P1.0产生加热脉冲
l打电话热;调用加热延迟程序
SETB P1.1
LCALL MOTOR _ RUN步进电机送纸
还原现场
浸水使柔软
2.2打印算法
数字打印机本质上实现了数据与打印点的对应,也就是说8位心电数据的取值范围是0 ~ 255,对应的是热敏打印纸上的256个点。通过加热敏感单元,纸张上的某个点会变黑,以显示数据大小。因此,需要将代表实际心电图大小的数据(以下简称原始数据)转换成能够指示加热点位置的数据(以下简称位置数据)。通过控制位置数据,依次打印出心电图数据的对应点,即可得到心电图。但是由于系统的模数转换器得到的心电数据是离散的,如果只把它们对应的点打印出来,只会得到一些离散的点。为了获得连续的心电图形状,需要按照一定的算法将相邻的离散点连接起来。对于垂直打印和水平打印,连接离散点的算法是不同的。由于篇幅的限制,在下面描述的打印模式的实现中,只详细描述了横向12导联同步打印和纵向打印,而只介绍了6导联打印的实现思路。
2.2.1水平6引脚印刷
心电图纸长度为216mm,每个导联心电图信号分配32mm,对应打印缓冲区中连续的32个字节。打印数据转换后的位置数据存储在这32个字节中。12导联心电图数据分为两组。打印一组时,打印剩余的6导联数据。具体实现过程可以参考横向12引线印刷模式。
2.2.2水平12引线同步印刷
在实施6导联打印模式的过程中,我们注意到,在大多数情况下,一个完成的心电波形中只有QRS波的主峰可以填满整个空间,而其他波段的幅度较小,占用的空间也很小,这些波段可以提供更多的信息。另外,单独打印12个导联也不利于医生同时比较不同导联的心电波形。而采用12导联同步打印时,虽然有些波形重叠,但对某些心脏疾病的诊断影响不大,可以获得更直观的结果。
12引线同步印刷程序的基本思想与6引线同步印刷程序的基本思想相同。不同之处在于,12个导联的数据同时打印在216mm宽的打印纸上,不可避免地导致不同导联的心电图形状重叠,相应的存储单元会被重复使用。如果单纯应用6导联打印程序,前一导联的数据会被相邻导联的数据冲掉,导致图形无法正确显示。图3显示了为每个导联分配的热敏打印纸空间和缓冲存储器单元(这里假设缓冲地址为0x1DH~0xEDH)。从图3中可以看出,除了铅芯I的第一个16毫米间距和铅芯V6的最后一个16毫米间距之外,打印纸的其他间距由两根铅芯共享。RAM的内部使用类似。为此,在外部RAM(大小为216字节,单位地址的低8位与存储器中的对应单位相同,例如内部RAM0x1DH单位对应外部RAM0x1DH单位)中打开内部打印缓冲区的一个图像区,将12个导联分为两组:一组(I、III、aVL、V1、V3、V5)仍存储在内部存储器中,另一组(II、 save)这样既能解决上述问题,又能节省内部资源,降低编程难度。
如上所述,不同导联占用不同的打印空间,所以对于某一导联心电信号,首先要确定打印间隔,然后再确定打印数据在间隔内的相对位置。
假设导联占据的打印空间的起始字节是第n个字节,要打印的ECG数据是M,将M除以8得到商K,余数是1,则该ECG数据对应于点对数(n-k)字节的第1位。即,对应于ECG数据的位置数据是第(n-k)个字节(该字节的1位是1位,其他位被清除)。因此,当打印该ECG数据时,只有该导联要传输的32字节打印数据中的第(n-k)字节的第1位为1,而所有其他位为0。
类似于液晶显示,对于一个导联的心电信号,要打印心电,必须用导线连接两个心电数据。也就是说,对于一个ECG曲线,初始显示数据点仅在初始列中显示1个点;从第二个数据点开始,从上一个数据点到当前数据点的线段应显示在下一列中。在热敏打印纸上,显示两个数据点之间的所有点都被加热,与内存相对应,两点之间的所有数据都被设置为1。
对于导联心电图信号,首先读取第一个心电图数据,然后将其转换为32字节的位置数据,以便直接打印。从第二个心电数据开始,除了转换成位置数据外,还要与前面的数据进行比较,从小数对应的位置数据中减去大数对应的位置数据,然后将结果与大数的位置数据相加。这样一来,这个心电数据就应该发送32个字节的数据,也就是完成了与前面的心电数据连接的操作。发现连接算法只影响两个相连位置的数据中非零字节之间的数据。为了简化计算,只需要减去这些字节,而不是计算所有32个字节。对于加法,只需要将大数对应的位置数据中的非零字节相加,也就是单字节相加。
比如V6导联心电信号,前一个数据是37H,后一个数据是55H,V6导联分配的打印间隔是1DH~3DH。根据位置数据转换算法,37H的位置数据为37H字节,其中包含80H,其他所有字节为00H。55H的位置数据为33H字节,其内容为20H,其他字节为00H。作为37H〈55H,应该是心电图数据55H的位置数据减去33H的位置数据。计算如图4所示。
2.3垂直打印程序
垂直打印可以实现12导联数据同时显示,不重叠。这样,医生可以同时参考和比较各种波形的变化趋势,为疾病的诊断提供方便。
热敏打印纸的宽度为216mm,分辨率为8dot/mm,这样最多可以打印1728个点,而这些点对应的是某个导联的1728个连续的心电图数据,即导联序列的第n个数据对应的是线图中的第n个点。相对于模具印刷,垂直印刷仍然要解决离散点的连接问题;但相对于横向顺序打印法,即按时间顺序打印点,难点在于需要同时打印多个不同时间振幅相同的点,即按照空间顺序打印点。
首先定义一个存储单元存储扫描值,扫描值从当前通道数据的最大值变为0,依次与每个通道数据进行比较:如果相同,则跟踪对应点;小的不被追查;有必要将当前ECG数据的两个相邻点与扫描值进行比较。只要其中一个大于扫描值,对应点就被跟踪,要跟踪的数据位置在其内存中为1。
例如,如果打印记忆缓冲区的第一个字节为N,大小为216字节,当前某个导联序列的第M个心电图数据为V,此时的扫描值为W: VW,继续比较第M个数据;v=w,对应点需要追踪;第五章.