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

📄 vfd.c

📁 一款收款机C源代码!因为是几年前的代码了
💻 C
字号:
///////////////////////////////////////////////////////////////////////////////
// 										vfd.c
//
// Copyright (c) 2004, WeiHua Technology Co., Ltd.
// All rights reserved.
//
// Created by:		Chen Huahai		2004-08-23
//
// Desription: 
//		VFD显示,是通过串行接口经串并转换电路后驱动显示的,三芯片共24端口输出,其中20端口有效输出.
//		Input ==> {A,B,C,D,E,F,G,H} - {A,B,C,D,E,F,G,H} - {A,B,C,D,E,F,G,H}
//					 {G10, G9, ...    G2, G1} - {P10, P9, ... P2, P1} - {invalid}
//							位驱动								段驱动
//		低电平驱动.
///////////////////////////////////////////////////////////////////////////////
#include "ecrsys.h"
#include "vfd.h"
#include <string.h>

#ifdef OLD_VFD
#define	VFD_DRV_IO				1
#define	VFD_DRV_SERIAL			2


volatile byte		vfddisBuf[VFD_BIT_NUM][3];
volatile byte 		vfd_tmp_buf[3];
volatile byte 	VFD_Buff[VFD_BIT_NUM];			// The VFD buffer, store the last display data
//byte		vfd_lcd_Disp;						// VFD or LCD display
byte		vfd_drv_mode;						// VFD driver mode : IO / Serial
volatile byte	bk_vfddisBuf[VFD_BIT_NUM][3];		// 正常程序的显示备份,用于打印机异常期间保存原显示.
byte	bk_main_vfddisBuf[VFD_BIT_NUM][3];	// 正常程序的显示备份,用于主程序保存及恢复显示.

