基于LC2294的VFD编程设计
【摘要】LPC2294是飞利浦半导体公司生产的基于ARM7TDMI-S内核的芯片。本文介绍一个基于LPC2294的VFD显示的设计工程(前后台模式),给出软件编程的相关文件说明及重要代码的详细设计过程。在本工程的基础上可以继续进行POS收款机等嵌入式电子产品的开发。
【关键词】LPC2294;ARM;VFD模块;PS6311
1.引言
真空荧光显示屏(VFD,Vacuum Flu-orecent Display)具有悦目的光彩、高亮度的发光效率、很好的可靠性与环境适应性以及长寿命等特性,因此,在工业、商业、特别是家用电器数字化产品领域得到了广泛的应用。对VFD显示屏的显示控制通常需通过专用的VFD控制/驱动器来实现,这种控制方式硬件设计简单、占用资源少,是目前VFD显示控制的主要实现方式。
LPC2294是基于一个支持实时仿真和跟踪的16/32位ARM7TDMI-S CPU,并带有256K字节的嵌入的高速Flash存储器。它有极低的消耗,多个32位定时器,RTC模块,WDT模块等。可以用来开发POS终端等多种嵌入式电子产品.POS终端上一般要求有个VFD客显,它可以用来显示时间、产品价格等。
本文设计了一个基于LPC2294的VFD显示工程(前后台模式),把该工程下载到基于LPC2294的开发板后,能够全部点亮VFD亮以及显示实时时钟等数据。该工程利用ads开发软件,在CodeWarrior IDE集成开发环境下编写编译链接,然后使用AXD和技创公司的techorICE仿真器调试并下载程序。下面对该工程的软件编程做具体介绍。
2.基于LPC2294的开发板与vfd模块的硬件连接
本设计中vfd模块的驱动芯片为PS6311。本设计利用LPC2294的P0.6与P0.7,P0.8连接到vfd模块的VFD_DAT,VFD_CS,VFD_CLK。其中,VFD_CS用来输入vfd片选信号,低电平有效;VFD_CLK是vfd时钟信号,作为控制串行数据线上的数据传输的波特率;VFD_DATA是串行数据线。
3.对vfd显示工程里的文件进行分析
利用ADS建立的vfd显示工程vfd.mcp。该工程文件分两个文件夹放置。一个是board文件夹,一个是application文件夹。
3.1 Board文件夹
该文件夹放置一些用ARM汇编语言写的文件(**.s)和一些头文件(*.h)。对其中文件简介如下。
LPC22xx.h文件对LPC2294的寄存器位置进行定义。
LPC2000_Config.h文件对lpc2294工作的时钟进行设置。它设置晶振频率FOSC为10MHZ,即#define FOSC 10000000L;设置锁相环PLL,使处理器时钟FCCLK为40MHZ;设置VPB分频器,使外设器件所使用的时钟FPCLK为10MHZ。同时还设置存储器加速模块的相关寄存器。
Vectors.s文件放置异常向量表Vectors和FIQ异常处理程序。
Init.s文件主要放置复位Reset和初始化InitStack,__user_initial_stackheap等处理程序。
STACK.s和heap.s文件为堆栈和堆在内存中创造存放空间。
3.2 Application文件夹
该文件夹放置一些用c语言写的文件(*.c)和一些头文件(*.h)。*.h文件主要起到对相应的*.c文件进行函数声明和外部函数声明的作用。下面给出这些文件的主要代码和分析。
3.2.1 Target.c文件
主要包含void InitLPC2000(void),void InitBoard (void)两个函数。分别对初始化lpc2294和开发板上外部总线进行设置。
3.2.2 main.c文件
#include"LPC2000_Config.H"
#include"vfd.h"
#include"rtc.h"
LPC_INT8U VfdShowtime;
LPC_INT8U ledflag;
LPC_INT8U T;
void time1init(void)
/*该函数初始化LPC2294里的定时器1,设置每过1毫秒产生一次中断,即置位定时器里IR中的MR0位;并复位定时器计数器TC*/
{TIMER1_TC=0;
TIMER1_PR=0;
TIMER1_MCR=0x03;
TIMER1_MR0=FPCLK/1000;
TIMER1_TCR=0x01;
}
int main(void)
//该主函数调用上述编写的函数,它先全部点亮vfd,然后令vfd显示实时时间。
{RTCIni();
InitVfd();
time1init();
T=0;
for(;;)
{if((TIMER1_IR&0x01)==1)
//根据time1init()对lpc2294定时器的设定,每过一毫秒,满足上式。
{TIMER1_IR=TIMER1_IR||0x01;
//此式清除LPC2294里定时器的中断,即令(TIMER1_IR&0x01)==0)。
T++;
if(T==100)
{T=0;
UpdateVfd();
//每过一百毫秒,读取VFD缓冲区里的时间数值,刷新VFD显示
}}}}
3.2.3 RTC.C文件
/*注解:对于需要使用到的lpc2294芯片里的模块,如实时时钟RTC模块,定时器TIMER1,I/O端口等,在使用这几个模块之前,应先对这几个模块里的各个寄存器先全部进行初始化,然后再使用。这样整个工程才能顺利运行。*/
#include"LPC2000_Config.H"
void RTCIni(void)
//该函数初始化LPC2294里的实时时钟RTC模块,并启动RTC。
{RTC_PREINT=FPCLK/32768-1;
RTC_PREFRAC=FPCLK-(FPCLK/32768) *32768;
//以上设置基准时钟分频器,以便能产生32.768KHZ的基准时钟。
RTC_HOUR=8;//初始化小时
RTC_MIN=30;//初始化分
RTC_SEC=0;//初始化秒
RTC_CCR=0x01;//启动RTC
}
struct TIME
{LPC_INT8U hour;
LPC_INT8U min;
LPC_INT8U sec;
}*t;
void GetTime(void)
//该函数读取LPC芯片里RTC模块的时间,送到t数组里。
{t->hour=RTC_HOUR;
t->min=RTC_MIN;
t->sec=RTC_SEC;
}
3.2.4 vfd.c文件
#include"LPC2000_Config.H"
#include"rtc.h"
#ifdef INCLUDE_VFD
#define DISMODE7 0x0f
#defineWRITETODIS 0x40
#defineSETPULSE3 0x8b
#defineSETDGT1 0xc0
#define DOTLEN 0x40
LPC_INT8U VfdBuffer[12]; //VFD缓冲区
LPC_INT8U VfdLength; //VFD显示个数
LPC_INT8U VFD_CLK,VFD_DAT,VFD_CS;
LPC_INT8U VfdDgtTbl[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,
0x00,0x40};
extern LPC_INT8U VfdShowtime;
extern LPC_INT8U ledflag;
void Updatevfd(void);
void SendCmdToVfd(LPC_INT8U value)
//此函数向VFD发送数据或命令
{LPC_INT8U i;
for(i=0;i<8;i++)
{VFD_CLK=0;//时钟置低
if(VFD_CLK==1)IOSET0|=0x00000100;
else IOCLR0|=0x00000100;
VFD_DAT=(value & 0x01);//串行线输出数据
if(VFD_DAT==1)IOSET0|=0x00000040;
else IOCLR0|=0x00000040;
VFD_CLK=1;//时钟置高,上升沿数据有效。
if(VFD_CLK==1)IOSET0|=0x00000100;
else IOCLR0|=0x00000100;
value/=2;//数据value向右右移一位。
}
VFD_DAT=1;
if(VFD_DAT==1)IOSET0|=0x00000040;
else IOCLR0|=0x00000040;
}
//初始化VFD
void InitVfd(void)
/*vfd模块初始化函数。该函数先初始化lpc2294的p0口全部为GPIO口,设置P0.6与P0.7,P0.8引脚为输出方向,然后利用P0.6与P0.7,P0.8送出数据到vfd模块的三根引脚VFD_DAT,VFD_CS和VFD_CLK,初始化VFD。*/
{PINSEL0=0x00000000; //设置p0口全部为GPIO口
IODIR0=0x000001c0; //设置P0.6与P0.7,P0.8为输出
VFD_CS=0;
if(VFD_CS==1)IOSET0|=0x00000080;
else IOCLR0|=0x00000080;
SendCmdToVfd(DISMODE7); //设置模式为16位数字,12段显示。
VFD_CS=1;
if(VFD_CS==1)IOSET0|=0x00000080;
else IOCLR0|=0x00000080;
VFD_CS=0;
if(VFD_CS==1)IOSET0|=0x00000080;
else IOCLR0|=0x00000080;
SendCmdToVfd(SETPULSE3); //设置脉冲宽度位10/16.
VFD_CS=1;
if(VFD_CS==1)IOSET0|=0x00000080;
else IOCLR0|=0x00000080;
ledflag=1; //使UpdateVfd()程序运行时,vfd模块全部点亮。
UpdateVfd();
ledflag=0;
VfdShowtime=1; //使UpdateVfd()程序运行时,vfd模块显示时间。
}
void TimeToVfd()
/*该函数用GetTime()读取时间,再将读取的t数组的时间数值送到VFD缓冲区*/
{GetTime();
VfdBuffer[0]=t->sec%0x0a;
VfdBuffer[1]=t->sec/0x0a;
VfdBuffer[2]=0x11;
VfdBuffer[3]=t->min%0x0a;
VfdBuffer[4]=t->min/0x0a;
VfdBuffer[5]=0x11;
VfdBuffer[6]=t->hour%0x0a;
VfdBuffer[7]=t->hour/0x0a;
VfdLength=8;//VFD显示个数
}
//更新VFD显示
void UpdateVfd(void)
//该函数更新VFD显示
{LPC_INT8U i;
VFD_CS=0;
if(VFD_CS==1)IOSET0|=0x00000080;
else IOCLR0|=0x00000080;
SendCmdToVfd(WRITETODIS);//写数据命令
VFD_CS=1;
if(VFD_CS==1)IOSET0|=0x00000080;
else IOCLR0|=0x00000080;
VFD_CS=0;
if(VFD_CS==1)IOSET0|=0x00000080;
else IOCLR0|=0x00000080;
SendCmdToVfd(SETDGT1);//地址设置命令
if(ledflag==1)//满足此条件,可令vfd模块全部点亮
{for(i=0;i<12;i++)
{SendCmdToVfd(0xff);
SendCmdToVfd(0xff);
SendCmdToVfd(0xff);
}
}else
{if(VfdShowtime==1)//令vfd模块显示时间
{TimeToVfd();
}
for(i=0;i {SendCmdToVfd(VfdDgtTbl[VfdBuffer[i] & 0x1f]); SendCmdToVfd(VfdBuffer[i]/0x20); SendCmdToVfd(0x00); } for(i=VfdLength;i<12;i++)//令大于VfdLength的位不亮。 {SendCmdToVfd(0x00); SendCmdToVfd(0x00); SendCmdToVfd(0x00); }} SendCmdToVfd(0x00);//令vfd模块里第12位以上都不亮。 SendCmdToVfd(0x00); SendCmdToVfd(0x00); VFD_CS=1; if(VFD_CS==1)IOSET0|=0x00000080; else IOCLR0|=0x00000080; } 4.结束语 把该工程下载到基于LPC2294的开发板后,能够脱机运行。VFD全亮和显示时间的图片为图1和图2。在本工程的基础上可以继续进行POS终端等嵌入式电子产品的开发。 参考文献 [1]周立功.ARM嵌入式系统基础教程[M].北京:北京航空航天大学出版社,2005. [2]王崇峰,黄梦涛.ARM7的键盘与VFD显示器接口技术[J].单片机与嵌入式系统应用,2009,1:40-42. [3]梁建辉,杨金岩.VFD控制/驱动器LPD16312的原理与应用[J].国外电子元器件,2003,1:58-62. [4]Philips Semiconductors.LPC2292/LPC2294 Product data.2004. 基金项目:集美大学李尚大学科建设基金(编号:ZC2011006)资助。 作者简介:蔡彦(1978-),女,福建厦门人,硕士,讲师。