可能感興趣的項(xiàng)目設(shè)計(jì):應(yīng)用于 POS 機(jī)、收銀機(jī)等80mm 高速微型打印機(jī)(原理圖、上位機(jī)、程序源碼)
附件內(nèi)容截圖:
字庫(kù)改組:
為了便于處理,我們對(duì)字模進(jìn)行如下改組:
把 16 X 16 漢字,分成左邊從上到下16個(gè)字節(jié),和右邊16個(gè)字節(jié),目的是可以把一個(gè)漢字當(dāng)成兩個(gè) 16X8 字母或數(shù)字處理。
改組后,字模數(shù)據(jù)從 RAM 讀出送往打印機(jī)時(shí),無(wú)論是漢字還是字母或數(shù)字,第n行點(diǎn)的 "字節(jié)數(shù)據(jù)" 就是: n, n+16, n+16*2, n+16*3......一行取48個(gè)字節(jié), 8*48=384 個(gè)點(diǎn)。
把 24 X 24 漢字,分成左邊從上到下 24行 X 12列, 和右邊 24 X 12 數(shù)據(jù),一行 12bit 數(shù)據(jù)存放在半字 16bit 中的低12bit, 左右半邊都有 24個(gè)"半字",或 48 個(gè)字節(jié),一個(gè)24X24漢字變成96個(gè)字節(jié)了。如此處理字模時(shí),把一個(gè)漢字當(dāng)成兩個(gè) 24 X 12 字母或數(shù)字來(lái)處理。 不管漢字字母或數(shù)字,第n行點(diǎn)的 ”半字?jǐn)?shù)據(jù)“ 就是 n,n+24,n+24*2,n+24*3......取32個(gè)"半字",剛好夠 12bit*32=384 個(gè)點(diǎn),即一行可打 32個(gè)字母,或16個(gè)漢字。
字模寫(xiě)入 SPI FLASH 時(shí),完成以上變換。打印時(shí),NUC123 從 SPI FLASH 讀出的字模,認(rèn)為是上述變換后的格式。
高速 SPI 接口傳輸數(shù)據(jù)
打印時(shí),字模數(shù)據(jù)要從 W25Q16 中通過(guò) SPI 接口讀取,再通過(guò) SPI 接口移入打印頭。
一行 16個(gè) 24 X 24 漢字有 16*96 = 1536 個(gè)字節(jié)。字符行與行之間一般有一到三個(gè)空行,走紙最快時(shí) 90mm/秒,694us 走一行,在這個(gè)時(shí)間內(nèi)要讀取所有 1536個(gè)字節(jié),放入 RAM 打印緩沖區(qū)。代碼中,把 SPI 配置成 28.8Mbps 從FLASH 中讀取字模,為便于用示波器查看波形,每次收發(fā) 16bit 中間,插入一個(gè)空閑 CLK,收發(fā)完 1536 Byte 要經(jīng)過(guò) 1536/2 = 768 次 17bit 時(shí)鐘,時(shí)間為 768*17/28.8 = 453us。關(guān)鍵是 SPI 收發(fā) 16bit 中間不能再有額外間隙,否則 28.8Mbps 失去意義,所以代碼中,使能 SPI 的 FiFo,同時(shí)配置 PDMA 來(lái)完成 SPI 收發(fā)。
點(diǎn)數(shù)據(jù)移入打印頭,SPI 速率配置為 4.8Mbps,384個(gè)點(diǎn)。數(shù)據(jù)傳輸時(shí)間約為 384/4.8 = 80us,走紙最快 90毫米/秒 時(shí) 694us走一行,數(shù)據(jù)早傳完了。走紙速度再快一倍也來(lái)得及。
USB 打印機(jī)模式
USB 打印模式,上位機(jī)傳輸過(guò)來(lái)的,是圖形點(diǎn)陣數(shù)據(jù)與命令混在一起,無(wú)需從 SPI FLASH 中讀字模,只要把點(diǎn)數(shù)據(jù)從USB數(shù)據(jù)流里分離出來(lái),移入打印頭即可。代碼中定義了一個(gè) 4096 字節(jié)的環(huán)形緩沖區(qū)。
USB 數(shù)據(jù)中斷: 分析數(shù)據(jù)流,見(jiàn)函數(shù) PTR_Data_Receive(), 遇圖形點(diǎn)陣數(shù)據(jù)流,寫(xiě)入環(huán)形緩沖區(qū)。遇命令立即執(zhí)行,或?yàn)閳?zhí)行做好準(zhǔn)備。若有打印命令或走紙命令,就把 “走紙行數(shù)” 通過(guò)全局變量 StepIncrease 傳給主循環(huán)代碼。
主循環(huán)里,1>若傳過(guò)來(lái)的走紙行數(shù) StepIncrease 不為0,就啟動(dòng)走紙。2>若已在走紙,就檢查環(huán)形緩沖區(qū)是否有待打印數(shù)據(jù)——比較寫(xiě)入指針與讀出指針的值可得知,若有待打印數(shù)據(jù),就會(huì)在紙每走過(guò)一行時(shí),把數(shù)據(jù)送入打印頭并加熱打印。
走紙,加熱和數(shù)據(jù)傳輸,三者同時(shí)處理的時(shí)序
需要走紙時(shí),只要設(shè)定速度值全局變量 pStepM_TimLimit,然后調(diào)用走紙啟動(dòng)函數(shù) PaperRollStart() 就開(kāi)始走紙了,何時(shí)走下一行,何時(shí)停止,都在 Timer1 中斷代碼里處理。中斷外面無(wú)需再處理走紙的事。
需要說(shuō)明的是:有一個(gè)走紙剩余行數(shù)全局變量 RemainderStep, 在此變量非0時(shí),可以隨時(shí)加大這個(gè)值,加長(zhǎng)走紙行數(shù)。
再來(lái)看何時(shí)把數(shù)據(jù)串入打印頭,何時(shí)加熱,下圖用鼠標(biāo)點(diǎn)擊可放大。
打印開(kāi)始時(shí),先啟動(dòng)走紙,前面空一兩行沒(méi)事,一行只有 0.0625mm。
把第一行點(diǎn)數(shù)據(jù),串入打印頭后,就等待走紙到第三行——由剩余步數(shù)全局變量 RemainderStep 的值可得知。只要一走到第三行,立即輸出點(diǎn)數(shù)據(jù)到加熱頭,并啟動(dòng)加熱定時(shí)。然后就去處理下一行點(diǎn)數(shù)據(jù)。
每次在走到新的一行時(shí)(實(shí)際是兩行), 都立即啟動(dòng)已準(zhǔn)備好的、這一行數(shù)據(jù)的加熱,接著代碼去準(zhǔn)備下一行點(diǎn)數(shù)據(jù)。 何時(shí)加熱停止呢? 不用擔(dān)心,由 Timer2 中斷代碼處理了。
打印開(kāi)始時(shí),必須知道要走幾行, 兩行一個(gè)點(diǎn),一行 16 X 16 字符,要走 32行,一般還要加上開(kāi)頭和結(jié)尾的空行。
連續(xù)打印時(shí),只要剩余行數(shù) RemainderStep 不為0——走紙未停,可以隨時(shí)增加這個(gè)值,加長(zhǎng)走紙行數(shù),繼續(xù)打印后續(xù)數(shù)據(jù)。
由以上分析可知,走紙是獨(dú)立的,想走多快,設(shè)定一個(gè)速度就可以了,走紙的同時(shí),處理打印數(shù)據(jù)。所以,走紙有多快,打印就可以有多快!