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

📄 prn_drv.c

📁 一款收款机C源代码!因为是几年前的代码了
💻 C
📖 第 1 页 / 共 2 页
字号:
/*----------------------------------------------------------
*	Printer Driver program
*---------------------------------------------------------*/
#include 	"ecrsys.h"
#include 	"ftype.h"
#include	"data.h"
#include "sysdata.h"
#include	<string.h>

void CvtBmp(void);
void CalcuDotNum(void);
WORD	th_temp_get(void);
void Prn_Step_Feed(void);
void Send_Dot_DMA_Buff(byte flag);
void CvtBmpCompress(const byte *src);
void CvtBmpNormal(const byte *src);


#define		MAX_HEAT_DOT_CNTR	128
//#define		MAX_HEAT_DOT_CNTR	384


volatile	static		CHR	*prn_curr_dot_ptr, Prn_Step_Base;
volatile	static		WORD		Ta2_Intvl;
volatile	CHR               Prn_Stat;
#define		DOT_DOUBLE_BASE			(byte *)(0xfc0000 + 0x38000 + 48 * 256)




const byte zeroData[MAX_CNTR_PRN_HEAD] = {
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
	};

#define		HEAT_1000  1000 * FOSC / 8
#define		HEAT_800	800 * FOSC / 8
#define		HEAT_750	750 * FOSC / 8
#define		HEAT_700	700 * FOSC / 8
#define		HEAT_600	600 * FOSC / 8
#define		HEAT_500	500 * FOSC / 8
#define		HEAT_300	300 * FOSC / 8

long dmaDataAddr;

byte bkDotRing[49][55];
byte tmpDotBuffer[49][55];
byte bkphead = 0;

#define		PAPER_END_ERR		1




const word feedTime[] = {
//	1500, 1400, 1300, 1200, 1000, 800, 800, 800, 800, 800, 800, 800,
//	800, 800, 800, 800, 800, 800, 800, 1000, 1200, 1300, 1400, 1500,
	1500, 1200, 1000, 850, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 850, 1000, 1200, 1500,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
	800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800
};

/*	Wait printer buffer empty and printer stop to IDLE mode		*/
void wait_prn_Stop(void)
{
	DEBUG_PRN(return;)
	while(1)
	{
		prn_Chk();
		if( (phead == prear) && ( Prn_Stat == PRN_IDLE))
			break;
	}
}

/*****************************************************************************************
*	Printer paper end,
*	Only allow user depress the FEED key and Clear key.
*
*	Feed 	--- > For feed paper.
*	Clear 	--- > For relese the paper end error.
*****************************************************************************************/
void	prn_papr_end(void)
{
	word	key;

	prn_flag.papr_end = TRUE;
	Clr_Period();
	Disp_Spec_Period();
	dis_sto_last_disp();
	Clr_All_Dsp_Data(FALSE);
	disp_Char_Str(Disp_Papr_Out,0);
	bellcnt = 0xfe;
	while( 1 )
	{
		if ( Key_Poll_Chk() )
		{
			key = GetKey( );
			if ( key == KD_FEED )						//Feed 1 character line.
			{
				disint();
				Prn_Stat = PRN_FEED;
				Ttl_Fd_line = NM_FEED_PAPER;
				PrnVccOn();
				VPR_ON();
				enint();
			}
			else if ( key == KD_CLEAR )				//Release the paper end error.
			{
				if ( PRN_PEND == 0 )
				{
					Clr_Dsp_Data();
					Insert_Num(0, 8);
//					Comm_Disp();
//					// add print last line before paper end
//					if (Prn_Last_Line_Paper_End() == PAPER_END_ERR)
//					{
//						Clr_Dsp_Data();
//						disp_Char_Str("PAPR OUT ---",0);
//						bellcnt = 0xfe;
//						continue;
//					}
					prn_flag.papr_end = FALSE;
					break;
				}
			}
		}
		if ( prn_flag.prn_break == 1 )								//Printer open flag.
		{
//			Fm_Events_Prn_Disc();
//			Sys_Halt(ERR_PRN_DSCNT);
		}
	}

	en_sto_last_disp();
	Lcm_Disp_Last_Line(LCM_LINE_2);
}
/*****************************************************************************************
*	For safely use the printer, we have to check the following:
*	1. Check the Paper end sensor,
*	2. Check the Temprature of the printer.
*	3. Check whethre the printer is connected, if not, then must do the printer disconnection.
*		02-11-17 16:49	By ZhengXiaoChun
*	Note:	This routine should be called when do the printer dot converting proces.
******************************************************************************************/
void prn_Chk( void )
{
	CHR i ;

	DEBUG_PRN(
		return;
	);
	if ( prn_flag.prn_break == 1 )						//Printer open flag.
	{
//		Fm_Events_Prn_Disc();
//		Sys_Halt(ERR_PRN_DSCNT);
	}
//	if ( ( PRN_PEND == 1 ) && ( prear != phead ))
	if (  PRN_PEND == 1 )
		prn_papr_end();
}

