51单片机在LCD12864上画曲线的源码如下:
- /********************************** LCD12864曲线显示*******************************************/
- /*********作者:王胜文。 email:nunk@163.com 希望与大家交流2017。08。03**********/
- #include<avr/io.h>
- #include<reg51.h>
- #include<drive_functions.h>
- #include<math.h>
- //#include<get_keys.h>
- #define Graphic_Clear 0x01 //檫除点
- #define Graphic_Not 0x02 //反相点
- #define Graphic_Draw 0x03 //画点
- uchar j=0,i=0;
- uchar r=32;
- /***********************在LCD上任意坐标画点********************************/
- void DrawPoint(uchar X,uchar Y,uchar Type)
- { //X,Y化点的坐标Type画点的类型:反相点,檫除点,画点
-
- uchar DX = (Y >> 3); //计算出属于哪个字节
- uchar BX = Y - (DX << 3); //计算出属于字节哪一位
- uchar TempData = 0;
-
-
- if (X > 63)
- {
- chip_select=2;
- X -= 64;
- }
- else
- {
- chip_select=1;
- }
- SetPage(DX); //设行地址
- SetColumn(X); //设列地址
-
- TempData = ReadData(); //读出所画点所在字节的内容
-
- switch (Type) //对该字节进行相应操作
- {
- case Graphic_Clear:
- TempData &= ~(1<<BX);
- break;
- case Graphic_Not:
- TempData ^= (1 << BX);
- break;
- case Graphic_Draw:
- TempData |= (1 << BX);
- break;
- default: break;
- }
-
- SetPage(DX); //设置行地址
- SetColumn(X); //设置列地址
- WriteData(TempData); //把修改后的字节送回LCD,达到画点目的
- }
- /********插值法画任意两点之间直线的函数,函数中只用加减法,程序运行效率很高**********/
- DrawLine(uchar x1,uchar y1,uchar x2,uchar y2)
- { //x1,y1起点坐标;x2,y2终点坐标;
- uchar x,y;
- uchar d_x,d_y;
- char err=0;
- uchar 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++ ) DrawPoint(x,y1,Graphic_Draw);
- }
- else
- {
- if(x2>=x1){temp=1;d_x=x2-x1;}else d_x=x1-x2;
- x=x1;y=y1;DrawPoint(x,y,Graphic_Draw);
- 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);}
- DrawPoint(x,y,Graphic_Draw);
- }
- 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;}
- DrawPoint(x,y,Graphic_Draw);
- }
- 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;}
- DrawPoint(x,y,Graphic_Draw);
- }
- 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;}
- DrawPoint(x,y,Graphic_Draw);
- }
- }
- }
- /***********************************************************************/
- void DrawLevel(void)
- {
- for(i=0;i<127;i++){DrawPoint(i,32,Graphic_Draw);}//画水平直线
- }
- /************************************************************************************/
- void DrawSineWave(void)
- {
- uchar xn=0;
- uchar yn=32;
- uchar i;
- uchar xi,yi;
- for(i=0;i<127;i++)
- {
- xi=i;
- yi=(sin(i*0.1)*32)+32;
- DrawLine(xn,yn,xi,yi); //在一系列零散的点上,两点两点之间连线,从而得到一条曲线
-
- xn=i;
- yn=yi;
-
- }
- }
- /*************************************************************************************/
- void DrawCircle(uchar x0,uchar y0,uchar r)//x0,y0为圆心坐标,r为圆半径
- {
- uchar xn,yn,xi,yi;
- unsigned int j;
- xn=cos(0)*r+x0;
- yn=sin(0)*r+y0;
- for(j=0;j<630;j++)
- {
- xi=(cos(j*0.01)*r)+x0;
- yi=(sin(j*0.01)*r)+y0;
- DrawLine(xn,yn,xi,yi); //在一系列零散的点上,两点两点之间连线,从而得到一条曲线
-
- xn=xi;
- yn=yi;
- }
- }
- /**************************************************************************************************/
- void DrawRetic(uchar x0,uchar y0,uchar x1,uchar y1)//画正方形,x0,y0为左上角坐标,x1,y1为右下角坐标
- {
- uchar i;
- for(i=0;i<=x1-x0;i++){ DrawPoint(x0+i,y0,Graphic_Draw); DrawPoint(x0+i,y1,Graphic_Draw); }
- for(i=0;i<=y1-y0;i++){ DrawPoint(x0,y0+i,Graphic_Draw); DrawPoint(x1,y0+i,Graphic_Draw); }
- }
- /**************************************************************************************************/
- void DrawTrigle(uchar x1,uchar y1,uchar x2,uchar y2,uchar x3,uchar y3)//画三角形,三个坐标为三角形顶点
- {
- DrawLine(x1,y1,x2,y2);
- DrawLine(x2,y2,x3,y3);
- DrawLine(x1,y1,x3,y3);
-
- }
- /******************************** main **********************************************************/
- void main(void)
- {
- ClearLCD();
- while(1)
- {
- ClearLCD();
- //DrawLevel();
- //DrawLine(0,63,127,0);
- DrawSineWave();
- //DrawCircle(63,32,r);
- //r-=4;
- //}
- //DrawRetic(10,10,30,30);
- //DrawTrigle(12,23,80,60,120,6);
- DrawRetic(5,5,120,60);
- }
- }
复制代码
仿真文件下载:
Proteus中单片机89C51在LCD12864上画曲线.rar
(62.69 KB, 下载次数: 196)
|