点亮VFD屏.docx
- 文档编号:27551071
- 上传时间:2023-07-02
- 格式:DOCX
- 页数:19
- 大小:80.06KB
点亮VFD屏.docx
《点亮VFD屏.docx》由会员分享,可在线阅读,更多相关《点亮VFD屏.docx(19页珍藏版)》请在冰豆网上搜索。
点亮VFD屏
VFD的实现原理和驱动设计
单片机音响技术网2008/2/21
VFD的简单介绍
VFD是指真空荧光显示器,是VacuumFluorescentDisplay的缩写,利用电子撞击玻璃基板上的荧光粉而发光,通过VFD上面的各个亮点的组合一起发亮来显示字符,数字,特定的图标等等。
由于VFD的显示,清晰明亮低工耗等特点被广泛用于家用电器,仪器设备,自动动化设备等上面,用来显示数字信息如温度,字符信息如:
名称和一些标记指示信息。
有关VFD的硬件结构,工作原理,在网上有很多的介绍,在官方网站可以很容易的找到非常准确的介绍。
VFD原理及使用请在本站下载
DVD视盘机的VFD显示典型硬件电路
VFD的硬件电路可根据VFD屏的SPEC了解其需要驱动的段,位,选择相应的驱动IC,常用的包括PT6312,PT6311,PT6311相对驱动的段,位多些,可连接的按键也多些。
驱动电路的外围元件参数参照PT6311,PT6312的SPEC即可,需要注意的是,6312,6311有很多品牌均可通用,不同品牌的驱动注意其振荡电阻阻值的差异,其余基本相同,另外在电路半设计中驱动电压+5V的去藕电容尽量靠近IC,驱动数据线(DATA,STB,CLK)各连接一个101瓷片到地,保证IC,数据线不受干扰或减轻干扰。
VFD显示屏的供电
VFD显示屏的供电包括交流~3V3灯丝电压和驱动芯片需要的-21V~-27V以及+5V,上图是典型的变压器次级供电处理电路。
还有一种方法是用直流逆变得到或者使用开关电源,现在市场上很多专门的DVD开关电源,满足DVD解码板以及VFD显示的电源要求,电源组包括:
+5V,±12V,-21V,~3V3,有些还带常用集成功放的电源,使用他们也非常方便。
笔者设计的TOPAV-2008开发平台,其VFD供电采用了直流逆变交流的方式,结构非常简洁,使用方便,详细可到单片机音响技术网了解。
VFD的软件控制驱动设计
前面说过VFD用途广泛,所以就非常有必要搞清楚如何通过软件去驱动它了,怎样让VFD显示我们要显示的内容,这就是一个程序员要思考的问题了,也是本文的目力所在。
市场上有很多电子产品都要用到VFD,其中目前比较火热的数字电视,机顶盒(DVB)还有DVD上面都在使用VFD显示。
要想让VFD正常的工作还要依赖一个工作的平台,比如说,你是在Sunplus平台上,还是在Cheertek,Ali,ST,MTK,ESS的等平台上做。
要让程序能高效的工作,并且具备最大可能性的移植和扩展性是非常重要的,例如让一个VFD的驱动模块同时可以在Sunplus,cheertek,Ali等多个平台上工作,也可以能在其它单片机上工作,只要它能支持C语言编程。
为了让整个模块更加的模块化,我们就需要对整个模块进行进一步的细份。
哎!
废话少说,太激动了。
驱动三步走
我们把VFD的驱动分成三步或三部分来实现,各个部分实现相应的功能:
第一步:
上层接口,用于适应市场上不同公司和种类的VFD。
第二步:
中间层,VFD各中显示功能的的实现,用语满足显示需求。
例如:
一般显示,闪动,滚动,旋转,等....
第三步:
平台接口,用于实现和各个平台之间的接口,主要是和CPU的通信。
基于上面的构想,下面就来分步实现它
简单的介绍一下实现环境:
编译环境:
GCC
语言:
C
测试平台:
Cheertek(CT219,909),和Ali(Ali3330,3329)(DVB的外部显示,用来显示电台名称等等…)
VFD硬件:
CS16312。
第一步:
建立通用接口:
用于适应市场上不同公司和种类的VFD8段编码在开始写成程序实现之前,先了解字符显示的原理,字符是根据8段编码的方式在VFD上面显示的,当然也有更多段的编码方式。
8段编码用一个字节来描述一个ASCII字符,对扩展的ASCII码如包含德语,法语等就要用到更多段的编码,也就是用多个字节来表示一个字符。
在一个八段编码的VFD中,把8段分别定义为a,b,c,d,e,f,g,h段,用一个字节来表示就是
hgfedcba
h是字节的最高位,a是字节的最低位。
显示字符的原理如下:
VFD常用字母的写法
“米”字8和8的区别请注意有不同根据上面的原理,0表示熄灭,1表示点亮,可以得出,8段分别点亮后的对应编码是:
8段的每一段对应一个字节的一个位的:
h:
10000000--->0x80
g:
01000000--->0x40
f:
00100000--->0x20
e:
00010000--->0x10
d:
00001000--->0x08
c:
00000100--->0x04
b:
00000010--->0x02
a:
00000001--->0x01
根据上面的每段编码,如果要显示字符'A'需要同时点亮a,b,c,e,f,g段并且d段熄灭,这样一个'A'的字符轮廓就出来了,如上图”AbCd”中的'A',所以的字母A的编码是01110111也就是把相应要点亮的段编码或起来就可以了'A'的编码值=a|b|c|e|f|g各个段的对应关系如下:
76543210
hgfedcba
01110111
通过上面的分析可以在程序中用如下宏来重新定义VFD的8段
#defineSEG_A0x01
#defineSEG_B0x02
#defineSEG_C0x04
#defineSEG_D0x08
#defineSEG_E0x10
#defineSEG_F0x20
#defineSEG_G0x40
#defineSEG_H0x80
通过上面的分析和段定义可以为字符'A'做如下定义:
#defineCHAR_ASEG_A|SEG_B|SEG_C|SEG_E|SEG_F|SEG_G
根据上面的分析定义,我可以为26个字母,和10个数字字符做完整的定义如下:
#defineNUM_0SEG_A|SEG_B|SEG_C|SEG_D|SEG_E|SEG_F
#defineNUM_1SEG_B|SEG_C
#defineNUM_2SEG_A|SEG_B|SEG_D|SEG_E|SEG_G
#defineNUM_3SEG_A|SEG_B|SEG_C|SEG_D|SEG_G
#defineNUM_4SEG_B|SEG_C|SEG_F|SEG_G
#defineNUM_5SEG_A|SEG_C|SEG_D|SEG_F|SEG_G
#defineNUM_6SEG_A|SEG_C|SEG_D|SEG_E|SEG_F|SEG_G
#defineNUM_7SEG_A|SEG_B|SEG_C
#defineNUM_8SEG_A|SEG_B|SEG_C|SEG_D|SEG_E|SEG_F|SEG_G
#defineNUM_9SEG_A|SEG_B|SEG_C|SEG_D|SEG_F|SEG_G
#defineCHAR_ASEG_A|SEG_B|SEG_C|SEG_E|SEG_F|SEG_G
#defineCHAR_aCHAR_A
#defineCHAR_BSEG_C|SEG_D|SEG_E|SEG_F|SEG_G
#defineCHAR_bCHAR_B
#defineCHAR_cSEG_D|SEG_E|SEG_G
#defineCHAR_CSEG_A|SEG_D|SEG_E|SEG_F
#defineCHAR_dSEG_B|SEG_C|SEG_D|SEG_E|SEG_G
#defineCHAR_DCHAR_d
#defineCHAR_ESEG_A|SEG_D|SEG_E|SEG_F|SEG_G
#defineCHAR_eCHAR_E
#defineCHAR_FSEG_A|SEG_E|SEG_F|SEG_G
#defineCHAR_fCHAR_F
#defineCHAR_gNUM_9
#defineCHAR_GNUM_9
#defineCHAR_HSEG_B|SEG_C|SEG_E|SEG_F|SEG_G
#defineCHAR_hCHAR_H
#defineCHAR_INUM_1
#defineCHAR_iNUM_1
#defineCHAR_LSEG_D|SEG_E|SEG_F
#defineCHAR_lCHAR_L
#defineCHAR_NSEG_A|SEG_B|SEG_C|SEG_E|SEG_F
#defineCHAR_nSEG_B|SEG_C|SEG_E|SEG_F|SEG_H
#defineCHAR_ONUM_0
#defineCHAR_oSEG_C|SEG_D|SEG_E|SEG_G
#defineCHAR_PSEG_A|SEG_B|SEG_E|SEG_F|SEG_G
#defineCHAR_pLETT_P
#defineCHAR_rSEG_E|SEG_G
#defineCHAR_RCHAR_r
#defineCHAR_SSEG_A|SEG_C|SEG_D|SEG_F|SEG_G
#defineCHAR_tSEG_D|SEG_E|SEG_F|SEG_G
#defineCHAR_TLETT_t
#defineCHAR_USEG_B|SEG_C|SEG_D|SEG_E|SEG_F
#defineCHAR_YSEG_B|SEG_C|SEG_D|SEG_F|SEG_G
#defineCHAR_GSEG_G
#defineCHAR_BLANK0x00
上面为基本的字符数字都做了编码定义,以后就可以通过编码来指代这些字符,如一个字符串“Helloworld”等于CHAR_H+CHAR_e+CHAR_l+CHAR_l+CHAR_BLANK+CHAR_w+CHAR_O
CHAR_r+CHAR_l+CHAR_d.
用数组表示:
charstr_hw[11]={CHAR_H,CHAR_e,CHAR_l,CHAR_l,CHAR_BLANK,CHAR_w,CHAR_O
CHAR_r,CHAR_l,CHAR_d};
显示原理
到目前为止,我们还只是对基本字符和数字进行了逻辑上的编码,和怎样生成一个字符串,这些多还仅仅是个开始,要想在VFD上面显示”helloworld”还有很多事情要做,接下来我们就要了解VFD是如何显示字符的。
VFD要显示字符还要通过一块VFD驱动芯片来实现,VFD本身只能显示就像电脑的显示器一样,要想让它显示内容还要通过驱动芯片加上周边驱动电路共同来完成显示的任务。
在DVB,DVB和其它用到VFD的电子产品中都会有一块VFD的电路板,通常叫VFD板(VFDpanel)或前面板(Frontpanel)这块电路板就是由VFD驱动芯片,周边驱动电路和VFD组成。
在目前的市场中VFD驱动芯片种类很多,但标准一样。
VFD通过驱动电路与驱动芯片相连,来完成驱动芯片的显示任务,而驱动芯片的的任务是通过平台系统(如Ali的3329主芯片)获得的。
在实际的编程过中,只需要通过平台系统上的主芯片(CPU)来控制VFD板上的驱动芯片从而完成一个显示任务,或其他任务,平台系统上的主芯片(CPU)一般是通过一个标准的三线串口来与VFD驱动芯片连接。
上面简单的介绍了主板CPU,驱动芯片和VFD之间的关系,具体的细节可以在相应的DATASHEET或spec.中找到,或从硬件工程师那看到详细的电路连接状况,对相互协调工作就会有比较深刻的认识。
哎!
又罗嗦了
透过CPU控制VFD驱动芯片,VFD驱动芯片(16312)的内部框图如下:
在上面的框图中,可以看到一个显示存储器(DisplayRAM)正是通过这个显示寄存器来实现显示功能的,显示寄存器中的一个字节可以描述一个字符,显示寄存器中的一位映射到VFD显示屏中的一个亮点,也就是说如果向显示寄存器中的一个被映射的位写1,那么在VFD显示屏中的相应的亮点就会被点亮,相反写0VFD显示屏中的相应的亮点就会被熄灭。
通过向显示寄存器中写入一个字节,来显示一个基本字符,写入若干个字节可以显示一个字符串。
显示寄存器透过段位在芯片外引出引脚然后连到VFD上,显示寄存器到VFD的映射就是这样通过硬件连接来实现的,通常由于驱动芯片的各个引脚可以根据自己的需要有选择的选用,线路的连接会有细微的变化,使得VFD的各个亮点映射到显示寄存器的具体的地址也会有一些细微差别,想要在VFD上任意位置为开始显示一个任意一个字符串,和点亮VFD上面的任意一点,程序员必须就必须知道和计算出在一块确定的VFD驱动板上,VFD上的每个亮点映射到了显示寄存器中的什么地址位,从而决定向显示寄存器的什么地址写数据,所以定义VFD上面的每个亮点在DISPLAYRAM中的地址,从右往左,VFD上面的所有亮点由若干个8段和icon组成:
例如:
下面N1_代表第一个8段
#defineN1_SEG_A_ADDR0x02
#defineN1_SEG_A_DATA0x04
//上面定义的意思是:
//1.8段中A段在显示寄存器中的字节地址即这个亮点映射到了显示存储器中的第几个字//节(例如0x02第二个字节).
//2.A段映射到显示寄存器的某个字节的第几位(例如:
0x04即000001008位中的第//
三位,也就是有置1的位)
//上面的定义描述了,从左往右,VFD第一个8段中的
A段映射到显示寄存器中第2个字节中的//第三位,也就说,如果把显示寄存器中的第二个字节中的第三位置
1,那么VFD第一个8段中//的A段就会被点亮,即向显示寄存器中的N1_SEG_A_ADDR地址处写入N1_SEG_A_DATA。
//下面可以依次定义VFD上面的各个亮点和ICON。
//注意:
关于宏定义的值(如:
0x02,0x04)从哪里来,将会在后面讲到,其实是要再写程序//来测试出各个亮点对应的地址,或从相关SPEC中得到。
驱动完成以后,对于不不同的VFD只//要添上值就可以了。
#defineN1_SEG_B_ADDR0x02
#defineN1_SEG_B_DATA0x08
#defineN1_SEG_C_ADDR0x02
#defineN1_SEG_C_DATA0x40
#defineN1_SEG_D_ADDR0x03
#defineN1_SEG_D_DATA0x08
#defineN1_SEG_E_ADDR0x03
#defineN1_SEG_E_DATA0x04
#defineN1_SEG_F_ADDR0x03
#defineN1_SEG_F_DATA0x40
#defineN1_SEG_G_ADDR0x03
#defineN1_SEG_G_DATA0x30
#defineN1_SEG_H_ADDR0x00
#defineN1_SEG_H_DATA0x00
............................
//IconDefine
#defineVFD_TITLE_ADDR0x00
#defineVFD_TITLE0x00
#defineVFD_CHAPTER_ADDR0x00
#defineVFD_CHAPTER0x00
#defineVFD_HOUR_ADDR0x00
#defineVFD_HOUR0x00
#defineVFD_HOUR_COL_ADDR0x02
#defineVFD_HOUR_COL0x01
...............................
上面对VFD上的各个亮点做了定义,但我们还需要建立一个映射表方便在调用各个段定义。
BYTEADDRESS_MAPPING[]=
{N1_SEG_A_ADDR,N1_SEG_B_ADDR,N1_SEG_C_ADDR,N1_SEG_D_ADDR,N1_SEG_E_ADDR,
N1_SEG_F_ADDR,N1_SEG_G_ADDR,0,
N1_SEG_A_DATA,N1_SEG_B_DATA,N1_SEG_C_DATA,N1_SEG_D_DATA,N1_SEG_E_DATA,
N1_SEG_F_DATA,N1_SEG_G_DATA,0,
.................
.................
};
根据三部分的驱动设计思想,我们把VFD驱动芯片通过串行接口与CPU的通信划分到整个驱动设计的第三部分,第一步所要做的是建立一个逻辑上与硬件无关公共接口。
根据上面对显示寄存器的分析,我们可以建立一个数组用来映射驱动芯片中的显示寄存器,上面的16X11显示存储器可以显示22个字节,所以我们可以做如下定义:
BYTE16312_DisplayRam[22];
第二步:
中间层:
VFD各种显示功能的的实现,用于满足显示需求。
在这部分主要根据第一层的公共接口和在第三层的驱动的基础上来实现VFD的各种显示功能,所以这部分主要是调用第三层的驱动函数来处理第一层的数据,或着说是将第一层的信息根据显示需求通过第三层发送给VFD驱动芯片中去。
对于一个VFD首先要具备对一个条信息的基本显示功能,下面将介绍如何显示一个字符串”Helloworld”,要想同时完全显示这个字符串,首先VFD上面必须要有11个8段,就是硬件支持同时显示11个字符的VFD,如果不够后面的字符就回丢失。
实现一个过程将字符串解析到16312_DisplayRam中。
voidParseStringToRamMapping(char*Str,BYTEStrcount)
{
BYTEi,j;
for(i=0;i{
for(j=0;j<8;j++)
{
if(Str[i+1]&(0x01< 16312_DisplayRam[ADDRESS_MAPPING[i*16+j]]|=ADDRESS_MAPPING[i*16+8+j]; else 16312_DisplayRam[ADDRESS_MAPPING[i*16+j]]&=~ADDRESS_MAPPING[i*16+8+j]; } } } //得到当前在VFD上正在显示的信息 voidParseRamMappingToString() { } //将"Helloworld"解析到16312_DisplayRam中。 ParseStringToRamMapping(str_hw,11); //将16312_DisplayRam写到VFD的RAM中去。 Write_Datas(16312_DisplayRam,NULL,22); 在主程序polling的时候呼叫Write_Datas方法将16312_DisplayRam最终写到VFD驱动芯片的显示RAM中之后,在调用Start_VFD();VFD上就会显示出“Helloworld”了。 在第二层中的内容主要是显示功能的实现和逻辑控制,程序写起来可以根据实际需求灵活多变,而第一部分和第三部分的内容则相对稳定。 所以也可以实现类似下面的函数来实时控制VFD的显示: voidShowMessagesOnVFD(char*Str,BYTEStrcount) { ParseStringToRamMapping(Str,Strcount); Write_Datas(16312_DisplayRam,NULL,22); Start_VFD(); } 或者 voidPrintMessagesOnVFD(char*Str,BYTEStrcount) { ParseStringToRamMapping(Str,Strcount); Write_Datas(16312_DisplayRam,NULL,22); Start_VFD(); } 第三步: 平台接口: 用于实现和各个平台之间的接口,主要是和CPU的通信。 在第三部分主要实现CPU与VFD驱动芯片通过串行接口通信的问题。 CPU通过串行接口控制VFD的关闭和显示,VFD的亮度,显示存储器的读写,按键扫描等。 在上面的图中可以看到,串口有四线,STB,CLK,Din,Dout但在实际电路中Din和Dout连接在一起使用,所有又叫三线串口。 STB: 片选信号线在上升或下降沿初始化串行接口随后等待接收 指令STB为低后的第一个字节作为指令,当处 理指令时当前其它处理被终止,当STB为高 时CLK被忽略。 CLK: 时钟信号线。 在上升沿读取串行数据下降沿输出数据。 Din: 数据输入。 Dout: 数据输出。 串口通信和GPIO 了解VFD用到的IO口,通过一台整机的电路图,或从PCB板上用万能表测出VFD串行接口连接到CPU上的引脚,然后根据CPU的SPEC得到映射到的IO接口,完整的说应该是GPIO(GeneralPurposeInput/Output的缩写即通用输入输出接口,支持I2C,串行总线等协议)。 如: Ali3330 #defineGPIO_VFD_STB17 #defineGPIO_VFD_SDA22//Din和Dout #defineGPIO_VFD_CLK16 上面的定义可以理解为: VFDSTB连接到了主板CPU上的IO17 VFDSDA连接到了主板CPU上的IO22 VFDCLK连接到了主板CPU上的IO16 知道了连接所用的IO后,就可以同过VFD串行接口向VFD驱动芯片发送收据和控制信息,向显示寄存器,键扫寄存器读写数据但,但首先要能够通过软件控制各个IO接口,也就是可以通过软件设置各个GIO的电位,例如: 把GPIO17拉高到+5伏,或拉低到-5伏,如果有确定的平台系统,则相应的平台会提供相应的GPIO操作接口 例如Cheertek909 HAL_WriteGPIO(GPIO_VFD_STB,1);//向PGIO17写1输出高电位 HAL_WriteGPIO(GPIO_VFD_STB,0);//向PGIO17写0输出低电位 HAL_ReadGPIO(GPIO_VFD_SDA)? 1: 0;//读GPIO Ali3330 #defineHAL_GPIO_BIT_SET(pos,val)/ do{osal_interrupt_disable();/ ((pos<32)/ ? HAL_GPIO_WRITE((HAL_GPIO_READ()&~(1<<(pos)))|((val)<<(pos)))/ : HAL_GPIO1_WRITE((HAL_GPIO1_READ()&~(1<
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 点亮 VFD