📄 vfd.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 + -