|
在设计仪器仪表时,经常会碰到要求在LCD显示屏上显示电流电压等参数的波形曲线。初次接触该问题的工程师都觉得这个很困难,无从下手,论坛上也经常有同志提出这方面问题。本文针对上述问题,阐述了显示曲线的原理,给出了画直线段的子程序。
在数字系统里,我们画的曲线都是由若干段的直线段组成的。例如,在一个电流采集系统中,显示的电流波形曲线是如何得到的?
首先,创建坐标系,X轴表示时间,Y轴表示电流;
然后,我们要在时间轴上连续采样若干个点的电流值,每个采样点的电流值都对应坐标系中的一个点;
最后,我们就可以将坐标系中的相邻点用直线段连接起来,得到的就是电流波形了!
因此,我们可以看出,画曲线的关键,真正的难点转为了画直线段。画直线段的算法有很多种,以下画直线段的C代码(针对51单片机)使用的是插补算法。
///////////////////////////////////////////////////////////
// //
// 来自www.viewtech.cn //
// 画线程序,适合单色LCD屏 //
// 驱动板VT1335b/VT6448b/VT4832b //
// 入口程序:draw_LINE(unsigned int x1,y1,x2,y2); //
// 起点(x1,y1),终点(x2,y2),以象素为单位 //
// LCD屏左上角为坐标原点 //
// //
// //
//////////////////////////////////////////////////////////
#include <reg51.h>
#include <absacc.h>
#define X_ADDR XBYTE[0x0000]
#define Y_ADDR XBYTE[0x0100]
#define CMD XBYTE[0x0200]
#define DAT XBYTE[0x0300]
//声明程序
draw_point(unsigned int x,unsigned int y);
draw_LINE(unsigned int x1,y1,x2,y2);
//*************************draw LINE start*******************************
draw_LINE(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{
unsigned int x,y;
unsigned int d_x,d_y;//d_x=x2-x1;d_y=y2-y1;
int err=0;
unsigned CHAR TEMP=0;
if(y2<y1){x=x1;y=y1;x1=x2;y1=y2;x2=x;y2=y;}
d_y=y2-y1;
if (d_y==0)
{
if (x1>x2) {x=x1;x1=x2;x2=x;}
for ( x=x1;x<=x2;x++ ) draw_point(x,y1);
}
else
{
if(x2>=x1){TEMP=1;d_x=x2-x1;}else d_x=x1-x2;
x=x1;y=y1;draw_point(x,y);
if(TEMP&&(d_y<=d_x))
while(x!=x2)
{if(err<0){x=x+1;err=err+(y2-y);}
else {x=x+1;y=y+1;err=err+(y2-y)-(x2-x);}
draw_point(x,y);
}
else if(TEMP&&(d_y>d_x))
while(y!=y2)
{d_x=x2-x;d_y=y2-y;
if(err<0){x=x+1;y=y+1;err=err+d_y-d_x;}
else {y=y+1;err=err-d_x;}
draw_point(x,y);
}
else if(!TEMP&&(d_y<=d_x))
while(x!=x2)
{d_x=x-x2;d_y=y2-y;
if(err<0){x=x-1;err=err+d_y;}
else {x=x-1;y=y+1;err=err+d_y-d_x;}
draw_point(x,y);
}
else if(!TEMP &&(d_y>d_x))
while(y!=y2)
{d_x=x-x2;d_y=y2-y;
if(err<0){x=x-1;y=y+1;err=err+d_y-d_x;}
else {y=y+1;err=err-d_x;}
draw_point(x,y);
}
}
}
draw_point(unsigned int x,unsigned int y)
{
unsigned CHAR TEMP,i;
Y_ADDR = y;X_ADDR = x/8;
if(y>255)CMD=0x14;else CMD=0x04;
TEMP=DAT;
i=0x80;
i=(i>>(x%8));
TEMP=(TEMP|i);
Y_ADDR = y;X_ADDR = x/8;
if(y>255)CMD=0x14;else CMD=0x04;
DAT=TEMP;
}
//************draw LINE end********************
//调用举例
main()
{
draw_LINE(0,0,150,150);//(0,0)->(150,150)
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|