12864图形显示函数.doc_第1页
12864图形显示函数.doc_第2页
12864图形显示函数.doc_第3页
12864图形显示函数.doc_第4页
12864图形显示函数.doc_第5页
免费预览已结束,剩余19页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

/*/程序说明:本程序为12864(st7920)驱动程序,只实现了最简单的显示功能/端口设置:RS、RW、EN分别为P0口的0、1、2,数据口为P2口/用取模软件取的图形或汉字必须是逐行取的,因为本函数是在液晶上逐行打点的/*/#include#include/内含-NOP-函数#include/内含rand()函数#define uchar unsigned char#define uint unsigned int/*宏定义所需指令#define BASIC_SET 0x30#define EXTEND_SET 0x34#define DRAW_ON 0x36#define DRAW_OFF 0x34/*端口定义sbit LCD_RS = P00;sbit LCD_RW = P01;sbit LCD_EN = P02;/*变量定义/uchar dis110; /读出缓存unsigned char tu;/*短延时void delay(uint k)uint i;uchar j;for(i = 0; i k ;i +)for(j = 0; j 10 ;j +);/*ms级延时函数/*void delay_1ms(uint x)uint i,j;for(j = 0;j x; j+)for(i = 0;i 110; i+); */*12864写指令函数void write_com(uchar cmd)LCD_RS = 0;LCD_RW = 0;delay(5);LCD_EN = 1;P2 = cmd;delay(5);LCD_EN = 0;/*12864写数据函数void write_dat(uchar dat)LCD_RS = 1; LCD_RW = 0;delay(5);LCD_EN = 1;P2 = dat;delay(5);LCD_EN = 0;/*从LCD中读数据uchar read_dat(void)uchar temp;P2 = 0XFF;/释放数据线LCD_RS = 1; /数据LCD_RW = 1; / 读模式LCD_EN = 1; /E为高电平进行读数据或指令delay(1);temp = P2;LCD_EN = 0;return temp; /*/设置光标(地址)函数/参数说明:x-为行号,y为列号/*void set_cursor(unsigned char x, unsigned char y)unsigned char i;switch(x) /确定行号case 0x00: i=0x80; break;/第一行case 0x01: i=0x90; break; /第二行case 0x02: i=0x88; break; /第三行case 0x03: i=0x98; break; /第四行default : break;i = y+i; /确定列号write_com(i);/*/显示字符函数/*/*void display_char(unsigned char Alphabet)write_dat(Alphabet);/写入需要显示字符的显示码 */*/指定位置显示字符串函数/参数说明:x为行号,y为列号/*/*void display_string(unsigned char x,unsigned char y,unsigned char *Alphabet)unsigned char i=0;set_cursor(x,y);/设置显示的起始地址while(Alphabeti!=0)write_dat(Alphabeti);/写入需要显示字符的显示码i+; */*以下为GDRAM绘图部分*/*绘图显示的清屏函数(因清屏指令在画图时不能用)-注意!void gui_clear()uchar i , j , k;write_com(EXTEND_SET);/扩展指令集,8位数据传输write_com(DRAW_OFF);/绘图显示关闭for(i = 0; i 2; i +)/分上下两屏写for(j = 0; j 32; j +)write_com(0x80 + j);/写y坐标delay(1);if(i = 0) /写x坐标write_com(0x80);delay(1);else /写下半屏write_com(0x88);delay(1);for(k = 0; k 16; k +)/写一整行数据/write_dat(0x00);/写高字节/write_dat(0x00);/写低字节delay(10);write_com(DRAW_ON);/打开绘图显示write_com(BASIC_SET);/打开基本指令集/*/*清内部RAM*/void clrgdram() unsigned char x,y ; for(y=0;y64;y+) for(x=0;x16;x+) write_com(0x34); write_com(y+0x80); /行地址 write_com(x+0x80); /列地址 write_com(0x30); write_dat(0x00); write_dat(0x00); /*/*有反白显示功能的打点函数*/参数:color=1,该点填充1;color=0,该点填充白色0;/*void GUI_Point(unsigned char x,unsigned char y,unsigned char color) unsigned char x_Dyte,x_byte;/定义列地址的字节位,及在字节中的哪1位 unsigned char y_Dyte,y_byte;/定义为上下两个屏(取值为0,1),行地址(取值为031)unsigned char GDRAM_hbit,GDRAM_lbit;write_com(0x36);/扩展指令命令/*X,Y坐标互换,即普通的X,Y坐标*x_Dyte=x/16;/计算在16个字节中的哪一个x_byte=x&0x0f;/计算在该字节中的哪一位y_Dyte=y/32;/0为上半屏,1为下半屏y_byte=y&0x1f;/计算在031当中的哪一行 write_com(0x80+y_byte);/设定行地址(y坐标),即是垂直地址write_com(0x80+x_Dyte+8*y_Dyte);/设定列地址(x坐标),并通过8*y_Dyte选定上下屏,即是水平地址 read_dat();/预读取数据GDRAM_hbit= read_dat();/读取当前显示高8位数据GDRAM_lbit= read_dat();/读取当前显示低8位数据delay(1); write_com(0x80+y_byte);/设定行地址(y坐标)write_com(0x80+x_Dyte+8*y_Dyte);/设定列地址(x坐标),并通过8*y_Dyte选定上下屏delay(1);if(x_byte8)/判断其在高8位,还是在低8位if(color=1)write_dat(GDRAM_hbit|(0x01(7-x_byte);/置位GDRAM区高8位数据中相应的点else write_dat(GDRAM_hbit&(0x01(7-x_byte);/清除GDRAM区高8位数据中相应的点write_dat(GDRAM_lbit);/显示GDRAM区低8位数据 elsewrite_dat(GDRAM_hbit);if(color=1)write_dat(GDRAM_lbit|(0x01(15-x_byte);/置位GDRAM区高8位数据中相应的点else write_dat(GDRAM_lbit&(0x01(15-x_byte);/清除GDRAM区高8位数据中相应的点 write_com(0x30);/恢复到基本指令集 /*(给定坐标并打点的)任意位置打点函数/*void lcd_set_dot(uchar x,uchar y)uchar x_byte,x_bit;/确定在坐标的那一字节哪一位uchar y_ping , y_bit;/确定在坐标的哪一屏哪一行uchar tmph , tmpl;/定义两个临时变量,用于存放读出来的数据write_com(EXTEND_SET);/扩展指令集write_com(DRAW_OFF);/绘图显示关闭x_byte = x / 16;/算出在哪一字节,注意一个地址是16位的x_bit = x % 16;/& 0x0f;/算出在哪一位y_ping = y / 32;/确定在上半屏还是下半屏,0代表上半屏,1代表下半屏y_bit = y % 32;/& 0x1f;/确定在第几行write_com(0X80 + y_bit);/先写垂直地址(最高位必须)write_com(0x80 + x_byte + 8 * y_ping);/水平坐标,下半屏坐标起始地址为0x88,(+8*y_ping)就是用来确定上半屏还是下半屏read_dat();/预读取数据tmph = read_dat();/读取当前显示高8位数据tmpl = read_dat();/读取当前显示低8位数据delay(1);write_com(0x80 + y_bit);/读操作会改变AC,所以重新设置一下write_com(0x80 + x_byte + 8 * y_ping);delay(1);if(x_bit 8)write_dat(tmph | (0x01 (7 - x_bit);/写高字节,因为坐标是从左向右的,GDRAM高位在左,低位在右write_dat(tmpl);/原低位数据送回elsewrite_dat(tmph);/原高位数据送回write_dat(tmpl | (0x01 x1)bak = x1;x1 = x0;x0 = bak;dolcd_set_dot(x0 , y);/从左到右逐点显示x0 +;while(x1 = x0); */*画竖直线函数*/x为起始点和终点的水平坐标,y0、y1为垂直坐标*/*/*void gui_rline(uchar x, uchar y0, uchar y1)uchar bak;/用于对两个数互换的中间变量,使y1为大值if(y0 y1)bak = y1;y1 = y0;y0 = bak;dolcd_set_dot(x , y0);/从上到下逐点显示y0 +;while(y1 = y0); */*任意两点间画直线*/x0、y0为起始点坐标,x1、y1为终点坐标*/*/*void gui_line(uchar x0 , uchar y0 , uchar x1 , uchar y1)char dx;/直线x轴差值char dy;/直线y轴差值char dx_sym;/x轴增长方向,为-1时减值方向,为1时增值方向char dy_sym;/y轴增长方向,为-1时减值方向,为1时增值方向char dx_x2;/dx*2值变量,用于加快运算速度char dy_x2;/dy*2值变量,用于加快运算速度char di; /决策变量if(x0 = x1)/判断是否为垂直线gui_rline(x0 , y0 , y1);/画垂直线return;if(y0 = y1)/判断是否为水平线gui_hline(x0 , x1 , y0);/画水平线return;dx = x1 - x0;/求取两点之间的差值dy = y1 - y0;/判断增长方向,或是否为水平线、垂直线、点if(dx 0)/判断x轴方向dx_sym = 1;elseif(dx 0)/判断y轴方向dy_sym = 1;elseif(dy = dy)/对于dx=dy,使用x轴为基准di = dy_x2 - dx;while(x0 != x1)lcd_set_dot(x0,y0);x0 +=dx_sym;if(di 0)di += dy_x2;/计算出下一步的决策值elsedi += dy_x2 - dx_x2;y0 += dy_sym;lcd_set_dot(x0, y0);/显示最后一点else /对于dxdy使用y轴为基准di = dx_x2 - dy;while(y0 != y1)lcd_set_dot(x0, y0);y0 += dy_sym;if(di 50) with = 50; dx = x1-x0;/ 求取两点之间的差值dy = y1-y0; wx = with/2;wy = with-wx-1; /判断增长方向,或是否为水平线、垂直线、点 if(dx0)/ 判断x轴方向 dx_sym = 1;/ dx0,设置dx_sym=1else if(dx0) dx_sym = -1;/ dx0,设置dx_sym=-1else /dx=0,画垂直线,或一点wx = x0-wx;if(wx=wy) break;wx+;return; if(dy0)/ 判断y轴方向 dy_sym = 1;/ dy0,设置dy_sym=1else if(dy0) dy_sym = -1;/ dy0,设置dy_sym=-1else /dy=0,画水平线,或一点wx = y0-wx;if(wx=wy) break;wx+;return; / 将dx、dy取绝对值dx = dx_sym * dx;dy = dy_sym * dy; /计算2倍的dx及dy值dx_x2 = dx*2;dy_x2 = dy*2; /使用Bresenham法进行画直线if(dx=dy)/ 对于dx=dy,则使用x轴为基准 di = dy_x2 - dx;while(x0!=x1) /x轴向增长,则宽度在y方向,即画垂直线draw_a = y0-wx;if(draw_a0) draw_a = 0;draw_b = y0+wy;gui_rline(x0, draw_a, draw_b);x0 += dx_sym;if(di0) di += dy_x2;/ 计算出下一步的决策值else di += dy_x2 - dx_x2;y0 += dy_sym;draw_a = y0-wx;if(draw_a0) draw_a = 0;draw_b = y0+wy;gui_rline(x0, draw_a, draw_b);else/ 对于dxdy,则使用y轴为基准 di = dx_x2 - dy;while(y0!=y1) /y轴向增长,则宽度在x方向,即画水平线draw_a = x0-wx;if(draw_a0) draw_a = 0;draw_b = x0+wy;gui_hline(draw_a, y0, draw_b); y0 += dy_sym;if(di0) di += dx_x2;else di += dx_x2 - dy_x2;x0 += dx_sym;draw_a = x0-wx;if(draw_a x1)i = x0;x0 = x1;x1 = i;if(y0 y1)i = y0;y0 = y1;y1 = i;/*判断是否是直线*/*if(y0 = y1)/画水平线gui_hline(x0 , x1 , y0);return;if(x0 = x1)/画竖直线gui_rline(x0 , y0 , y1);return;while(y0 127)/横轴超出液晶边界return;if(y0 + with) 63)return;gui_rectangle(x0 , y0 , x0 + with , y0 + with); */*画填充正方形函数*/x0、y0为正方形左上角坐标,with正方形边长*/*/*void gui_square_fill(uchar x0 , uchar y0 , uchar with)if(with = 0)return;if(x0 + with) 127)/横轴超出液晶边界return;if(y0 + with) 63)return;gui_rectangle_fill(x0 , y0 , x0 + with , y0 + with);*/*画圆函数*/x0、y0为圆心坐标,r为圆的半径*/*/*void gui_circle(uchar x0 , uchar y0 , uchar r)char a , b;char di;if(r 31 | r = 0)/圆大于液晶屏或者没半径则返回return;a = 0;b = r;di = 3 - 2 * r;/判断下个点位置的标志while(a = b)lcd_set_dot( x0 - b , y0 - a);/3lcd_set_dot( x0 + b , y0 - a); /0lcd_set_dot( x0 - a , y0 + b);/1lcd_set_dot( x0 - b , y0 - a); /7lcd_set_dot( x0 - a , y0 - b); /2lcd_set_dot( x0 + b , y0 + a); /4lcd_set_dot( x0 + a , y0 - b); /5lcd_set_dot( x0 + a , y0 + b); /6lcd_set_dot( x0 - b , y0 + a);a +;/*使用bresenham算法画圆*if(di 1; center_y = (y0 + y1) 1; /* 计算出椭圆的半径,x轴半径和y轴半径 if(x0 x1) radius_x = (x0 - x1) 1; else radius_x = (x1 - x0) 1; if(y0 y1) radius_y = (y0 - y1) 1; else radius_y = (y1 - y0) 1; /* 计算半径平方值 radius_xx = radius_x * radius_x; radius_yy = radius_y * radius_y; /* 计算半径平方值乘2值 radius_xx2 = radius_xx1; radius_yy2 = radius_yy1; /* 初始化画图变量 xx = 0; yy = radius_y; di = radius_yy2 + radius_xx - radius_xx2*radius_y ;/ 初始化决策变量 /* 计算出椭圆y轴上的两个端点坐标,作为作图起点 draw_x0 = draw_x1 = draw_x2 = draw_x3 = center_x; draw_y0 = draw_y1 = center_y + radius_y; draw_y2 = draw_y3 = center_y - radius_y; lcd_set_dot(draw_x0,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论