byte const vfdBitBuf[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
const byte disbuf[] = {
		0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, // "0123456789"
		VFD_CHAR_SPACE, // ' '
		VFD_CHAR_MINUS,	// '-'
		VFD_CHAR_A, VFD_CHAR_b, VFD_CHAR_C, VFD_CHAR_d, VFD_CHAR_E,
		VFD_CHAR_F, VFD_CHAR_G, VFD_CHAR_H, VFD_CHAR_I, VFD_CHAR_J,
		VFD_CHAR_SPACE, VFD_CHAR_L, VFD_CHAR_SPACE, VFD_CHAR_n, VFD_CHAR_O,
		VFD_CHAR_P, VFD_CHAR_SPACE, VFD_CHAR_R, VFD_CHAR_S, VFD_CHAR_t,
		VFD_CHAR_U, VFD_CHAR_SPACE, VFD_CHAR_SPACE, VFD_CHAR_SPACE, 
		VFD_CHAR_y, VFD_CHAR_Z 
	};
const byte posCvt[] = {8,9,0,1,2,3,4,5,6,7};

///////////////////////////////////////////////////////////////////////////////
//									VFD特殊符号(逗号及下划线)显示驱动.
///////////////////////////////////////////////////////////////////////////////
volatile byte vfdCommaAndUnderline[VFD_BIT_NUM];

#define		VFD_COMMA_DIS			(0x01 << 4)
#define		VFD_COMMA_EN			(~(0x01 << 4))
#define		VFD_UNDERLINE_DIS		(0x01 << 5)
#define		VFD_UNDERLINE_EN		(~(0x01 << 5))

// private function
void DispComma(byte pos);
void ClrDispComma(byte pos);
void ClsDispComma(void);
void DispUnderline(byte pos);
void ClrDispUnderline(byte pos);
void ClsDispUnderline(void);
void disint(void);
void enint(void);

static bool m_VfdOn = true;
void Vfd_On(void)
{
	m_VfdOn = true;
}

void Vfd_Off(void)
{
	m_VfdOn = false;
}

#define	IsVfdOn()	(m_VfdOn)

///////////////////////////////////////////////////////////////////////////////
// Description:Insert period to VFD
// In Param:	pos
// Out Param:	void
// Return:		void
///////////////////////////////////////////////////////////////////////////////
void Vfd_InsPeriod(byte pos)
{
    Vfd_DispChar(pos, VFD_Buff[pos], 1);
}

///////////////////////////////////////////////////////////////////////////////
// Description: Clear period
// In Param:	pos
// Out Param:	void
// Return:		void
///////////////////////////////////////////////////////////////////////////////
void Vfd_ClrPeriod(byte pos)
{
   	Vfd_DispChar(pos, VFD_Buff[pos], 0);
}

///////////////////////////////////////////////////////////////////////////////
// Description: drive VFD via Serial
// In Param:	void
// Out Param:	void
// Return:		void
// Description:	FOSC == 11M, u2brg = 3, 本函数执行时间为45us(示波器查看).
///////////////////////////////////////////////////////////////////////////////
void Vfd_WriteStr_Serial(void)
{
	// 先关闭VFD显示.
	u2tb = 0xff;
	while (!ti_u2c1);
	u2tb = 0xff;
	while (!ti_u2c1);
	u2tb = 0xff;
	while (!ti_u2c1);

	// 等待发送完毕,立即锁存.
	while (!txept_u2c0);
	VFD_CLR = 0;
	VFD_CLR = 1;

	// 再送下一位显示数据.
	u2tb = vfd_tmp_buf[0];
	while (!ti_u2c1);
	u2tb = vfd_tmp_buf[1];
	while (!ti_u2c1);
	u2tb = vfd_tmp_buf[2];
	while (!ti_u2c1);

	// 等待发送完毕,立即锁存.
	while (!txept_u2c0);
	VFD_CLR = 0;
	VFD_CLR = 1;
}

///////////////////////////////////////////////////////////////////////////////
// Description: drive VFD via Normal I/O lines
// In Param:	void
// Out Param:	void
// Return:		void
///////////////////////////////////////////////////////////////////////////////
void Vfd_WriteStr(void)
{
//	asm("jsr.a 1e00h");

//	if (vfd_drv_mode == VFD_DRV_IO)
//	{
//		asm("jsr.a 1e00h");
//	}
//	else if (vfd_drv_mode == VFD_DRV_SERIAL)
//	{
		Vfd_WriteStr_Serial();
//	}
//	else
//	{
//	}
}

///////////////////////////////////////////////////////////////////////////////
// Description: Vfd display initial
// In Param:	void
// Out Param:	void
// Return:		void
///////////////////////////////////////////////////////////////////////////////
void Vfd_Init(void)
{
   pd7 = 0xFF;

	VFD_CLR_DIR = 1;
	VFD_CLK_DIR = 1;
	VFD_DI_DIR  = 1;

//	if (Hw_GetVer() == HW_V2)
	{
		vfd_drv_mode = VFD_DRV_IO;
	}
//	else
//	{
//		vfd_drv_mode = VFD_DRV_SERIAL;				// 新版本用同步串口方式驱动.
//	}
	Vfd_Clr();

	ClsDispComma();
	ClsDispUnderline();

//   if (vfd_drv_mode == VFD_DRV_SERIAL)
   {
//	   pd7_3 = 0;
	   // need set A/B/C register
	   ps1_0 = 1;					// TxD2 output
		psl1_0 = 0;					// TxD2 port
	
//	   ps1_1 = 0;					// RxD2 as I/O
	
		ps1_2 = 1;					// CLK2 func select enable
		psl1_2 = 0;
		psc_0 = 0;					// CLK2 output
	
	   // MODE: set data format,set start bit and stop bit
	   u2mr = 0x01;			   // set baud rate: BRG's source and BRG's value
	   u2c0 = 0x10;				// LSB, f1, 2 division, 10M/2 = 5M
//	   ckpol_u2c0 = 1;			// transfer data at rising edge of clock
	   u2brg = 7;					// if FOSC == 14M, {7} is OK!
//	   s2tic = 0x05;           // set serial IPL,enable interrupt
//	   u2c1 = 0x05;            // enable Tx

		te_u2c1 = 1;            // enable Tx
	   u2irs = 1;              // cause by TI = 1(transmit completed)
	}
	
//	tb1mr = 0x40;						// f8, disable gate, timer mode
//	tb1 	= 500 * FOSC / 8;			// set timer B1 initial value
//	tb1ic = 0x05;
//	tb1s = 1;							// Start timer B1
}

///////////////////////////////////////////////////////////////////////////////
// Description: VFD clear all display
// In Param:	
// Out Param:	
// Return:		
///////////////////////////////////////////////////////////////////////////////
void Vfd_Clr(void)
{
	byte i;
	
	for (i=0; i<VFD_BIT_NUM; i++)
	{
		Vfd_DispChar(i, ' ', 0);
	}
}

///////////////////////////////////////////////////////////////////////////////
// Description: display into VFD
// In Param:	posi, dsp_char, dot
// Out Param:	void
// Return:		void
///////////////////////////////////////////////////////////////////////////////
void Vfd_DispChar(byte pos, byte temp, byte dots)
{
	extern volatile bool bPrnProtectEnable;
	byte cmdbuf[5];
	byte tmpPos;
	byte tmpPos2 = pos;
   
	VFD_Buff[pos] = temp;
	
	tmpPos = 9 - pos;
	pos = posCvt[tmpPos];

	if ((temp >= '0') && (temp <= '9'))
	{
		temp = disbuf[temp-'0'];
	}
	else if ((temp >= 0x0A) && (temp <= 0x0F))
	{
		temp -= 0x0A;
		temp = disbuf[temp+12];
	}
	else if ((temp >= 'a') && (temp <= 'z'))
	{
		temp -= 'a';
		temp = disbuf[temp+12];
	}
	else if ((temp >= 'A') && (temp <= 'Z'))
	{
		temp -= 'A';
		temp = disbuf[temp+12];
	}
	else if (temp == ' ')
	{
		temp = disbuf[10];
	}
	else if (temp == '-')
	{
		temp = disbuf[11];
	}
	else if(temp == '.')
	{
		temp = VFD_CHAR_DEC;
	}
	else if (temp <= 9)
	{
		temp = disbuf[temp];
	}
	else
	{
		VFD_Buff[tmpPos2] = ' ';
		return;
	}
	
	if (dots != 0)
	{
		temp &= 0x7f;
	}

	if (pos <= 7)
	{
		cmdbuf[0] = temp << 4;
		if ((cmdbuf[0] & 0x10) == 0x10)
		{
			cmdbuf[0] += 0x0f;
		}
		cmdbuf[1] = (temp >> 4) + 0xf0;
		cmdbuf[2] = ~(0x01 << pos);
	}
	else if (pos <= 9)
	{
		cmdbuf[0] = temp << 4;
		if ((cmdbuf[0] & 0x10) == 0x10)
		{
			cmdbuf[0] += 0x0f;
		}
		if (pos == 8)
			cmdbuf[1] = (temp >> 4) + 0xB0;
		else
			cmdbuf[1] = (temp >> 4) + 0x70;
		cmdbuf[2] = 0xff;
	}
	else
	{
		return;
	}

	#if 0
   if (bPrnProtectEnable)
	#else
	if (0)
	#endif
   {
   	disint();
		memcpy(bk_vfddisBuf[tmpPos], cmdbuf, 3);
		enint();
   }
   else
   {
		ta0s = 0;	//	disint();
		memcpy(vfddisBuf[tmpPos], cmdbuf, 3);
		ta0s = 1;	// enint();
	}
}

/*
	保存VFD显示数据. (中断调用)
*/
void StoreVfdDisp(void)
{
	memcpy(bk_vfddisBuf, vfddisBuf, sizeof(vfddisBuf));
}

/*
	恢复VFD显示数据. (中断调用)
*/
void RestoreVfdDisp(void)
{
	memcpy(vfddisBuf, bk_vfddisBuf, sizeof(vfddisBuf));
}

/*
	保存VFD显示数据. (主程序调用)
*/
void Main_StoreVfdDisp(void)
{
	memcpy(bk_main_vfddisBuf, vfddisBuf, sizeof(vfddisBuf));
}

/*
	恢复VFD显示数据. (主程序调用)
*/
void Main_RestoreVfdDisp(void)
{
	memcpy(vfddisBuf, bk_main_vfddisBuf, sizeof(vfddisBuf));
}



///////////////////////////////////////////////////////////////////////////////
// Description: Copy function "Vfd_WrtStrEx" to Internal RAM.
// In Param:	void
// Out Param:	void
// Return:		void
///////////////////////////////////////////////////////////////////////////////
void Vfd_CopyFuncToRam(void)
{
	extern dword softRtcAddr;
	
	asm("mov.l #_Vfd_WrtStrEx, _softRtcAddr");
	memcpy((byte *)0x1e00, (byte *)softRtcAddr, 0x100);
}

///////////////////////////////////////////////////////////////////////////////
// Description: 刷新VFD显示,在系统定时中断中调用.
// In Param:	void
// Out Param:	void
// Return:		void
///////////////////////////////////////////////////////////////////////////////
void Vfd_WrtStrEx(void)
{
	volatile byte *cmdbuf = vfd_tmp_buf;
	byte i, j;
	byte temp;

	//asm("fclr i");
	// 设置中断允许优先级与打印中断平行,即屏蔽打印中断.
	asm("ldipl #4");										
	for (i=3; i>0; i--)
	{
		temp = *cmdbuf++;
		
		if (i == 3)
		{
			temp >>= 3;
		}
		else
		{
	   		VFD_CLK = 0;
	   		if (temp & 0x01)	VFD_DI = 1;
	      	else	      		VFD_DI = 0;
	   		temp >>= 1;
		   	VFD_CLK = 1;

	   		VFD_CLK = 0;
	   		if (temp & 0x01)	VFD_DI = 1;
	      	else	      		VFD_DI = 0;
	   		temp >>= 1;
		   	VFD_CLK = 1;

	   		VFD_CLK = 0;
	   		if (temp & 0x01)	VFD_DI = 1;
	      	else	      		VFD_DI = 0;
	   		temp >>= 1;
		   	VFD_CLK = 1;
		}

		VFD_CLK = 0;
		if (temp & 0x01)	VFD_DI = 1;
   	else	      		VFD_DI = 0;
		temp >>= 1;
   	VFD_CLK = 1;

		VFD_CLK = 0;
		if (temp & 0x01)	VFD_DI = 1;
   	else	      		VFD_DI = 0;
		temp >>= 1;
   	VFD_CLK = 1;

		VFD_CLK = 0;
		if (temp & 0x01)	VFD_DI = 1;
   	else	      		VFD_DI = 0;
		temp >>= 1;
   	VFD_CLK = 1;

		VFD_CLK = 0;
		if (temp & 0x01)	VFD_DI = 1;
   	else	      		VFD_DI = 0;
		temp >>= 1;
   	VFD_CLK = 1;

		VFD_CLK = 0;
		if (temp & 0x01)	VFD_DI = 1;
   	else	      		VFD_DI = 0;
		temp >>= 1;
   	VFD_CLK = 1;
	}
	VFD_CLR = 0;
	VFD_CLR = 0;
	VFD_CLR = 1;
	//asm("fset i");
	// 恢复中断允许优先级,即重设为系统定时中断的优先级.
	asm("ldipl #3");
}

///////////////////////////////////////////////////////////////////////////////
// Description: Close Vfd display
// In Param:	void
// Out Param:	void
// Return:		void
///////////////////////////////////////////////////////////////////////////////
void Vfd_Cls(void)
{
	vfd_tmp_buf[0] = 0xFF;							// clear VFD
	vfd_tmp_buf[1] = 0xFF;
	vfd_tmp_buf[2] = 0xFF;
	Vfd_WriteStr();
}

///////////////////////////////////////////////////////////////////////////////
// Description: 刷新VFD显示,在系统定时中断中调用本函数.
// In Param:	
// Out Param:	
// Return:		
///////////////////////////////////////////////////////////////////////////////
void Vfd_Flush(void)
{
   volatile static byte vfdScanCnt = 0; 

   if (IsVfdOn())
   {
		vfd_tmp_buf[0] = vfddisBuf[vfdScanCnt][0];
		vfd_tmp_buf[1] = vfddisBuf[vfdScanCnt][1] & 
								(vfdCommaAndUnderline[VFD_BIT_NUM - 1 - vfdScanCnt] | 0xCf);
		vfd_tmp_buf[2] = vfddisBuf[vfdScanCnt][2];
		//asm("jsr.a 1e00h");
		Vfd_WriteStr();
		vfdScanCnt++;
		vfdScanCnt %= VFD_BIT_NUM;
	}
}

///////////////////////////////////////////////////////////////////////////////
//									VFD特殊符号(逗号及下划线)显示驱动.
///////////////////////////////////////////////////////////////////////////////

// 显示指定位置的逗号.
void DispComma(byte pos)
{
   if (pos >= VFD_BIT_NUM)
   	return;

	vfdCommaAndUnderline[pos] &= VFD_COMMA_EN;
}

// 清除显示指定位置的逗号.
void ClrDispComma(byte pos)
{
   if (pos >= VFD_BIT_NUM)
   	return;

	vfdCommaAndUnderline[pos] |= VFD_COMMA_DIS;
}

// 清除所有位置的逗号.
void ClsDispComma(void)
{
	byte i;
	for (i=0; i<VFD_BIT_NUM; i++)
		vfdCommaAndUnderline[i] |= VFD_COMMA_DIS;
}

// 显示指定位置的下划线.
void DispUnderline(byte pos)
{
   if (pos >= VFD_BIT_NUM)
   	return;

	vfdCommaAndUnderline[pos] &= VFD_UNDERLINE_EN;
}

// 清除显示指定位置的下划线.
void ClrDispUnderline(byte pos)
{
   if (pos >= VFD_BIT_NUM)
   	return;

	vfdCommaAndUnderline[pos] |= VFD_UNDERLINE_DIS;
}

// 清除所有位置的下划线.
void ClsDispUnderline(void)
{
	byte i;
	for (i=0; i<VFD_BIT_NUM; i++)
		vfdCommaAndUnderline[i] |= VFD_UNDERLINE_DIS;
}
#if 0  //used for disp flash,  but no useful 
/*--------------------------------------------------------------------
*	display flash
*	used for the offer function, alerm operator
*	beep 3 times, and flash 3 times
*-------------------------------------------------------------------*/
void	disp_flash(void)
{
	BYTE	r;
	BYTE	r1;
	byte	bk[VFD_BIT_NUM][3];	// 正常程序的显示备份,用于主程序保存及恢复显示.
	Main_StoreVfdDisp();
	memcpy(bk, bk_main_vfddisBuf, sizeof(vfddisBuf));
	disp_Char_Str("--OFFER---",0);

	for ( r = 0; r < 3; r ++ )
	{
		Main_StoreVfdDisp();
		for ( r1 = 0; r1 < 3; r1 ++ )
		{
			Clr_Dsp_Data();
			bellcnt = 0x3e;
			Delay(200);		/*delay 0.3 s */
			Main_RestoreVfdDisp();
			Delay(200);		/*delay 0.3 s */
		}
		Delay(500);
	}
	memcpy(bk_main_vfddisBuf, bk,sizeof(vfddisBuf));
	Main_RestoreVfdDisp();
}
#endif
#endif//end OLD VFD

⌨️ 快捷键说明

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