📄 p190v20.asm
字号:
;***********************************************************
;程序名称: 打印子程序
;程序开发: 前锋集团技术中心 江海波
;编写时间: 2004年3月24日
;软件环境: 供税控收款机QF560型的上层C语言使用
;硬件环境: EPSON M190G 8针梭式击打式打印机
;MCU: TOSHIBA TMP93CS41@max 16M/1
;程序版本: V2.00
;最后修订时间: 2004年5月2日
;修订部分说明:
;V2.0: 修正了快速进纸在操作上的时序,精简了部分指令
;----------------------------------------------------------
;汇编词典:
;列保护计数器动作时间: 超过0.8ms没有检测到列到位脉冲将导致保护动作
;行保护计数器动作时间: 超过100ms没有检测到行到位脉冲将导致保护动作
;__searchtab: 查表函数,用于查出当前所需要的一行点
;__printrow: C语言调用汇编打印函数的入口
;__feedPAper: 快速进纸,由C调用
;c_*: 与中文前半个字节查表有关的段标
;ch_*: 与中文后半个字节查表有关的段标
;nex: next的简写
;e_*: 与西文查表有关的段标
;p_reload: 行重新装载,准备下一个要打印的行的点阵,即pszdot缓冲区
;s*_wait*: 第*组针,等待信号*,其中信号0为等待"0",1为等待"1",11为等待第二个1
;p_delay: Printer delay信号检验去噪声用延迟函数
;ff_delay: Fast paper Feed delay快速进纸机开启时间控制延迟函数
;----------------------------------------------------------
;需要的变量定义:
;code 代码段区首地址,存放要打印的一行文字,中文为GBK码,西文为ASCII码
;pszdot 打印取点的暂存缓冲区首地址
;count_tab 计数器,计30个打印位置
;flag 向pszdot送BIT位时的标志寄存器
;dotline 表示当前打印该字的第几行
;count11 行计数器,计数汉字的11个点阵行
;p_error_flag Print error flag打印状态标志,指示打印任务是否正确完成0x55表示正确,0x00表示出错
PUBLIC __searchtab
PUBLIC __printrow
PUBLIC __feedpaper
PUBLIC __delay
;*****************打印程序专用延迟函数*********************
p_delay: ;信号检验去噪声用延迟函数
ld b,0x1E ;0x1E=30,延迟0.1mS
p_delay1:
nop
nop
nop
nop
nop
nop
nop
nop
nop
djnz b,p_delay1
ret
ff_delay: ;快速进纸机开启时间控制延迟函数
ld b,0xFD ;0xFD=253延迟2.88mS
ff_delay1:
ldcf 7,(P8) ;由于ldcf指令的执行时间长,这里用来
ldcf 7,(P8) ;代替nop指令作延迟用,并没有实际意义
ldcf 7,(P8)
ldcf 7,(P8)
ldcf 7,(P8)
ldcf 7,(P8)
ldcf 7,(P8)
ldcf 7,(P8)
ldcf 7,(P8)
ldcf 7,(P8)
djnz b,ff_delay1
ret
__searchtab:
ld (flag),0x80
ld (count_tab),18
ld xhl,pszdot
ld xix,code
get_code:
ld w,(xix)
cp w,0
jp nz,chin_foreign
ret ;取完,结束
;***************判断中文还是西文*****************
chin_foreign:
ld w,(xix) ;没取完,继续取下一个区位码
and w,0x80
jr nz,chinese
;**************西文,进行如下处理**************
xiwen: ;确定起始位置
ld xbc,0
ld c,(xix) ;if(nPos1 >= 139) break;//nPos1:当前字符的点阵信息存放在nDot中的位置,以int为单位计数
sub xbc,32 ;j = pszRow[szPos]; //szPos:当前打印字符在pszRow中的位置
mul xbc,6 ;nPos = (j - 32)*6; //nPos: 当前打印字符的点阵在常数表中的起始位置
add xbc,zikuadr ;查到的起始位置放入XBC寄存器
cp (dotline),4
jr c,arithmetic_00 ;dotline<=3,采用数字或英文前3行的算法
call arithmetic_1 ;dotline>3,采用数字或英文后8行的算法
jp arithmetic_comm
;if(!(pszRow[szPos] & 0x80))//西文
chinese:
;确定起始位置
ld xwa,0
ld xbc,0
ld a,(xix) ;if(nPos1 >= 133) break;
sub xwa,0xa0
sub xwa,16
mul xwa,94
inc 1,xix
ld c,(xix)
sub xbc,0xa0
sub xbc,1
add xbc,xwa
mul xbc,15
add xbc,zikuadr
add xbc,0x6AE
cp (dotline),9
jr c,arithmetic_88 ;dotline<=8,采用汉字前8行的算法
jr z,arithmetic_99 ;dotline=9,采用汉字第9行的算法
cp (dotline),10
jr z,arithmetic_100 ;dotline=10,采用汉字第10行的算法
call arithmetic_11 ;dotline=11,采用汉字第11行的算法
jr arithmetic_comm
arithmetic_00:
call arithmetic_0
jr arithmetic_comm
arithmetic_88:
call arithmetic_8
jr arithmetic_comm
arithmetic_99:
call arithmetic_9
jr arithmetic_comm
arithmetic_100:
call arithmetic_10
arithmetic_comm:
inc 1,xix
jp get_code
;*********与查表有关的子程序***************
judje_1or_0:
jr c,evalu111
ld d,(flag)
cpl d
and (xhl),d ;清0
jr incr111
evalu111:
ld d,(flag)
or (xhl),d ;置1
incr111:
inc 1,xhl
dec 1,(count_tab)
jp z,renew
ret
tab_741:
ld e,(xbc)
rlc 1,e
call judje_1or_0
rlc 3,e
call judje_1or_0
rlc 3,e
call judje_1or_0
ret
tab_630:
ld e,(xbc)
rlc 2,e
call judje_1or_0
rlc 3,e
call judje_1or_0
rlc 3,e
call judje_1or_0
ret
tab_52:
ld e,(xbc)
rlc 3,e
call judje_1or_0
rlc 3,e
call judje_1or_0
ret
;********数字或英文前3行的算法:全清0*****************
arithmetic_0:
ld w,6
move_6:
ld d,(flag)
cpl d
and (xhl),d ;清0
inc 1,xhl
dec 1,(count_tab)
jr nz,one_x
ld (count_tab),18 ;一个针给完,重心给值
ld xhl,pszdot ;pszdot首地址给xhl
rrc (flag) ;取下一个针;phh
one_x:
djnz w,move_6
ret
;********数字或英文后8行的算法:取每个字节的第11-dotline位移入pszdot
arithmetic_1:
ld w,6 ;英文移6次
ld a,(dotline)
sub a,3
judjex:
ld d,(xbc) ;取点阵字节
rlc a,d
jr c,evalu1x
ld d,(flag)
cpl d
and (xhl),d ;清0
jr incr1x
evalu1x:
ld d,(flag)
or (xhl),d ;置1
incr1x:
inc 1,xbc
inc 1,xhl
dec 1,(count_tab)
jr nz,one_zix
ld (count_tab),18 ;一个针给完,重心给值
ld xhl,pszdot ;pszdot首地址给xhl
rrc (flag) ;取下一个针;phh
one_zix:
djnz w,judjex
ret
;*******汉字前8行的算法:取前11个字节的第8-dotline位移入pszdot,接着的一位清0
arithmetic_8:
;ld xiy,0x100
ld w,11 ;中文移11次
ld a,(dotline)
judje:
ld d,(xbc) ;取点阵字节
rlc a,d
jr c,evalu1
ld d,(flag)
cpl d
and (xhl),d ;清0
jr incr1
evalu1:
ld d,(flag)
or (xhl),d ;置1
incr1:
inc 1,xbc
;inc 1,xiy
inc 1,xhl
dec 1,(count_tab)
jr nz,one_zi
ld (count_tab),18 ;一个针给完,重心给值
ld xhl,pszdot ;pszdot首地址给xhl
rrc (flag) ;取下一个针;phh
one_zi:
djnz w,judje
ld d,(flag) ;11位完成后,第12位清0
cpl d
and (xhl),d
inc 1,xhl
dec 1,(count_tab)
jp z,renew
ret
;***********汉字第9行的算法**********
arithmetic_9:
add xbc,11 ;取第12个字节的点阵信息
call tab_741
inc 1,xbc ;取第13个字节的点阵信息
call tab_630
inc 1,xbc ;取第14个字节的点阵信息
call tab_52
inc 1,xbc ;取第15个字节的点阵信息
call tab_741
ld d,(flag) ;11位完成后,第12位清0
cpl d
and (xhl),d
inc 1,xhl
dec 1,(count_tab)
jr z,renew
ret
;***********汉字第10行的算法**********
arithmetic_10:
add xbc,11 ;取第12个字节的点阵信息
call tab_630
inc 1,xbc ;取第13个字节的点阵信息
call tab_52
inc 1,xbc ;取第14个字节的点阵信息
call tab_741
inc 1,xbc ;取第15个字节的点阵信息
call tab_630
ld d,(flag) ;11位完成后,第12位清0
cpl d
and (xhl),d
inc 1,xhl
dec 1,(count_tab)
jr z,renew
ret
;***********汉字第11行的算法**********
arithmetic_11:
add xbc,11 ;取第12个字节的点阵信息
call tab_52
inc 1,xbc ;取第13个字节的点阵信息
call tab_741
inc 1,xbc ;取第14个字节的点阵信息
call tab_630
inc 1,xbc ;取第15个字节的点阵信息
call tab_52
ld d,(flag) ;10位完成后,第11位清0
cpl d
and (xhl),d
inc 1,xhl
dec 1,(count_tab)
jr nz,next_f
ld (count_tab),18
ld xhl,pszdot
rrc (flag) ;取下一个针;phh
next_f:
ld d,(flag) ;11位完成后,第12位清0
cpl d
and (xhl),d
inc 1,xhl
dec 1,(count_tab)
jr z,renew
ret
renew:
ld (count_tab),18
ld xhl,pszdot
rrc (flag) ;取下一个针;phh
ret
;**************对18个打印位置的控制程序 by JHBCD***********
__printrow:
ld (p_error_flag),0x00 ;打印状态标志,默认为出错状态
ld (count11),11
ld (dotline),1
ld (pa),0x00
ld b,0x12 ;0x1E=30,0x12=18
p_init: ;初始化pszdot区清零
ld xhl,pszdot
ld (xhl+),0x00
djnz b,p_init
; ld (P8),0xd7 ;开钱箱,要用的时候再开本语句
ld (P8FC),0
ld (P8CR),0x0e ;p80.P84口设为输入
and (mada),0x3d ;将p96,p91清0
or (mada),0x82 ;驱动马达
p_reload:
call __searchtab
ld d,18;
ld xhl,pszdot
ld iy,0x87DE ;装载行保护计数器,保护时间100ms
;******************等待一个行到位信号**********************
ph_wait0:
ldcf 4,(P8)
jp nc,ph_wait1
djnz iy,ph_wait0
jp printer_off
ph_wait1:
ldcf 4,(P8)
jp c,ph_delay
djnz iy,ph_wait1
jp printer_off
ph_delay:
call p_delay
ph_wait11:
ldcf 4,(P8)
jp c,solen1
djnz iy,ph_wait11
jp printer_off
;*************************第一组针*************************
solen1:
ld e,(xhl)
and e,0x92 ;取出第一组针的数据
ld wa,0xED ;装载列保护计数器原始程序将该值赋0x2fd0
s1_wait0:
ldcf 7,(P8)
jp nc,s1_wait1
djnz wa,s1_wait0
jp printer_off
s1_wait1:
ldcf 7,(P8)
jp c,s1_delay
djnz wa,s1_wait1
jp printer_off
s1_delay:
call p_delay
s1_wait11:
ldcf 7,(P8)
jp c,s1_print
djnz wa,s1_wait11
jp printer_off
s1_print:
ld (pa),e ;送出第一组针的端口打印信号
;**************************第二组针************************
solen2:
ld e,(xhl)
and e,0x49 ;取出第二组针的数据
ld wa,0xED ;装载列保护计数器
s2_wait0:
ldcf 7,(P8)
jp nc,s2_wait1
djnz wa,s2_wait0
jp printer_off
s2_wait1:
ldcf 7,(P8)
jp c,s2_delay
djnz wa,s2_wait1
jp printer_off
s2_delay:
call p_delay
s2_wait11:
ldcf 7,(P8)
jp c,s2_print
djnz wa,s2_wait11
jp printer_off
s2_print:
ld (pa),e ;送出第二组针的端口打印信号
;***********************第三组针***************************
solen3:
ld e,(xhl)
and e,0x24 ;取出第三组针的数据
ld wa,0xED ;装载列保护计数器
s3_wait0:
ldcf 7,(P8)
jp nc,s3_wait1
djnz wa,s3_wait0
jp printer_off
s3_wait1:
ldcf 7,(P8)
jp c,s3_delay
djnz wa,s3_wait1
jp printer_off
s3_delay:
call p_delay
s3_wait11:
ldcf 7,(P8)
jp c,s3_print
djnz wa,s3_wait11
jp printer_off
s3_print:
ld (pa),e ;送出第三组针的打印信号
s_next: ;下一个打印位置
inc 1,xhl ;换数据指针位置
dec 1,d ;18个位置还没有打印完成
jp nz,solen1
;****************在回车前,将第三组打印针收回**************
s_off:
ld wa,0xED ;装载列保护计数器
off_wait0:
ldcf 7,(P8)
jp nc,off_wait1
djnz wa,off_wait0
jp printer_off
off_wait1:
ldcf 7,(P8)
jp c,off_delay
djnz wa,off_wait1
jp printer_off
off_delay:
call p_delay
off_wait11:
ldcf 7,(P8)
jp c,off_print
djnz wa,off_wait11
jp printer_off
off_print:
ld (pa),0x00 ;关断打印信号,开始回车过程
line_fini: ;1行的18个位置打印完成,这个时候字车正在回车途中
inc 1,(dotline)
dec 1,(count11) ;判断汉字的11行是否完成
jp nz,p_reload
;*为了保证打印质量,我们在每两行汉字之间插入一个可调整的间隙
space:
ld a,1 ;调整a,可以调整两行汉字之间的间距
sp_reload:
ld iy,0x87DE
sp_wait0:
ldcf 4,(P8)
jp nc,sp_wait1
djnz iy,sp_wait0
jp printer_off
sp_wait1:
ldcf 4,(P8)
jp c,sp_delay
djnz iy,sp_wait1
jp printer_off
sp_delay:
call p_delay
sp_wait11:
ldcf 4,(P8)
jp c,sp_next
djnz iy,sp_wait11
jp printer_off
sp_next:
djnz a,f_reload
p_fini: ;本次打印任务完成
ld (pa),0x00
and (mada),0x3D ;0x3D=0B00111101关电源,关快速进纸机
ld (p_error_flag),0x55 ;打印状态标志,顺利完成了打印任务
ret ;打印程序完成的返回点
;****************进纸一个点阵行 by JHBCD*******************
__feedpaper:
ld (p_error_flag),0x00 ;打印状态标志,默认为出错状态
ld (P8FC),0
ld (P8CR),0x0E ;p80.P84口设为输入
ld d,(code)
or (P9),0x02 ;0x02=0B00000010驱动马达
f_reload:
ld iy,0x87DE
f_wait0:
ldcf 4,(P8)
jp nc,f_wait1
djnz iy,f_wait0
jp printer_off
f_wait1:
ldcf 4,(P8)
jp c,f_delay
djnz iy,f_wait1
jp printer_off
f_delay:
call p_delay
f_wait11:
ldcf 4,(P8)
jp c,f_next
djnz iy,f_wait11
jp printer_off
f_next:
or (P9),0x40 ;0x40=0B01000000开快速进纸机
call ff_delay ;调用快速进纸延迟函数
and (P9),0x3F ;0x3F=0B00111111关快速进纸机
djnz d,f_reload
ld (p_error_flag),0x55 ;打印状态标志,顺利完成了打印任务
printer_off: ;打印完成后的工作
ld (PA),0x00
and (P9),0x3D ;0x3D=0B00111101关电源,关快速进纸机
ret ;打印程序完成的返回点
;**********************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -