关键词:液晶型提示器、镜像、实时输出、无线遥控器 、AVR单片机、串口、C语言、Visual C++、双缓冲、延时函数、消息循环
前言:
播音提示器是电视台最常见的设备,其基本原理比较简单,即采用单反玻璃反射镜像显示的上滚文字。老式的提示器大多采用CRT显示器和字幕上滚软件,新型提示器大多使用液晶显示屏输出文字并使用了专用的实时播音提示软件,部分型号还增加了遥控功能。
2007年10月随着我台真三维虚拟演播室的建设,我们更新了一直使用老式DOS版字幕上滚软件的播音提示器,即保留了单反玻璃、机架、用做输出的21寸彩电,重新采购了计算机,重新设计编写了新的提示器软件,设计制作了无线遥控电路和相关的单片机程序。
本文将详细介绍提示器软件的设计、无线遥控电路的设计以及相关的VC++程序、单片机C语言程序、电路原理图。
提纲:
一、 播音提示器的基本原理
二、 使用VC++设计提示器软件
三、 实时高速贴图的实现途径----双缓冲和消息循环
四、 液晶显示字幕与CRT显示字幕的区别
五、 使用无线遥控器,PT2262和PT2272
六、 使用AVR单片机转发信号
七、 按键复用的问题
八、 提示器VC++程序主要源代码
九、 AVR单片机CodeVision C语言源程序
十、 结束语
正文:
一、 播音提示器的基本原理
播音提示器利用单反玻璃单面反射和单面透射的光学特性,使播音员能够看到挡在摄像机前面的单反玻璃上反射的上滚文字,而摄像机拍摄透过单反玻璃并不会受到另一面反射的文字的影响,播音提示器或通过摄像头或通过计算机将文字显示在于单反玻璃呈45度夹角的显示器上,由于镜面反射的缘故,要想看到反射形成的正像,显示器必须输出镜像的画面。镜像画面对于CRT显示器来说很简单,只需要拆开机器交换行扫描输出线即可,对于液晶显示器来说就没有那么简单了,所有的镜像画面全部要通过计算机软件来生成。至于镜像的方法有两种,一种是更改显示输出,使整个显示画面镜像显示,一种是通过实时运算,镜像一个贴图区,本文将介绍后一种实现方法。
二、 使用VC++设计提示器软件
很多字幕上滚软件并不是实时贴图的,即有一个生成上滚文件的过程。随着计算机运算能力的大幅跃升,采用优化的算法、高效率的设计语言也是可以实现实时贴图输出的。VC++6.0是widows程序设计中应用程序执行效率较高的开发平台之一,而且其内置的GDI绘图函数可以很方便地输出图形,相比.net语言中的GDI+输出速度上还有一定优势。
三、 实时高速贴图的实现途径----双缓冲和消息循环
在windows MFC程序设计中,即使是简单的刷新也可能使界面闪烁不已,要实现平滑流畅的文字滚动效果依赖控件和定时器肯定是行不通的。我们只能通过双缓冲的办法,即在内存中作图,在贴图的过程中又画好下一幅图片,如此反复,在通过一定的延时手段,让贴图速度(文字滚动速度)能够得到很好的控制。
下面是一个使用液晶屏做为字幕输出时镜像贴图的函数,演示了内存缓冲贴图的技术。需要指出的是本文所采用的实时贴图算法均衡考虑了一些实时参数修改响应的问题,并不是最精简的贴图算法,实际上现在一般的计算机配置用这个函数也可以滚动得飞快!
void CTishiqiDlg::Onplay2()
{
isPlayMirr=2;
//在内存中建立位图
CDC *pDC=GetDC();
CDC *pDCpic=m_pic.GetDC();
CDC dcMem;
// BITMAP bm;
iExit=0;
CBitmap bmpBuf;
DWORD start,nowTime;
dcMem.CreateCompatibleDC(NULL);
bmpBuf.DeleteObject();
bmpBuf.CreateCompatibleBitmap(pDC,mWidth,mHeight);
CBitmap *poldBitmap=dcMem.SelectObject(&bmpBuf);
dcMem.SetBkMode(TRANSPARENT);
//输出滚动字幕
for (mTi=0;mTi<=mLen;mTi++)
{
start=GetTickCount();
if (mLen<10)
{ //估算文字长度,如不考虑中途修改可去掉以提高速度
CSize size=pDCpic->GetTextExtent(tStr);
int xx= size.cx;
int yy= size.cy;
mLen=(xx/mWidth+1)*yy*172+mHeight;
pos=0;
}
rect.top=rect.top-m_slid2.GetPos();
pos=pos+m_slid2.GetPos();
// m_slid3.SetScrollPos(pos,TRUE);
if (iExit>0) mTi=mLen;
dcMem.SetTextColor(fontColor);
CFont *poldFont=dcMem.SelectObject(&m_font);