引言
在个人便携式核探测仪器领域,有时需要进行大量数据量处理和实时可视化显示。个人核探测仪器用动态实时数据曲线来显示监测量,可以更加直观地反映一个阶段监测量的变化趋势,比仅用数字显示更为形象和直观。使用友好的人机界面,可以在提升产品品质、扩展功能和提高操作便利性方面带来长足的进步。
1曲线绘制原理
1.1选用Bresenham画线算法绘制曲线
数据曲线是把许多数据点用平滑线连接而成的,所以在液晶上绘制曲线时需要找到合适的连线算法。本文选取Bresenham画线算法。此算法由Bresenham在1965年提出,其特点是绘制过程中不做除法,不用浮点数,只进行整数加减法和乘2运算,且乘2运算可以用硬件移位实现。Bresenham画线算法速度快,适合用硬件实现。其算法画线依据如图1所示。
图1Bresenham算法画线依据
A(x1,y1)和B(x2,y2)两个点代表液晶上面的2个像素点,在水平方向的间隔假设为3个点,需要把A、B用平滑的线连接起来。如图1所示,由A、B两个点确定一条直线ax+by+c=0,在A(x1,y1)点右边的像素列上与A相邻的有B0和B1两点,分别称为A的右上邻接像素点和右邻接像素点。M(x1+1,y1+0.5)点并不是液晶上面的真实像素点,而是虚拟的点,用作右上邻接像素点和右邻接像素点的分界。使用A、B两个点确定的直线ax+by+c=0与x1+1的交点,与M点进行比较,来绘制右上邻接像素点或者右邻接像素点。交点在M点上方绘制右上邻接像素点,反之则绘制右邻接像素点。
1.2待显示数据存储方式
对于大量数据显示的情况,数据的组织方式就显得格外重要。一种方案是用数组存储待显示数据。按3个像素点间距,对液晶上曲线显示区域进行划分,可以显示76个数据,所以需要存储这76个数据,可用数组float display[76]实现。数组中每个数据元素始终对应液晶的一个像素列,再根据每个数据元素大小具体对应这个像素列中的具体像素点。
display[75]对应液晶第230列,display[74]对应第227列,它们之间的水平间距是3个像素点。当采集到新数据时,需要将新数据值存储在display[75]变量里。原来display[75]变量里的数据则存在display[74]中,即从display[75]变量开始,依次把display[76]数组里的数据移动到前一个变量里存储。因为display[76]数组中的75个变量分别对应液晶上的一个像素列,所以经过这种处理后再用display[76]数组数据绘制曲线,就可以在液晶上面看到曲线有从右向左移动的效果。
用数组存储待显示数据的方案,由于需要把display[76]数组里面数据依次向前移动一个位置后再进行曲线绘制,因此在需要处理大量显示数据时实时性会受到影响。本文采用的方案是以链式存储方式组织待显示数据。首先,动态分配75个节点链接起来,当采集到新数据后,动态分配一个节点把新数据存入其数据域,使动态分配节点指针域指向75个节点的首节点。待绘制完整的曲线后,释放最后一个节点。下一次采集到新数据时重复这个过程。
1.3显示曲线的实时更新
实时曲线更新后,希望看到曲线有从右向左移动的效果。直观的想法是先把整个液晶显示屏清屏,然后绘制新曲线。经过实验发现屏幕有闪烁现象。本文提出的方案是:当得到新的测控数据后,先对最后4个像素列上的原曲线以背景色绘制,再用黑色在最后4个像素列上绘制新曲线,这个过程依次进行直到完整曲线绘制完毕。
2曲线绘制实例
本文为LM4229液晶设计了画线函数,调用接口为:
paintline(x0,y0,x1,y1,color)//(x0,y0)和(x1,y1)对应液晶上2个像素点坐标
其中,color为1表示用Bresenham画线算法把(x0,y0)和(x1,y1)用黑色线连接,color为0表示用背景色绘制。
当得到新的测控数据后,需要把新数据加入到链表中,再绘制曲线。曲线有从右向左移动效果的实现代码为:
typedef struct aa{
int data;
struct aa *next;
} node;
node *oldhead, *p, *s;
oldhead=p=(node *)malloc(sizeof(node));
oldhead>data=0;
for(i=0; i<75; i++){
s=(node *)malloc(sizeof(node));
s>data=0;
p>next=s;
p=s;
}
p>next=NULL;//初始化链表,首节点为 oldhead
node * newhead=(node *)malloc(sizeof(node));
newhead>data=newvalue;
newhead>next=oldhead;
node * head=newhead;
for(j=74; j>=0;j--) {
paintline (x,oldhead>data,x3,oldhead>next>data,0);
paintline (x,newhead>data,x3,newhead>next>data,1);
oldhead=oldhead>next;
newhead=newhead>next
x=x-3;
if(x==5)
x=230;//设计液晶最右边绘图像素列为第230列,最左边绘图像素列为第5列,这样绘制曲线区域有225个像素列,按照相邻2个数据点3个像素列的间隔,可以绘制75个数据点
} free(oldhead);//释放链表最末尾一个节点
oldhead=head;
采用随机产生的数据绘制实时曲线,如图2所示。
图2实时曲线
结语
实时曲线绘制是个人便携式仪器的友好人机界面的重要组成部分,本文在液晶上对曲线直接绘制具有绘制速度快、实现简单的特点。直接绘制曲线避免了使用第三方插件,有利于缩小程序存储空间,降低生产成本,具有较高的应用价值。