⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p190v20.asm

📁 本程序为M190微型打印机的程序,采用C语言和汇编混合编写,已经经过调试并在应用中
💻 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 + -