📄 p190v20.inc
字号:
;***********************************************************
;程序名称: 打印子程序
;程序开发: 前锋集团技术中心 江海波
;编写时间: 2004年3月24日
;软件环境: 供税控收款机QF560型的上层C语言使用
;硬件环境: EPSON M190G 8针梭式击打式打印机
;MCU: TOSHIBA TMP93CS41@max 16M/1
;程序版本: V3.00
;最后修订时间: 2004年8月28日
;修订部分说明:
;V2.0: 修正了快速进纸在操作上的时序,精简了部分指令
;V3.0: 使用宏代换编写,加入打印机自检程序,供税控机V2.0硬件使用
; 并且增强了程序的健壮性.
; 本程序在P192v30的基础上修改而来,对寄存器和查表算法作了
; 相应的优化,用于打印12y-11x点中文和8y-6x西文字库
;----------------------------------------------------------
;汇编词典:
;列保护计数器动作时间: 超过0.8ms没有检测到列到位脉冲将导致保护动作
;行保护计数器动作时间: 超过120ms没有检测到行到位脉冲将导致保护动作
;__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 打印取点的暂存缓冲区首地址,长度为30Byte
;count_tab 计数器,计30个打印位置
;p_flag 向pszdot送BIT位时的标志寄存器
;dotline 表示当前打印该字的第几行
;count16 行计数器,计数汉字的16个点阵行
;p_error_flag Print error flag打印状态标志,指示打印任务是否正确完成
; 0x55表示正确,0x00表示打印没有执行
; 0x10表示没有检测到"R"信号,0x20表示没有检测到"T"信号
;**********************************************************
;--------------------全局函数声明--------------------------
PUBLIC __searchtab ;---打印查表函数
PUBLIC __printrow ;---打印函数,供C语言使用
PUBLIC __feedpaper ;---快速进纸函数,供C语言使用
PUBLIC __print_test ;---打印机自检函数,供C语言使用
;**********************************************************
;定义伪指令,当软,硬件结构改变时修改本位置上的指令即可完成程序修改
;----------------------------------------------------------
;下层汇编语言与上层C语言之间通过一个名叫"code"的缓冲区传递要打印的数据信息
;这个缓冲区被定义在地址:
code equ 0x100
;该区的长度为31字节,在代码段区,存放要打印的一行文字,中文为GBK码,西文为ASCII码
;----------------------------------------------------------
;打印程序需要一个名叫"pszdot"缓冲区,存放查表得到的点的信息
;这个缓冲区被定义在地址:
pszdot equ 0x120
;该区的长度为30字节
;----------------------------------------------------------
;打印程序需要一个名叫"count_tab"的标志位作为计数器,计30个打印位置
;这个标志位被定义在地址:
count_tab equ 0x140
;----------------------------------------------------------
;打印程序需要一个名叫"dotline"的标志位,指示当前打印的行号
;这个标志位被定义在地址:
dotline equ 0x141
;----------------------------------------------------------
;打印程序需要一个名叫"p_flag"的标志位,在取点时指示取点的BIT位
;这个标志被定义在地址:
p_flag equ 0x142
;----------------------------------------------------------
;打印程序需要一个名叫"count16"的标志寄存器,来计数一个汉字的16个横行,以控制打印
;这个标志被定义在地址:
count16 equ 0x143
;----------------------------------------------------------
;为了方便程序调试和硬件Debug模式下的调试工作,程序安排了一个错误标志
;这个标志被定义在地址:
p_error_flag equ 0x144
;----------------------------------------------------------
;本打印机所使用的字库为中/西文一体的16*16点字库
;这个字库被放置在地址:
zikuadr equ 0x20000
;----------------------------------------------------------
;打印机的驱动针被安排在端口print_port
;打印机的A针在print_port口的高位
print_port equ PA ;---PRINTER solenoid control PORT
;----------------------------------------------------------
;打印机的电源开启控制被放置在端口p_pc_port,BIT p_pc_bit
p_pc_port equ P9 ;---Printer Power Control PORT
p_pc_bit equ 7 ;---Printer Power Control BIT
;----------------------------------------------------------
;打印机的快速进纸控制被放置在端口p_fp_port,BIT p_fp_bit
p_fp_port equ P9 ;---Printer Fast Paper feed PORT
p_fp_bit equ 6 ;---Printer Fast Paper feed BIT
;----------------------------------------------------------
;打印机反馈回的R信号被放置在端口p_rs,BIT p_rs_bit
p_rs equ P9 ;---Printer Reset Signal port
p_rs_bit equ 5 ;---Printer Reser Signal BIT
;----------------------------------------------------------
;打印机反馈回的T信号被放置在端口p_ts,BIT p_ts_bit
p_ts equ P9 ;---Printer Timing Signal port
p_ts_bit equ 2 ;---Printer Timing Signal BIT
;----------------------------------------------------------
;为了保证打印质量,我们在每两行汉字之间插入一个可调整的间隙,现在这个间隙为
space_line equ 0x01 ;---space between two characters
;----------------------------------------------------------
;为了保证程序不发生冲突,我们在每次调用打印函数时,对端口做了重新初始化,这个
;初始化需要进行端口定义:
;(1)打印机的驱动针被安排在端口print_port的方向字为
p_p_dir equ PACR ;---Printer solenoid Port direction register
;(2)打印机的控制信号的端口进进行初始化,我们定义了该口的初始化函数为
p_s_port_init: ;---Printer Signal PORT INITialization
ld (P9FC),0x09 ;P9FC
ld (P9CR),0xC9 ;P9CR
ret
;----------------------------------------------------------
;通用寄存器分配功能分配:
;w,a:临时变量,xwa可作临时指针
;*****************打印程序专用延迟函数*********************
p_delay: ;信号检验去噪声用延迟函数
ld b,0x1E ;0x1E=30,延迟0.1mS
p_d_loop: ;---Printer Delay LOOP
nop
nop
nop
nop
nop
nop
nop
nop
nop
djnz b,p_d_loop
ret
f_f_delay: ;快速进纸机开启时间控制延迟函数
ld b,0xFD ;0xFD=253延迟2.88mS
f_f_d_loop: ;---Fast Feed Delay LOOP
ldcf 7,(print_port) ;由于ldcf指令的执行时间长,这里用来
ldcf 7,(print_port) ;代替nop指令作延迟用,并没有实际意义
ldcf 7,(print_port)
ldcf 7,(print_port)
ldcf 7,(print_port)
ldcf 7,(print_port)
ldcf 7,(print_port)
ldcf 7,(print_port)
ldcf 7,(print_port)
ldcf 7,(print_port)
djnz b,f_f_d_loop
ret
;******************点阵查表函数 by JHBCD*******************
;****本函数由打印函数调用,用于查出要打印的下一行144个点****
__searchtab:
ld (p_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,(p_flag)
cpl d
and (xhl),d ;清0
jr incr111
evalu111:
ld d,(p_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,(p_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 (p_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,(p_flag)
cpl d
and (xhl),d ;清0
jr incr1x
evalu1x:
ld d,(p_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 (p_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,(p_flag)
cpl d
and (xhl),d ;清0
jr incr1
evalu1:
ld d,(p_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 (p_flag) ;取下一个针;phh
one_zi:
djnz w,judje
ld d,(p_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个字节的点阵信息
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -