📄 vfd_new.c
字号:
/******************************************************************************
* ptd.c
*
* Function: set the ptd vfd driver
*
* copyright: Weihua
*
* author: Analy
*
* Date: 2006-05-30
*
* VFD显示点阵字库,10段,高电平驱动, 含有逗号和下划线
* The segment code position:
* 0
* ________
* | |
* 5 | | 1
* | 6 |
* |--------|
* | | 2
* 4 | | _
* |________| |_| 7
* 3 _
* | | 8
* ======== |/
* 9
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*
* posi: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |*
* bit: b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7 | b8 | b9 |*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*
******************************************************************************/
#include "ecrsys.h"
#include "ftype.h"
#include "disp.h"
#include "vfd_new.h"
#include <string.h>
#ifdef NEW_VFD
void Vfd_Disp_Set(word seg_data, byte len, byte posi);
#define VFD_STB_ON 0
#define VFD_STB_OFF 1
#define MAX_VFD_LEN 10 /* 10位VFD, 这个不可以在上层函数中调用 */
typedef struct{
byte level;
byte onoff; // bool onoff
}VFD_STAT;
static VFD_STAT Vfd_Stat; /* The VFD status */
static word Vfd_Seg_Buff[MAX_VFD_LEN]; /* The VFD display segment buffer, used in Vfd_Drv.c */
//static word Bak_Vfd_Seg_Buff[MAX_VFD_LEN]; /* The backup of VFD display buffer */
//byte Disp_Ext_Fixed[MAX_VFD_LEN]; /* 长显特殊字符的缓冲区, 目前仅有小数点,逗号,下划线 */
const word Vfd_Disp_Dot[] = {
0x0000,/* ' ' */ 0x0000,/*- '!' */ 0x0022,/* '"' */ 0x0000,/** '#' */
0x0000,/** '$' */ 0x0000,/** '%' */ 0x0000,/** '&' */ 0x0002,/* ''' */
0x0000,/** '(' */ 0x0000,/** ')' */ 0x0000,/** '*' */ 0x0000,/** '+' */
0x0100,/* ',' */ 0x0040,/* '-' */ 0x0080,/* '.' */ 0x0000,/** '/' */
0x003F,/* '0' */ 0x0006,/* '1' */ 0x005B,/* '2' */ 0x004F,/* '3' */
0x0066,/* '4' */ 0x006D,/* '5' */ 0x007D,/* '6' */ 0x0007,/* '7' */
0x007F,/* '8' */ 0x006F,/* '9' */ 0x0000,/** ':' */ 0x0180,/* ';' */
0x0000,/** '<' */ 0x0048,/* '=' */ 0x0000,/** '>' */ 0x0000,/** '?' */
0x0000,/** '@' */ 0x0077,/* 'A' */ 0x007C,/* 'B' */ 0x0039,/* 'C' */
0x005E,/* 'D' */ 0x0079,/* 'E' */ 0x0071,/* 'F' */ 0x003D,/* 'G' */
0x0076,/* 'H' */ 0x0006,/* 'I' */ 0x001E,/* 'J' */ 0x0000,/** 'K' */
0x0038,/* 'L' */ 0x0000,/** 'M' */ 0x0054,/* 'N' */ 0x003F,/* 'O' */
0x0073,/* 'P' */ 0x0067,/* 'Q' */ 0x0050,/* 'R' */ 0x006D,/* 'S' */
0x0078,/* 'T' */ 0x003E,/* 'U' */ 0x0000,/** 'V' */ 0x0000,/** 'W' */
0x0000,/** 'X' */ 0x006E,/* 'Y' */ 0x0000,/** 'Z' */ 0x0000,/** '{' */
0x0000,/** '\' */ 0x0000,/** ']' */ 0x0000,/** '^' */ 0x0200,/* '_' */
0x0020,/* '`' */ 0x0077,/* 'a' */ 0x007c,/* 'b' */ 0x0039,/* 'c' */
0x005E,/* 'd' */ 0x0079,/* 'e' */ 0x0071,/* 'f' */ 0x003D,/* 'g' */
0x0076,/* 'h' */ 0x0006,/* 'i' */ 0x001E,/* 'j' */ 0x0000,/** 'k' */
0x0038,/* 'l' */ 0x0000,/** 'm' */ 0x0054,/* 'n' */ 0x003F,/* 'o' */
0x0073,/* 'p' */ 0x0067,/* 'q' */ 0x0050,/* 'r' */ 0x006D,/* 's' */
0x0078,/* 't' */ 0x003E,/* 'u' */ 0x0000,/** 'v' */ 0x0000,/** 'w' */
0x0000,/** 'x' */ 0x006E,/* 'y' */ 0x0000,/** 'z' */ 0x0000,/** '{' */
0x0030,/* '|' */ 0x0000,/** '}' */ 0x0040,/* '~' */ 0x03ff,/* 全亮 */
};
const word Vfd_Quote_Seg[] = //只包含小数点, 逗号, 分号和下划线.
{
0x0080,/* '.' */ 0x0100,/* ',' */ 0x0180,/* ';' */ 0x0200/* '_' */
};
#define Vfd_Wait() {}
/********************************************************************************
* 函数说明: 写一个字节到PT6311
* 输入参数: void
* 输出参数: void
* 返回值: void
********************************************************************************/
static void Vfd_Write_Byte(byte wrByte)
{
byte i;
for (i = 0; i < 8; i++)
{
VFD_CLK = 0; /* 上升沿启发写, 先设置成0 */
Vfd_Wait();
VFD_DIN = wrByte&0x01;
wrByte >>= 1;
VFD_CLK = 1; /* 启动上升沿 */
Vfd_Wait();
}
}
/********************************************************************************
* 函数说明: Vfd的初始化
* 初始化VFD的时候, 调用了延时函数Wait, 所以需保证系统中断是开的
* 说明: 这里的初始化语句是有一定的顺序的, 不能随意修改其顺序
* 输入参数: void
* 输出参数: void
* 返回值: void
********************************************************************************/
void Vfd_Init(void)
{
byte i;
// Wait(200); /* Waiting for PT6311 hardware initializing */
VFD_STB_DIR = 1;
VFD_CLK_DIR = 1;
VFD_DIN_DIR = 1;
/* Initial the VFD status */
Vfd_Stat.level = VFD_DFT_BRIGHT; // 预定义的默认的亮度
Vfd_Stat.onoff = 1;
/* Set the PT6311 write data mode */
VFD_STB = VFD_STB_ON;
Vfd_Write_Byte( 0x40 );
VFD_STB = VFD_STB_OFF;
Vfd_Wait();
/* Clear the display RAM, for when the IC power is applied for the first time
the contents of display RAM are not defined, must do this step */
Vfd_Disp_Set(0, MAX_VFD_LEN, 0);
/* Set the PT6311 16 digits, 12 segments work mode */
VFD_STB = VFD_STB_ON;
Vfd_Write_Byte( 0x0f );
VFD_STB = VFD_STB_OFF;
Vfd_Wait();
/* Set the display mode */
VFD_STB = VFD_STB_ON;
Vfd_Write_Byte( 0x80|((Vfd_Stat.onoff&0x01)<<3)|(Vfd_Stat.level&0x07) );
VFD_STB = VFD_STB_OFF;
Vfd_Wait();
for(i = 0; i < MAX_VFD_LEN; i++)//清除缓冲区
{
Vfd_Seg_Buff[i] = 0;
// Disp_Ext_Fixed[i] = 0;
// Bak_Vfd_Seg_Buff[i] = 0;
}
}
/********************************************************************************
* 函数说明: 在VFD上显示一格点阵, 可以显示一个字符
* 输入参数: seg_data, posi[0-MAX_VFD_LEN]
* 输出参数: void
* 返回值: void
********************************************************************************/
void Vfd_Disp_Grid(word seg_data, byte posi)
{
byte addr;
if (posi >= MAX_VFD_LEN)
return;
Vfd_Seg_Buff[posi] = seg_data;
/* Calculate the address */
addr = (MAX_VFD_LEN-1-posi)*3; /* 位置必须再取一次反 */
/* 发送段码数据到指定的地址位置 */
VFD_STB = VFD_STB_ON;
Vfd_Write_Byte( addr|0xC0 );
Vfd_Write_Byte(seg_data);
Vfd_Write_Byte(seg_data>>8);
VFD_STB = VFD_STB_OFF;
Vfd_Wait();
}
/********************************************************************************
* 函数说明: 在VFD上显示多格点阵, 可以显示字符串
* 由于硬件上面的显示位置与实际的显示位置是有所不同的,\
* 它们的地址正好是递减的, 所以这里需要做特殊的处理.
* 输入参数: src, byte len, posi[0-MAX_VFD_LEN]
* 输出参数: void
* 返回值: void
********************************************************************************/
void Vfd_Disp_Mem(word *src, byte len, byte posi)
{
byte addr;
byte i;
if (posi >= MAX_VFD_LEN)
return;
if (posi+len > MAX_VFD_LEN)
len = MAX_VFD_LEN - posi;
for( i =0; i < len ; i++)
{
Vfd_Seg_Buff[posi+1] = src[i];
}
/* Calculate the address */
addr = (MAX_VFD_LEN-posi-len)*3; /* 位置必须再取一次反 */
src += len-1;
/* 发送段码数据到指定的地址位置 */
VFD_STB = VFD_STB_ON;
Vfd_Write_Byte( addr|0xC0 );
while(len--)
{
Vfd_Write_Byte(*src);
Vfd_Write_Byte(*src>>8);
Vfd_Write_Byte(0); // 写入空数据, 地址加1, 自动指向下一个数据缓冲区的地址
src--;
}
VFD_STB = VFD_STB_OFF;
Vfd_Wait();
}
/********************************************************************************
* 函数说明: 在多格中显示相同的点阵
* 输入参数: seg_data, len, posi[0-MAX_VFD_LEN]
* 输出参数: void
* 返回值: void
********************************************************************************/
void Vfd_Disp_Set(word seg_data, byte len, byte posi)
{
word tmp[MAX_VFD_LEN];
byte len2 = len;
if (posi >= MAX_VFD_LEN)
return;
if (posi+len > MAX_VFD_LEN)
len = MAX_VFD_LEN - posi;
while(len2--)
{
tmp[len2] = seg_data;
}
Vfd_Disp_Mem(tmp, len, posi);
}
/********************************************************************************
* 函数说明: 设置VFD亮度等级(8个亮度等级), 初始化默认等级为0
* 这里无法量化实际上的亮度, 因为跟很多原因有关, (电压, 环境, VFD本身)
* 目前这里所能够做的只是软件亮度设置等级, 即VFD的刷新速度.
* 输入参数: level [0-8]
* 输出参数: void
* 返回值: void
********************************************************************************/
void Vfd_Set_Bright(byte level)
{
Vfd_Stat.level = level&0x07;
VFD_STB = VFD_STB_ON;
Vfd_Write_Byte( 0x80|((Vfd_Stat.onoff&0x01)<<3)|(Vfd_Stat.level&0x07) );
VFD_STB = VFD_STB_OFF;
Vfd_Wait();
}
/********************************************************************************
* 函数说明: 关闭VFD显示, 即使这时发送显示命令, 也不再显示, 不过这时
* 更新了显示的缓冲区
* 输入参数: void
* 输出参数: void
* 返回值: void
********************************************************************************/
void Vfd_Cls(void)
{
Vfd_Stat.onoff = 0;
VFD_STB = VFD_STB_ON;
Vfd_Write_Byte( 0x80|((Vfd_Stat.onoff&0x01)<<3)|(Vfd_Stat.level&0x07) );
VFD_STB = VFD_STB_OFF;
Vfd_Wait();
}
/********************************************************************************
* 函数说明: 打开VFD显示, 显示显示缓冲区的内容
* 输入参数: void
* 输出参数: void
* 返回值: void
********************************************************************************/
void Vfd_Open(void)
{
Vfd_Stat.onoff = 1;
VFD_STB = VFD_STB_ON;
Vfd_Write_Byte( 0x80|((Vfd_Stat.onoff&0x01)<<3)|(Vfd_Stat.level&0x07) );
VFD_STB = VFD_STB_OFF;
Vfd_Wait();
}
/********************************************************************************
* 函数说明: 清除VFD的显示
* 输入参数: void
* 输出参数: void
* 返回值: void
********************************************************************************/
void Vfd_Clr(void)
{
byte i;
for(i = 0; i < MAX_VFD_LEN; i++)
{
Vfd_Seg_Buff[i] = 0;
}
Vfd_Disp_Mem(Vfd_Seg_Buff, MAX_VFD_LEN, 0);
}
/********************************************************************************
* 函数说明: 一次性显示或隐藏显示中的特殊段, 有小数点, 逗号, 下划线
* 输入参数: type, posi
* type可以取0~7, 即DISP_SEG_NOR ~ DISP_SEG_DOT_COMMMA_UDL
* 输出参数: void
* 返回值: void
********************************************************************************/
void Disp_Set_XtrSeg(byte type, byte posi)
{
word seg_data;
if (posi >= MAX_VFD_LEN)
return;
seg_data = Vfd_Seg_Buff[posi]|((((word)type)&0x07)<<7);
Vfd_Disp_Grid(seg_data, posi);
}
/********************************************************************************
* 函数说明: 一次性隐藏显示中的特殊段, 有小数点, 逗号, 下划线
* 输入参数: type, posi
* type可以取0~7, 即DISP_SEG_NOR ~ DISP_SEG_DOT_COMMMA_UDL
* 输出参数: void
* 返回值: void
********************************************************************************/
void Disp_Clr_XtrSeg(byte type, byte posi)
{
word seg_data;
byte flag;
if (posi >= MAX_VFD_LEN)
return;
flag = (byte)((Vfd_Seg_Buff[posi]&0x0380)>>7);
flag &= ~type;
seg_data = Vfd_Seg_Buff[posi]&0x07f;
seg_data |= ((word)(flag&0x07))<<7;
Vfd_Disp_Grid(seg_data, posi);
}
byte Vfd_Cvt_Char(byte *data)
{
byte dots = DISP_SEG_NOR;
if(*data <= 9)
{
*data += '0';
}
else if(*data<= 0x0f)
{
*data += 'A' - 0x0a;
}
else if((*data < 0x20)||(*data >= 0x80))
{
*data = 0x20;
}
else if(*data == '.')
{
*data = 0xff;
dots = DISP_SEG_DOT;
}
else if(*data == ',')
{
*data = 0xff;
dots = DISP_SEG_COMMA;
}
else if(*data == ';')
{
*data = 0xff;
dots = DISP_SEG_DOT_COMMA;
}
return dots;
}
/********************************************************************************
* 函数说明: 显示一个字符, 如果带小数点, 支持小数点的显示
* 输入参数: posi: 注意此处的posi是一个绝对地址
* 输出参数: void
* 返回值: void
********************************************************************************/
void Vfd_DispChar(byte posi, byte data, byte dots)
{
word tmp = 0;
byte flag;
flag = Vfd_Cvt_Char(&data);
if(data == 0xff)
tmp = Vfd_Seg_Buff[posi];
else
tmp = Vfd_Disp_Dot[data-0x20];
flag |= dots;
if(flag != DISP_SEG_NOR)
{
tmp |= ((word)flag)<<7;
}
Vfd_Disp_Grid(tmp, posi);
}
void Vfd_InsPeriod(byte posi)
{
if(posi >= MAX_VFD_LEN)
return;
Disp_Set_XtrSeg(DISP_SEG_DOT, posi);
}
void Vfd_ClrPeriod(byte posi)
{
word seg_data;
if(posi >= MAX_VFD_LEN)
return;
Disp_Clr_XtrSeg(DISP_SEG_DOT, posi);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -