隨着電子技術的發展,打印機已經普遍應用到各個領域,成爲各類智能數字化儀器儀表的重要數據輸出手段。而其中熱敏打印機憑其體積小、重量輕、可靠性高、打印字符清晰、無噪聲、走紙均勻等獨特能而愈來愈受到青睞,更是成爲小型醫療儀器如心電圖機的首先。html
下面以筆者課題組開發的12導同步心電圖機爲例,介紹以普通52單片機爲主控芯片應用串行熱敏打印機實現多種方式的心電圖形打印,並重點描述了12導聯同步打印方式的程序實現方案。算法
1 系統硬件設計緩存
系統配置了一個內置式數字打印機,它主要由熱敏打印頭(W216-QS)和步進電機組成。W126-QS點陣式熱敏打印頭打印數據採用串行輸入,其內部不只包含有由C-MOS集成芯片構成的1728位移位寄存器,還包含藉助高密度厚膜工藝製成的加熱元件。這些加熱元件經過鎖存和切換晶體管驅動,可在熱敏打印紙上產生1728個點,對應的打印寬度爲216mm,分辨率爲8dot/mm。熱敏打印頭所需的打印數據爲串行數據,數據傳輸遵循SPI口的通訊協議。系統採用了口線模擬SPI的工做方式與打印頭通訊,電路如圖1所示。.net
考慮到52單片機內部令有256字節的內部RAM,系統還外擴1片HM628128存儲12導心電數據和中間轉換結果。設計
2 系統軟件編寫htm
數字打印實現的兩個關鍵問題:①如何將心電數據轉換成打印數據;②若是將數據輸出到數字打印機。一般採用的方法是轉換數據同時將其輸出到打印機打印。這樣節省了存儲器空間;缺點是程序實現複雜,通用性差(不一樣打印方式的數據輸出程序不一樣),系統功能不易擴展,數據轉換和輸出都要考慮打印點位置,而且每輸出一點的數據都要調用一次程序,加大了系統開銷。系統軟件中沒有采有這種方式,而是在內存中開闢216字節打印緩衝區,將熱敏打印頭1728個點與216×8位數據相對應,每次將要打印的一線數據都轉換完再輸出。這樣只需在數據轉換時考慮打印位置和方式,輸出程序只需將216字節的數據按位輸出便可,而且每打印一線數據只需調用一次輸出子程序,字節了系統開銷。缺點是佔用系統資源,這一點在12導同步打印表現得尤其明顯。接口
系統程序實現三種打印方式:分兩次打印12導聯數據,每次打印6導、12導同步打印、縱向打印(打印效果如圖2)。在每一種打印程序中實現模擬SPI口將打印數據送至數字打印機的子程序共用,不一樣處在於如何將心電數據轉換成打印數據。ip
2.1 I/O口線模擬SPI口內存
SPI(Serial Peripheral InteRFace)總線串口是由Motorola公司提出的一種同步串行外設接口,經過四根線進行通訊:時鐘線(SPKCLK)、數據輸出線(SPIMISO)、數據輸出線(SPIMOSI)、片選線(CS),內部經過SPIDAT寄存器完成串-並/並-串轉換。它主要工做在主從式系統中,一個主器件能夠帶多個從器件,主器件經過片選線控制總線衝突,使同一時刻只有一個從器件與從器件交換數據。資源
系統應用的串行熱陣式打印機數據傳輸採用SPI時序,但普通52單片機無SPI口,因此採用I/O口線模擬SPI時序。考慮到系統中MCU做爲主器件老是發送數據,而數字打印機做爲惟一從器件又老是接收數據,因此只需用口線模擬SPI口的時鐘線(SPIKCLK)、數據輸出線(SPIMOSI),程序模擬SPIDAT完成並-串轉換便可。如前所提到打印頭打印的數據點數爲1728點,分辨率爲8mm/mV,對應216字節的數據,爲此從內部RAM中分配出216字節的空間做爲打印緩衝區,程序從緩衝區依次讀數據,在模擬時鐘線的控制下將並行數據轉換成的串行數據按位依次送至打印機的移位寄存器中,結束後送LATCH鎖存信號和打印頭加熱脈衝STROBE,從而在熱敏打印紙打印出一線心電圖形,驅動步進電機向前走紙便可以連續打印。SPI口模擬程序以下:
OUTPUT:
現場保護
LCALL INTRAM ;初始化內部打印緩衝區
MOV R0,#Dat_Buff ;初始化R0爲緩衝區末位地址
DAT_OUT:
MOV A,@R0 ;從緩衝區讀數據
MOV R7,#08H ;初始化R7控制並/串數據轉換
CONT_CHG:
RRC A ;對ACC循環右移實現並-串轉換
MOV P1.3,C 將串行數據送至打印機
SETB P1.1 ;模擬SPI時鐘
NOP
CLR P1.1
DJNZ R7,CONT_CHG ;判斷1字節數據是否轉換完
DEC R0 ;尋址下一字節
CJNE R0,#15H,DAT_OUT;判斷數據是否所有轉換完
CLR P1.2 ;產生數據鎖存信號
NOP
SETB P1.2
NOP
CLR P1.0 ;產生加熱脈衝
LCALL HEATDLY ;調用加熱延時程序
SETB P1.1
LCALL MOTOR_RUN ;步進電機走紙
恢復現場
RET
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導聯前16mm空間和V6導聯的後16mm空間沒有被複用,打印紙的其它空間都是被兩個導聯共用。內部RAM使用狀況也與之相似。爲此在外部RAM開闢一個內部打印緩衝區的影像區(大小爲216字節,單元地址的低8位與內存相應單元相同,如內部RAM 0x1DH單元與外部RAM 0xXX1DH相對應),將12導聯分爲兩組:一組(I,III,aVL,V1,V3,V5)仍然存儲於內部存儲器,而另外一組(II,aVF,V2,V4,V6)存儲於外部影像區,在12導聯一線數據轉換完要打印時,將兩部分按照對應單元相與便可。這樣作不但能夠解決上述問題,並且節省了內部資源、下降程序編寫的難度。
如前所述不一樣導聯所佔的打印空間不一樣,因此,對於某導聯心電信號,先要肯定其打印區間,而後再肯定打印數據在該區間的相對位置。
假定某導聯所佔打印空間的起始字節爲第n個字節,而要打印的心電數據爲m,將m除以8,得商k,餘數爲1,則此心電數據對應點對數(n-k)字節的第1位。即該心電數據對應的位置數據爲第(n-k)字節(該字節的1位置1,其它位清零)。所以,打印此心電數據時,該導聯所要傳送的32字節打印數據中只有第(n-k)字節的第1位爲1,其餘都爲0。
與液晶顯示相相似,對於一個導聯的心電信號,要實現心電圖打印,必須將盯連兩個心電數據用線鏈接。即對於一條心電曲線,起始顯示數據點在起始列只顯示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,依次與通道的每個數據進行比較:相同則對應點被描記;小則不被描記;大則須要將當前心電數據相鄰的兩點與掃描值相比較,只要其中一個比掃描值大,則對應點被描記,要描記的噗將其內存對應的數據位置1。
舉例說明,若是打印內存緩衝區的首字節爲n,大小爲216字節,而當前某一導聯順序第m個心電數據是v,而此時的掃描值爲w:①v>w,則繼續比較第m+1個數據;②v=w,則對應點須要被描記;③v。