/******************************************************************************
* Describe:	convert Normal string to dot-matrix buffer
* Input :	void
* Output:	void
* return:	void
******************************************************************************/
const 	byte kValue[33] = {0, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29,
							31, 32, 34, 35, 37, 38, 40, 41, 43, 44, 46, 47, 49, 50, 52, 53 };

/******************************************************************************
* Describe:	calculate dot num per dot line, and separate there into 6 part.
* Input :	void
* Output:	void
* return:	void
******************************************************************************/
void CalcuDotNum(void)
{
	byte i, j, k, idx, dotNum, dataCnt;
	byte tmpDotNum;
	byte *ptr;

	for (i=0,idx=phead; i<24; i++,idx++)
	{
		Prn_Dot_Ring[idx][0] = NM_DOT_FD_CNTR;
	}
	return;

	// calculate need send times and data length every dot line
	for ( i=0,idx=phead; i<24; i++,idx++ )
	{
		ptr = Prn_Dot_Ring[idx];
		*ptr = NM_DOT_FD_CNTR;		// two step is one dot line
		// calculate (dot sum < 64)'s data length
		dotNum = 0;
		k = 1;
		dataCnt = 0;
		ptr += 7;
		for (j=7; j<55; j++)
		{
			tmpDotNum = dotNum;
			dotNum += DotNumArray[*ptr++];
			dataCnt++;								// data lenth

			if (dotNum >= MAX_HEAT_DOT_CNTR )
			{
				if (dotNum == MAX_HEAT_DOT_CNTR  )
				{
					dotNum = 0;
					Prn_Dot_Ring[idx][k] = dataCnt;
					dataCnt = 0;
				}
				else
				{
					dotNum -= tmpDotNum;
					Prn_Dot_Ring[idx][k] = dataCnt - 1;
					dataCnt = 1;
				}
				k++;
			}
		}
//		if ((dataCnt != 0) && (dotNum != 0))
		if (dataCnt != 0)
		{
			Prn_Dot_Ring[idx][k] = dataCnt;
			k++;
		}
		for ( ; k<7; k++)
		{
			Prn_Dot_Ring[idx][k] = 0;
		}
	}
}

#define 	HEAT_TM		800

volatile	static		CHR	*prn_curr_dot_ptr, Prn_Step_Base;
CHR		Total_Dot_Cntr = 0;
CHR 	Heat_Cntr = 0;
/******************************************************************************
* Describe:	Interrupt for timer A2 used for the heating processing.(TIME A2 ISR )
* Input :	void
* Output:	void
* return:	void
******************************************************************************/
void HeatTimer( void )
{
	if (Prn_Stat == PRN_HEAT)
	{
		Prn_Stat = PRN_FEED;
		ta4s = 0;
		ta4 = 10;
		ta4s = 1;

		STB1 = STB2 = 1;		// Off all STB segment.
	}
	ta2s = 0;									// Disable the Timer A2.
}

/******************************************************************************
* Describe:	Timer A4 (paper feed Timer) ISR
* Input :	void
* Output:	void
* return:	void
******************************************************************************/
extern byte pause_Prn;
extern byte currCloseFlag;
extern byte prnThPause;

byte feedStep = 0;
word feedTime1 = 3000 * FOSC / 8;
word feedTime2 = 1000 * FOSC / 8;
byte volatile feedFlag = 0;
byte volatile sendDataFlag = 0;

#define		STEP_TIME			700

void PaperFeedTimer(void)
{
	byte tmp;
	static byte feedCnt = 0;
	word time;

	ta4s = 0;
	ta4 = STEP_TIME * FOSC / 8;
	ta4s = 1;
	ir_ta4ic = 0;								// 防止由于中断响应延迟,两次步进时间间隔太短.

	if (prnThPause)
	{
		STB1 = STB2 = 1;						// Off all STB segment.
		STEP_OFF();
		return;
	}

	if (pause_Prn)								// succesive print time exceed 30s, need cool 5 ~ 10 s
	{
		STB1 = STB2 = 1;						// Off all STB segment.
		currCloseFlag = 0;
		STEP_OFF();
		return;
	}

	if (Prn_Stat == PRN_PROTECT)				// 过热保护,暂停加热,直至温度降低.
	{
		if (th_temp_get() != NG)
		{
			Prn_Stat = PRN_HEAT;
		}
	}

	if (Prn_Stat == PRN_HEAT)					// heat timer function
	{
		Prn_Stat = PRN_FEED;
		STB1 = STB2 = 1;							// Off all STB segment.
	}

	if (Prn_Stat == PRN_FEED)
	{
		if (Ttl_Fd_line == 0)					// All feed line finish.
		{
			feedFlag = 0;
			sendDataFlag = 0;
			Prn_Stat = PRN_IDLE;
			VPR_OFF();
			PrnVccOff();
		}
		else if (Ttl_Fd_line == 1)
		{
			Prn_Step_Feed();
			Ttl_Fd_line --;
			if (phead != prear)					// schdule
			{
				prn_curr_dot_ptr = (CHR*)&Prn_Dot_Ring[prear][0];
				Ttl_Fd_line = *prn_curr_dot_ptr ++;

				if (Ttl_Fd_line == NM_DOT_FD_CNTR)	// Normal data printing.
				{
					sendDataFlag = 1;
					Send_Dot_DMA_Buff(1);		// Start the dot sending.
				}
				else
				{
					sendDataFlag = 0;
					if (Ttl_Fd_line != NM_CHA_SP_CNTR)	// 非字符行间隔.
					{
						feedFlag = 1;
					}
					Send_Dot_DMA_Buff(3);
				}
				prear++;
			}
		}
		else if (Ttl_Fd_line == 2)
		{
			Ttl_Fd_line --;
			if (sendDataFlag == 1)				// send data & heat
			{
				Send_Dot_DMA_Buff(2);			// Start the dot sending.
			}
			else
			{
				Send_Dot_DMA_Buff(3);
			}
			Prn_Step_Feed();
		}
		else
		{
			Ttl_Fd_line --;
			Send_Dot_DMA_Buff(3);
			Prn_Step_Feed();
		}
		feedCnt = 0;
		currCloseFlag = 1;
	}
	else if (feedCnt < 10)						// only for continued print protect
	{
		STEP_OFF();
		feedCnt++;
	}
	else
	{
		STEP_OFF();
		currCloseFlag = 0;
	}

	if ((Prn_Stat == PRN_IDLE) && (phead != prear))
	{
		prn_schedule();
	}
}

/******************************************************************************
* Describe:
* Input :	void
* Output:	void
* return:	void
******************************************************************************/
void Prn_Step_Feed(void)
{
	// WD2-KR主板与WD1主板,两个驱动端口顺序相反.
	const byte cw_data[4] = {0x00, 0x10, 0x18, 0x08};

	prn_step ++;
	if (prn_step >= 4)
		prn_step = 0;

	// On motor & set phase
	STEP_ON();
	g_Cs_Drive &= 0xE7;
	g_Cs_Drive |= cw_data[prn_step];
	CS_DRIVE = g_Cs_Drive;

	if ((sysflag->fl_wmotor) && (sysflag->set_timmer != 0))
	{
		WMTOR = 1;
		wmtor_timmer = sysflag->set_timmer;
	}
}

void prn_schedule(void)
{
	if ((phead != prear) && (Prn_Stat == PRN_IDLE))	// Exist data need print.
	{
//		if (prn_flag.prn_break || prn_flag.temp_high || prn_flag.papr_end)
//		{
//			return;
//		}
		if ((prn_flag.papr_end) || (PRN_TH == 1))
		{
			return;
		}

		PrnVccOn();
		VPR_ON();

		prn_curr_dot_ptr = (CHR*)&Prn_Dot_Ring[prear][0];
		Ttl_Fd_line = *prn_curr_dot_ptr ++;

		if ((Ttl_Fd_line == NM_DOT_FD_CNTR))	// Normal data printing.
		{
			sendDataFlag = 1;
			Send_Dot_DMA_Buff(1);				// Start the dot sending.
		}
		else
		{
//			if (Ttl_Fd_line == NM_CHA_SP_CNTR)
			{
				Prn_Stat = PRN_FEED;
				Prn_Step_Feed();				// Feed 1-step.
				Ttl_Fd_line--;
				sendDataFlag = 0;
				if (Ttl_Fd_line != NM_CHA_SP_CNTR)
				{
					feedFlag = 1;
				}
			}
		}
		prear ++;
	}
}

/******************************************************************************
* Describe:Send the Dot to DMA buffer accoring to the buffer information.
* Input :	void
* Output:	void
* return:	void
******************************************************************************/
void Send_Dot_DMA_Buff(byte flag)
{
	if (flag == 1)
	{
		dmaDataAddr = (long)&prn_curr_dot_ptr[7];
		dmaTranLen = 47;
#pragma ASM
		ldc _dmaDataAddr, dma0
		ldc _dmaTranLen, dct0
#pragma ENDASM
		u4tb = prn_curr_dot_ptr[6];				// start sending.

		Prn_Stat = PRN_SEND;
	}
	else if (flag == 2)
	{
		STB2 = 0;
		Prn_Latch = 0;
		Prn_Stat = PRN_HEAT;
		Prn_Latch = 1;

		Ta2_Intvl = th_temp_get();
		if (Ta2_Intvl == NG)
		{
			Prn_Stat = PRN_PROTECT;				// 过热保护.
			STB2 = 1;
			return;
		}
		ta4s = 0;
//		ta4 = 500 * FOSC / 8;
		ta4 = Ta2_Intvl;
		ta4s = 1;								// Start timer A2
	}
	else
	{
//		if (feedFlag == 1)						// User Feed Operation
//		{
//			ta4s = 0;
//			ta4 = feedTime[Ttl_Fd_line] * FOSC / 8;
////			ta4 = 800 * FOSC / 8;
//			ta4s = 1;
//		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -