【STM32+HAL】地表最强高刷OLED显示配置【I2C】

2024-03-19 03:04

本文主要是介绍【STM32+HAL】地表最强高刷OLED显示配置【I2C】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

(超长代码预警,,,建议使用客户端浏览,,,)

一、前言

有关初级I2C版OLED配置,详见【STM32+HAL】OLED显示初始化配置

有关SPI版OLED配置,详见【STM32+HAL】七针OLED(SSD1306)配置(SPI版)

二、实现功能

开启DMA实现OLED超高刷新率超高速率传输

三、HAL库配置步骤

1、开启I2C

2、开启DMA

3、开启中断

至此,HAL库配置完毕

四、Keil填写代码

1、oled.c

/*此c文件用于画图和字符操作(高级操作)(主要)由打点为基础再 线 折线再画和填充 矩形 三角形 圆 椭圆 圆角矩形然后是 图片 字符 字符串最后是 汉字
*/#include "oled_draw.h"
#include "stdlib.h"
#include "math.h"//画图光标
static int  _pointx=0;
static int 	_pointy=0;//以下4个函数是对当前光标的设置 供以下绘制函数调用 用户不直接使用
void MoveTo(int x,int y)
{_pointx=x;_pointy=y;
}
TypeXY GetXY(void)
{TypeXY m;m.x=_pointx;m.y=_pointy;return m;
}
int GetX(void)
{return _pointx;
}
int GetY(void)
{return _pointy;
}
void LineTo(int x,int y)
{DrawLine(_pointx,_pointy,x,y);_pointx=x;_pointy=y;
}void OLED_Clean(void)//清屏
{extern unsigned char ScreenBuffer[SCREEN_PAGE_NUM][SCREEN_COLUMN];uint16_t i;for (i = 0; i < SCREEN_PAGE_NUM * SCREEN_COLUMN; ++i){ScreenBuffer[0][i] = 0;}OLED_FILL(ScreenBuffer[0]);
}//显示一个字符
//关于字体尺寸及使用请看SetFontSize()的注释
//当size=0时 x为第几行 y为第几列
void OLED_ShowChar(int x, int y, unsigned char c, unsigned int size)
{int i,j;unsigned char draw_background,bg,a,b,color;//	size=GetFontSize();		//字体尺寸color=GetDrawColor();	//字体颜色 1白0黑bg=GetTextBkMode();		//写字的时候字的背景的颜色 1白0黑draw_background= bg != color;	//这两个颜色要不一样字才看得到if(!size)//默认字符大小{if((x>6) || (y>SCREEN_COLUMN-8))return;c=c-' ';			//得到偏移后的位置for(i=0;i<8;i++)WriteByteBuffer(x,y+i,F8X16[c*16+i]);for(i=0;i<8;i++)WriteByteBuffer(x+1,y+i,F8X16[c*16+i+8]);}else//使用原作粗体字符{//判断一个字符的上下左右是否超出边界范围if ((x >= SCREEN_COLUMN) ||         // Clip right(y >= SCREEN_ROW) ||        		// Clip bottom((x + 5 * size - 1) < 0) ||   		// Clip left((y + 8 * size - 1) < 0)    		// Clip top)return;for (i=0; i<6; i++){int line;//一个字符在font5x7中由一行6个char表示//line为这个字符的第某行内容if (i == 5)line = 0x0;elseline = pgm_read_byte(font5x7+(c*5)+i);for (j=0; j<8; j++){unsigned char draw_color = (line & 0x1) ? color : bg;//目前需要填充的颜色是0 就是背景色 1就是字体色//不同号大小的字体只是最基础字体的放大倍数 这点要注意//比如基础字是1个像素 放大后就是4个像素 再就是9个像素 达到马赛克的放大效果if (draw_color || draw_background)for ( a = 0; a < size; a++ )for ( b = 0; b < size; b++ )SetPointBuffer(x + (i * size) + a, y + (j * size) + b, draw_color);line >>= 1;}}}
}//显示字符串 就是显示多次显示字符
void OLED_ShowString(int x, int y,char *str, unsigned int size)
{unsigned char j=0,tempx=x,tempy=y;
//	unsigned char size=GetFontSize();if(!size)//默认字体{while (str[j]!='\0'){OLED_ShowChar(x,y,str[j],size);y+=8;if(y>120){y=0;x+=2;}j++;}}else//使用原作粗体字符{while (str[j]!='\0'){if(str[j]=='\n'){tempy+=8*size;tempx=x;j++;continue;}OLED_ShowChar(tempx,tempy,str[j],size);tempx+=size*6;j++;}}
}//显示数字 就是多次显示数字的字符
void OLED_ShowNum(unsigned char x,unsigned char y,unsigned int num,unsigned char len, unsigned int size)
{unsigned char t,temp;unsigned char enshow=0;
//	unsigned char size=GetFontSize();if(!size){for(t=0;t<len;t++){temp=(num/oled_pow(10,len-t-1))%10;if(enshow==0&&t<(len-1)){if(temp==0){OLED_ShowChar(x,y+8*t,' ',size);continue;}elseenshow=1;}OLED_ShowChar(x,y+8*t,temp+'0',size);}}else{for(t=0;t<len;t++){temp=(num/oled_pow(10,len-t-1))%10;if(enshow==0&&t<(len-1)){if(temp==0){OLED_ShowChar(x+(size*6)*t,y,'0',size);continue;}else enshow=1;}OLED_ShowChar(x+(size*6)*t,y,temp+'0',size);}}
}//显示汉字
void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t *cn)
{uint8_t j,wordNum;if((x > 7)||(y>128-16))return;while ( *cn != '\0')	 																	//在C语言中字符串结束以‘\0’结尾{for (wordNum=0; wordNum<NUM_OFCHINESE; wordNum++){if ((CN16CHAR[wordNum].Index[0] == *cn)&&(CN16CHAR[wordNum].Index[1] == *(cn+1)))   //查询要写的字在字库中的位置{for (j=0; j<32; j++) 															//写一个字{if (j == 16)	 															//由于16X16用到两个Y坐标,当大于等于16时,切换坐标{x++;}WriteByteBuffer(x,y+(j%16),CN16CHAR[wordNum].Msk[j]);}y += 16;x--;if(y > (128-16)){x += 2;y = 0;}}}cn += 2;																																							//此处打完一个字,接下来寻找第二个字}
}//绘制一个点
void DrawPixel(int x,int y)
{SetPointBuffer(x,y,GetDrawColor());
}//得到某个点的颜色
Type_color GetPixel(int x,int y)
{if(GetPointBuffer(x,y))return pix_white;elsereturn pix_black;
}//划线
//参数:起点坐标 终点坐标
void DrawLine(int x1,int y1,int x2,int y2)
{unsigned short us;unsigned short usX_Current, usY_Current;int lError_X = 0, lError_Y = 0, lDelta_X, lDelta_Y, lDistance;int lIncrease_X, lIncrease_Y;lDelta_X = x2 - x1; //计算坐标增量lDelta_Y = y2 - y1;usX_Current = x1;usY_Current = y1;if ( lDelta_X > 0 )lIncrease_X = 1; 			//设置单步正方向else if ( lDelta_X == 0 )lIncrease_X = 0;			//垂直线else{lIncrease_X = -1;			//设置单步反方向lDelta_X = - lDelta_X;}//Y轴的处理方式与上图X轴的处理方式同理if ( lDelta_Y > 0 )lIncrease_Y = 1;else if ( lDelta_Y == 0 )lIncrease_Y = 0;			//水平线else{lIncrease_Y = -1;lDelta_Y = - lDelta_Y;}//选取不那么陡的方向依次画点if ( lDelta_X > lDelta_Y )lDistance = lDelta_X;elselDistance = lDelta_Y;//依次画点 进入缓存区 画好后再刷新缓冲区就好啦for ( us = 0; us <= lDistance + 1; us ++ )					//画线输出{SetPointBuffer(usX_Current,usY_Current,GetDrawColor());	//画点lError_X += lDelta_X ;lError_Y += lDelta_Y ;if ( lError_X > lDistance ){lError_X -= lDistance;usX_Current += lIncrease_X;}if ( lError_Y > lDistance ){lError_Y -= lDistance;usY_Current += lIncrease_Y;}}
}//快速划线 专用于画横平的线 提高效率
void DrawFastHLine(int x, int y, unsigned char w)
{int end = x+w;int a;Type_color color =GetDrawColor();for ( a = MAX(0,x); a < MIN(end,SCREEN_COLUMN); a++){SetPointBuffer(a,y,color);}
}//快速划线 专用于画竖直的线 提高效率
void DrawFastVLine(int x, int y, unsigned char h)
{int end = y+h;int a;Type_color color =GetDrawColor();for (a = MAX(0,y); a < MIN(end,SCREEN_ROW); a++)SetPointBuffer(x,a,color);
}//绘制折线 开始和转折点的坐标 总点个数
void DrawPolyLineTo(const TypeXY *points,int num)
{int i=0;MoveTo(points[0].x,points[0].y);for(i=1;i<num;i++)LineTo(points[i].x,points[i].y);
}//使用对角点填充矩形
void DrawRect1(int left,int top,int right,int bottom)
{DrawLine ( left, top, right, top );DrawLine ( left, bottom , right , bottom );DrawLine ( left, top, left, bottom );DrawLine ( right , top, right , bottom );
}//功能:使用对角点填充矩形
void DrawFillRect1(int left,int top,int right,int bottom)
{DrawRect1(left,top,right,bottom);FillRect(left+1,top+1,right-left-1,bottom-top-1);
}//左上角坐标 矩形宽高
void DrawRect2(int left,int top,int width,int height)
{DrawLine ( left, top, left+width-1, top );DrawLine ( left, top+height-1 , left+width-1 , top+height-1 );DrawLine ( left, top, left, top+height-1);DrawLine ( left+width-1 , top, left+width-1 , top+height-1);
}//填充矩形
void DrawFillRect2(int left,int top,int width,int height)
{//先用上面的函数画外框DrawRect2(left,top,width,height);//然后填充实心FillRect(left+1,top+1,width-1,height-1);
}//画圆
void DrawCircle ( int usX_Center, int usY_Center, int usRadius)
{short sCurrentX, sCurrentY;short sError;sCurrentX = 0; sCurrentY = usRadius;sError = 3 - ( usRadius << 1 );     //判断下个点位置的标志while ( sCurrentX <= sCurrentY ){//此处画圆打点的方法和画圆角矩形的四分之一圆弧的函数有点像SetPointBuffer ( usX_Center + sCurrentX, usY_Center + sCurrentY	,GetDrawColor());             //1,研究对象SetPointBuffer ( usX_Center - sCurrentX, usY_Center + sCurrentY ,GetDrawColor());             //2SetPointBuffer ( usX_Center - sCurrentY, usY_Center + sCurrentX ,GetDrawColor());             //3SetPointBuffer ( usX_Center - sCurrentY, usY_Center - sCurrentX ,GetDrawColor());             //4SetPointBuffer ( usX_Center - sCurrentX, usY_Center - sCurrentY ,GetDrawColor());             //5SetPointBuffer ( usX_Center + sCurrentX, usY_Center - sCurrentY ,GetDrawColor());             //6SetPointBuffer ( usX_Center + sCurrentY, usY_Center - sCurrentX ,GetDrawColor());             //7SetPointBuffer ( usX_Center + sCurrentY, usY_Center + sCurrentX ,GetDrawColor());             //0sCurrentX ++;if ( sError < 0 )sError += 4 * sCurrentX + 6;else{sError += 10 + 4 * ( sCurrentX - sCurrentY );sCurrentY --;}}
}//填充圆
void DrawFillCircle( int usX_Center, int usY_Center, int r)
{DrawFastVLine(usX_Center, usY_Center-r, 2*r+1);DrawFillCircleHelper(usX_Center,usY_Center, r, 3, 0);
}//画部分圆
//圆心坐标 半径 4份圆要画哪一份或哪几份
void DrawCircleHelper(int x0, int y0, unsigned char r, unsigned char cornername)
{int f = 1 - r;int ddF_x = 1;int ddF_y = -2 * r;int x = 0;int y = r;Type_color color=GetDrawColor();while (x<y){if (f >= 0){y--;ddF_y += 2;f += ddF_y;}x++;ddF_x += 2;f += ddF_x;if (cornername & 0x4)//右上{//此处画圆的方式是交替打点 从2边打到中间 最终x<y就打完点跳出循环SetPointBuffer(x0 + x, y0 + y,color);SetPointBuffer(x0 + y, y0 + x,color);}if (cornername & 0x2)//右下{SetPointBuffer(x0 + x, y0 - y, color);SetPointBuffer(x0 + y, y0 - x, color);}if (cornername & 0x8)//左上{SetPointBuffer(x0 - y, y0 + x, color);SetPointBuffer(x0 - x, y0 + y, color);}if (cornername & 0x1)//左下{SetPointBuffer(x0 - y, y0 - x, color);SetPointBuffer(x0 - x, y0 - y, color);}}
}//填充2个四分之一圆和中间的矩形
//此函数专用于画圆角矩形
//右上四分之一圆或左下四分之一圆的圆心 半径 中间矩形的高
void DrawFillCircleHelper(int x0, int y0, unsigned char r, unsigned char cornername, int delta)
{int f = 1 - r;int ddF_x = 1;int ddF_y = -2 * r;int x = 0;int y = r;Type_color color=GetDrawColor();while (x < y){if (f >= 0){y--;ddF_y += 2;f += ddF_y;}x++;ddF_x += 2;f += ddF_x;if (cornername & 0x1)//填充右边的2个四分之一圆和中间的矩形{DrawFastVLine(x0+x, y0-y, 2*y+1+delta);DrawFastVLine(x0+y, y0-x, 2*x+1+delta);}if (cornername & 0x2)//填充左边的2个四分之一圆和中间的矩形{DrawFastVLine(x0-x, y0-y, 2*y+1+delta);DrawFastVLine(x0-y, y0-x, 2*x+1+delta);}}
}//绘制一个圆弧
//x,y:圆弧中心坐标
//r:圆弧的半径
//angle_start:圆弧起始角度
//angle_end:圆弧终止角度
//注意:慎用此方法,此方法还需优化。
void DrawArc(int x,int y,unsigned char r,int angle_start,int angle_end)
{float i=0;TypeXY m,temp;temp=GetXY();SetRotateCenter(x,y);SetAnggleDir(0);if(angle_end>360)angle_end=360;SetAngle(0);m=GetRotateXY(x,y+r);MoveTo(m.x,m.y);for(i=angle_start;i<angle_end;i+=5){SetAngle(i);m=GetRotateXY(x,y+r);LineTo(m.x,m.y);}LineTo(x+r,y);MoveTo(temp.x,temp.y);
}void DrawFillArc(int x,int y,unsigned char r,int angle_start,int angle_end)
{return;
}//画圆角矩形
void DrawRoundRect(int x, int y, unsigned char w, unsigned char h, unsigned char r)
{//画出边缘 因为边缘是直线 所以专用高效率函数DrawFastHLine(x+r, y, w-2*r); 		// TopDrawFastHLine(x+r, y+h-1, w-2*r); 	// BottomDrawFastVLine(x, y+r, h-2*r); 		// LeftDrawFastVLine(x+w-1, y+r, h-2*r); 	// Right//画出四个圆角DrawCircleHelper(x+r, y+r, r, 1);DrawCircleHelper(x+w-r-1, y+r, r, 2);DrawCircleHelper(x+w-r-1, y+h-r-1, r, 4);DrawCircleHelper(x+r, y+h-r-1, r, 8);
}//画实心圆角矩形
void DrawfillRoundRect(int x, int y, unsigned char w, unsigned char h, unsigned char r)
{//画实心矩形DrawFillRect2(x+r, y, w-2*r, h);//再填充左右两边DrawFillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1);	//右上角的圆心DrawFillCircleHelper(x+r, y+r, r, 2, h-2*r-1);		//左下角的圆心
}//画椭圆
//圆心 2个轴长
void DrawEllipse(int xCenter,int yCenter,int Rx,int Ry)
{int Rx2=Rx*Rx;int Ry2=Ry*Ry;int twoRx2=2*Rx2;int twoRy2=2*Ry2;int p;int x=0;int y=Ry;int px = 0;int py = twoRx2*y;//椭圆最下面的点SetPointBuffer(xCenter+x,yCenter+y,GetDrawColor());//因为此时x=0 俩个点为同一个 原作这样写的 那就这样吧SetPointBuffer(xCenter-x,yCenter+y,GetDrawColor());//椭圆最上面的点SetPointBuffer(xCenter+x,yCenter-y,GetDrawColor());SetPointBuffer(xCenter-x,yCenter-y,GetDrawColor());//Region?1 画出上下的线条 说实话我也没看懂了 算法大佬p=(int)(Ry2-Rx2*Ry+0.25*Rx2);while(px<py){x++;px+=twoRy2;if(p<0)p+=Ry2+px;else{y--;py-=twoRx2;p+=Ry2+px-py;}SetPointBuffer(xCenter+x,yCenter+y,GetDrawColor());SetPointBuffer(xCenter-x,yCenter+y,GetDrawColor());SetPointBuffer(xCenter+x,yCenter-y,GetDrawColor());SetPointBuffer(xCenter-x,yCenter-y,GetDrawColor());}//Region?2p=(int)(Ry2*(x+0.5)*(x+0.5)+Rx2*(y-1)*(y-1)-Rx2*Ry2);while(y>0){y--;py-=twoRx2;if(p>0)p+=Rx2-py;else{x++;px+=twoRy2;p+=Rx2-py+px;}SetPointBuffer(xCenter+x,yCenter+y,GetDrawColor());SetPointBuffer(xCenter-x,yCenter+y,GetDrawColor());SetPointBuffer(xCenter+x,yCenter-y,GetDrawColor());SetPointBuffer(xCenter-x,yCenter-y,GetDrawColor());}
}//填充一个椭圆 参数同上
void DrawFillEllipse(int x0, int y0,int rx,int ry)
{int x, y;int xchg, ychg;int err;int rxrx2;int ryry2;int stopx, stopy;rxrx2 = rx;rxrx2 *= rx;rxrx2 *= 2;ryry2 = ry;ryry2 *= ry;ryry2 *= 2;x = rx;y = 0;xchg = 1;xchg -= rx;xchg -= rx;xchg *= ry;xchg *= ry;ychg = rx;ychg *= rx;err = 0;stopx = ryry2;stopx *= rx;stopy = 0;while( stopx >= stopy ){DrawFastVLine( x0+x, y0-y, y+1);DrawFastVLine( x0-x, y0-y, y+1);DrawFastVLine( x0+x, y0, y+1);DrawFastVLine( x0-x, y0, y+1);y++;stopy += rxrx2;err += ychg;ychg += rxrx2;if ( 2*err+xchg > 0 ){x--;stopx -= ryry2;err += xchg;xchg += ryry2;}}x = 0;y = ry;xchg = ry;xchg *= ry;ychg = 1;ychg -= ry;ychg -= ry;ychg *= rx;ychg *= rx;err = 0;stopx = 0;stopy = rxrx2;stopy *= ry;while( stopx <= stopy ){DrawFastVLine( x0+x, y0-y, y+1);DrawFastVLine( x0-x, y0-y, y+1);DrawFastVLine( x0+x, y0, y+1);DrawFastVLine( x0-x, y0, y+1);x++;stopx += ryry2;err += xchg;xchg += ryry2;if ( 2*err+ychg > 0 ){y--;stopy -= rxrx2;err += ychg;ychg += rxrx2;}}
}//功能:绘制一个矩形内切椭圆
//x0,y0:矩形左上角坐标
//x1,y1:矩形右下角坐标
void DrawEllipseRect( int x0, int y0, int x1, int y1)
{int a = abs(x1 - x0);int b = abs(y1 - y0);	//get diametersint b1 = b&1;long dx = 4*(1-a)*b*b;long dy = 4*(b1+1)*a*a;long err = dx+dy+b1*a*a;long e2;if (x0 > x1) { x0 = x1; x1 += a; }if (y0 > y1) { y0 = y1; }y0 += (b+1)/2;y1 = y0-b1;a *= 8*a;b1 = 8*b*b;do {DrawPixel( x1, y0);DrawPixel( x0, y0);DrawPixel( x0, y1);DrawPixel( x1, y1);e2 = 2*err;if (e2 >= dx) {x0++;x1--;err += dx += b1;}if (e2 <= dy) {y0++;y1--;err += dy += a;}} while (x0 <= x1);while (y0-y1 < b) {DrawPixel( x0-1, y0);DrawPixel( x1+1, y0++);DrawPixel( x0-1, y1);DrawPixel( x1+1, y1--);}
}//画三角形
void DrawTriangle(unsigned char x0, unsigned char y0, unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2)
{//很简单  就是画3条任意线DrawLine(x0, y0, x1, y1);DrawLine(x1, y1, x2, y2);DrawLine(x2, y2, x0, y0);
}//填充三角形
void DrawFillTriangle(int x0, int y0, int x1, int y1, int x2, int y2)
{int a, b, y, last;int dx01, dy01,dx02,dy02,dx12,dy12,sa = 0,sb = 0;Type_color tmpcolor;tmpcolor =GetDrawColor();SetDrawColor(GetFillColor());if (y0 > y1){SWAP(y0, y1); SWAP(x0, x1);}if (y1 > y2){SWAP(y2, y1); SWAP(x2, x1);}if (y0 > y1){SWAP(y0, y1); SWAP(x0, x1);}if(y0 == y2){a = b = x0;if(x1 < a){a = x1;}else if(x1 > b){b = x1;}if(x2 < a){a = x2;}else if(x2 > b){b = x2;}DrawFastHLine(a, y0, b-a+1);return;}dx01 = x1 - x0,dy01 = y1 - y0,dx02 = x2 - x0,dy02 = y2 - y0,dx12 = x2 - x1,dy12 = y2 - y1,sa = 0,sb = 0;if (y1 == y2){last = y1;   // Include y1 scanline}else{last = y1-1; // Skip it}for(y = y0; y <= last; y++){a   = x0 + sa / dy01;b   = x0 + sb / dy02;sa += dx01;sb += dx02;if(a > b){SWAP(a,b);}DrawFastHLine(a, y, b-a+1);}sa = dx12 * (y - y1);sb = dx02 * (y - y0);for(; y <= y2; y++){a   = x1 + sa / dy12;b   = x0 + sb / dy02;sa += dx12;sb += dx02;if(a > b){SWAP(a,b);}DrawFastHLine(a, y, b-a+1);}SetDrawColor(tmpcolor);
}//画一幅画,PCtoLCD2002参数请选择[阴码 列行式 逆向]
//起点坐标x y 图像取模数组 图像宽高w h
void DrawBitmap(int x, int y, const unsigned char *bitmap, unsigned char w, unsigned char h)
{int iCol,a;int yOffset = abs(y) % 8;int sRow = y / 8;int rows = h/8;if(x+w < 0 || x > SCREEN_COLUMN-1 || y+h < 0 || y > SCREEN_ROW-1)return;if(y < 0){sRow--;yOffset = 8 - yOffset;}if(h%8!=0) rows++;for(a = 0; a < rows; a++){int bRow = sRow + a;if(bRow > (SCREEN_ROW/8)-1) break;if(bRow > -2){for (iCol = 0; iCol<w; iCol++){if (iCol + x > (SCREEN_COLUMN-1)) break;if (iCol + x >= 0){if (bRow >= 0){if(GetDrawColor() == pix_white){unsigned char temp = ReadByteBuffer(bRow,x + iCol);temp|=pgm_read_byte(bitmap+(a*w)+iCol) << yOffset;WriteByteBuffer(bRow,x + iCol,temp);}else if(GetDrawColor() == pix_black){unsigned char temp = ReadByteBuffer(bRow,x + iCol);temp&=~(pgm_read_byte(bitmap+(a*w)+iCol) << yOffset);WriteByteBuffer(bRow,x + iCol,temp);}else{unsigned char temp = ReadByteBuffer(bRow,x + iCol);temp^=(pgm_read_byte(bitmap+(a*w)+iCol) << yOffset);WriteByteBuffer(bRow,x + iCol,temp);}}if (yOffset && bRow<(SCREEN_ROW/8)-1 && bRow > -2){if(GetDrawColor() == pix_white){unsigned char temp = ReadByteBuffer(bRow+1,x + iCol);temp|=pgm_read_byte(bitmap+(a*w)+iCol) >> (8-yOffset);WriteByteBuffer(bRow+1,x + iCol,temp);}else if (GetDrawColor() == pix_black){unsigned char temp = ReadByteBuffer(bRow+1,x + iCol);temp&=~(pgm_read_byte(bitmap+(a*w)+iCol) >> (8-yOffset));WriteByteBuffer(bRow+1,x + iCol,temp);}else{unsigned char temp = ReadByteBuffer(bRow+1,x + iCol);temp^=pgm_read_byte(bitmap+(a*w)+iCol) >> (8-yOffset);WriteByteBuffer( bRow+1,x + iCol,temp);}}}}}}
}//画一幅画,PCtoLCD2002参数请选择[阴码 逐行式 逆向],具体描述参见[draw_api.h]
//起点坐标x y 图像取模数组 图像宽高w h
void DrawXBitmap(int x, int y, const unsigned char *bitmap, unsigned char w, unsigned char h)
{// no need to dar at all of we're offscreenint xi, yi, byteWidth = (w + 7) / 8;if (x + w < 0 || x > SCREEN_COLUMN - 1 || y + h < 0 || y > SCREEN_ROW - 1)return;for (yi = 0; yi < h; yi++) {for (xi = 0; xi < w; xi++ ) {if (pgm_read_byte(bitmap + yi * byteWidth + xi / 8) & (1 << (xi & 7))) {SetPointBuffer(x + xi, y + yi, GetDrawColor());}}}
}

2、oled_drive.c

/*图形库原理:其实就是对一个数组进行操作,数组操作完成之后,直接将整个数组刷新到屏幕上因此此c文件用于配置oled底层 用于单片机与oled的直接且唯一通信移植此图形库主要完善单片机与OLED的通信:SPI_Configuration() 	配置通信引脚WriteCmd()      		写命令WriteDat()      		写数据OledTimeMsFunc()  oled_config中的函数 为系统提供时基此例程仅演示SPI通信方式 需要更改其他通信方式请在[oled_config.h]修改
*/#include "oled_driver.h"
#include "math.h"
#include "string.h"#if (TRANSFER_METHOD == HW_IIC)	//1.硬件IICvoid I2C_Configuration(void){}/**@brief  I2C_WriteByte,向OLED寄存器地址写一个byte的数据@param  addr:寄存器地址data:要写入的数据@retval 无*/
void I2C_WriteByte(uint8_t addr, uint8_t data)
{extern I2C_HandleTypeDef hi2c1;HAL_I2C_Mem_Write(&hi2c1, OLED_ADDRESS, addr, I2C_MEMADD_SIZE_8BIT, &data, 1, 10);
}void WriteCmd(unsigned char cmd)//写命令
{I2C_WriteByte(0x00, cmd);
}void WriteDat(unsigned char dat)//写数据
{I2C_WriteByte(0x40, dat);
}#endif //(TRANSFER_METHOD ==HW_IIC)void OLED_Init(void)
{WriteCmd(0xAE); //display offWriteCmd(0x20); //Set Memory Addressing Mode
//	WriteCmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,InvalidWriteCmd(0x00); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,InvalidWriteCmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7WriteCmd(0xc8); //Set COM Output Scan DirectionWriteCmd(0x00); //---set low column addressWriteCmd(0x10); //---set high column addressWriteCmd(0x40); //--set start line addressWriteCmd(0x81); //--set contrast control registerWriteCmd(0xff); //亮度调节 0x00~0xffWriteCmd(0xa1); //--set segment re-map 0 to 127WriteCmd(0xa6); //--set normal displayWriteCmd(0xa8); //--set multiplex ratio(1 to 64)WriteCmd(0x3F); //WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM contentWriteCmd(0xd3); //-set display offsetWriteCmd(0x00); //-not offsetWriteCmd(0xd5); //--set display clock divide ratio/oscillator frequencyWriteCmd(0xf0); //--set divide ratioWriteCmd(0xd9); //--set pre-charge periodWriteCmd(0x22); //WriteCmd(0xda); //--set com pins hardware configurationWriteCmd(0x12);WriteCmd(0xdb); //--set vcomhWriteCmd(0x20); //0x20,0.77xVccWriteCmd(0x8d); //--set DC-DC enableWriteCmd(0x14); //WriteCmd(0xaf); //--turn on oled panelOLED_Clean();
}void OLED_ON(void)
{WriteCmd(0X8D);  //设置电荷泵WriteCmd(0X14);  //开启电荷泵WriteCmd(0XAF);  //OLED唤醒
}void OLED_OFF(void)
{WriteCmd(0X8D);  //设置电荷泵WriteCmd(0X10);  //关闭电荷泵WriteCmd(0XAE);  //OLED休眠
}void OLED_FILL(unsigned char BMP[])
{unsigned char *p;p = BMP;extern I2C_HandleTypeDef hi2c1;while(hi2c1.State != HAL_I2C_STATE_READY);HAL_I2C_Mem_Write_DMA(&hi2c1, OLED_ADDRESS, 0x40, I2C_MEMADD_SIZE_8BIT, p, SCREEN_PAGE_NUM * SCREEN_PAGEDATA_NUM);
}/*此c文件(原oled_config.c)用于配置oled例如初始化oled引脚 刷新oled注意!!!如需演示动画效果 OledTimeMsFunc()需放入1ms中断等中1ms调用一次为库提供时间基准 原作是放入滴答定时器中
*/extern unsigned char ScreenBuffer[SCREEN_PAGE_NUM][SCREEN_COLUMN];
extern unsigned char TempBuffer[SCREEN_PAGE_NUM][SCREEN_COLUMN];
unsigned int OledTimeMs=0;												//时间基准//将ScreenBuffer屏幕缓存的内容显示到屏幕上
void UpdateScreenBuffer(void)
{OLED_FILL(ScreenBuffer[0]);
}
//将TempBuffer临时缓存的内容显示到屏幕上
void UpdateTempBuffer(void)
{OLED_FILL(TempBuffer[0]);
}//
//请将此函数放入1ms中断里,为图形提供时基
//系统时间基准主要用于FrameRateUpdateScreen()中固定帧率刷新屏幕
void OledTimeMsFunc(void)
{if(OledTimeMs != 0x00){OledTimeMs--;}
}/*此c文件用于画图的底层操作(基础操作)全屏操作包括 初始化 清屏 更新数组到屏幕画线 点 旋转 封闭图形的填充 时间的基准更新
*///#include "oled_basic.h"
//#include "oled_driver.h"
//#include "math.h"
//#include "string.h"TypeRoate _RoateValue={{0,0},0,1};
static unsigned char _BitTableS[8]={0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};
static void Rotate(int x0,int y0,int*x,int*y,double angle,int direction);
extern unsigned int OledTimeMs;/*此c文件用于对颜色进行操作在这里主要是画线线条(一般为白)和填充(一般为白)的颜色(在oled.font中还有一个字体背景的颜色(一般为黑))在划线画图和打点时都会访问此文件函数获取打点的颜色
*///如有需要还可以自己迭代字体颜色 文字背景颜色等
static Type_color _Draw=pix_white;
static Type_color _fill=pix_white;void SetDrawColor(Type_color value)	//就是划线 线条的颜色
{_Draw=value;
}
Type_color GetDrawColor(void)
{return _Draw;
}void SetFillcolor(Type_color value)	//就是填充 实心图形内的颜色
{_fill=value;
}
Type_color GetFillColor(void)
{return _fill;
}//清屏
void ClearScreen(void)
{ClearScreenBuffer(0);
}
//更新屏幕 注意此处特指刷新屏幕数组而不是临时数组
void UpdateScreen(void)
{UpdateScreenDisplay();
}///
//给选择的缓冲区写入8位数据
void FillByte(int page,int x,unsigned  char byte)
{if(GetFillColor())WriteByteBuffer(page,x,ReadByteBuffer(page,x)|byte);elseWriteByteBuffer(page,x,ReadByteBuffer(page,x)&(~byte));
}
//给选择的缓冲区填充一个矩形
void FillRect(int x,int y,int width,int height)
{int i,j;int temp =(y+height-1)/8-y/8;	//需要填充的矩形在屏幕中所占的行数 屏幕被分为8大行if(x>SCREEN_COLUMN ||y>SCREEN_ROW)return;for(i=x; i<x+width&&i<128; i++){if( temp==0 ){FillByte(y/8,i,_BitTableS[height-1]<<(y%8));}else{//从左往右 竖向填充FillByte(y/8,i,_BitTableS[(8-y%8)-1]<<(y%8));for(j=1;j<temp;j++){FillByte(y/8+j,i,0xff);}FillByte(y/8+temp,i,_BitTableS[(height-1+y)%8]);}}
}
//画一条起点坐标为x,y 长度为height的竖线 (与DrawFastHLine()类似 不过后者是使用打点实现)
void FillVerticalLine(int x,int y,int height,int value)
{int temp =(y+height-1)/8-y/8,j;if( temp==0 ){FillByte(y/8,x,_BitTableS[height-1]<<(y%8));}else{FillByte(y/8,x,_BitTableS[(8-y%8)-1]<<(y%8));for(j=1;j<temp;j++){FillByte(y/8+j,x,0xff);}FillByte(y/8+temp,x,_BitTableS[(height-1+y)%8]);}
}//——————————————————————————————————————————————————————————————————————————————————————————————————————————
//版权声明:本文为CSDN博主「xtlisk」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
//原文链接:https://blog.csdn.net/xtlisk/article/details/51249371//点x,y绕x0,y0旋转angle弧度
float mySqrt(float x)
{float a = x;unsigned int i = *(unsigned int *)&x;i = (i + 0x3f76cf62) >> 1;x = *(float *)&i;x = (x + a / x) * 0.5;return x;
}
//开平方根函数
unsigned int sqrt_16(unsigned long M)
{unsigned int N, i;unsigned long tmp, ttp;   // 结果、循环计数if (M == 0)               // 被开方数,开方结果也为0return 0;N = 0;tmp = (M >> 30);          // 获取最高位:B[m-1]M <<= 2;if (tmp > 1)              // 最高位为1{N ++;                 // 结果当前位为1,否则为默认的0tmp -= N;}for (i=15; i>0; i--)      // 求剩余的15位{N <<= 1;              // 左移一位tmp <<= 2;tmp += (M >> 30);     // 假设ttp = N;ttp = (ttp<<1)+1;M <<= 2;if (tmp >= ttp)       // 假设成立{tmp -= ttp;N ++;}}return N;
}//需要优化atant2 cos sin算法
static void Rotate(int x0,int y0,int*x,int*y,double angle,int direction)
{int temp=(*y-y0)*(*y-y0)+(*x-x0)*(*x-x0);double r=mySqrt(temp);double a0=atan2(*x-x0,*y-y0);if(direction){*x=x0+r*cos(a0+angle);*y=y0+r*sin(a0+angle);}else{*x=x0+r*cos(a0-angle);*y=y0+r*sin(a0-angle);}
}//功能:设置旋转角度
void SetAngle(float angle)
{_RoateValue.angle=RADIAN(angle);
}
//功能:设置旋转方向 1为逆时针,0为顺时针
void SetAnggleDir(int direction)
{_RoateValue.direct=direction;
}
//功能:设置旋转中心点
void SetRotateCenter(int x0,int y0)
{_RoateValue.center.x=x0;_RoateValue.center.y=y0;
}
//功能:设置角度、旋转方向、旋转中心
void SetRotateValue(int x,int y,float angle,int direct)
{SetRotateCenter(x,y);SetAnggleDir(direct);SetAngle(angle);
}
//功能:将一个坐标旋转一定角度
//x,y:需要旋转的坐标
//return:旋转后的坐标
TypeXY GetRotateXY(int x,int y)
{TypeXY temp;int m=x,n=y;Rotate(_RoateValue.center.x,_RoateValue.center.y,&m,&n, _RoateValue.angle ,_RoateValue.direct);temp.x=m;temp.y=n;return temp;
}/
//由某一点开始 获取向上方向同颜色的像素点的个数
unsigned char GetLengthUp(unsigned char x,unsigned char y,unsigned char value)
{if(GetPointBuffer(x,y)==value){if(y==0)return 0;return 1+GetLengthUp(x,y-1,value);}return 0;
}
//和上面函数同理 获取向下方向
unsigned char GetLengthDown(unsigned char x,unsigned char y,unsigned char value)
{if(GetPointBuffer(x,y)==value){if(y==63)return 0;return 1+GetLengthUp(x,y+1,value);}return 0;
}
/
//由一个点开始填充一个封闭图形
//亲测此函数可能有问题 可能是套娃太多 内存不够用
//测试效果是套娃几十个点后花屏
void FloodFill(unsigned char x,unsigned char y,int oldcolor,int newcolor)
{UpdateScreen();if(GetPointBuffer(x,y)==oldcolor)//这个点的颜色不对{SetPointBuffer(x,y,newcolor);//把这个点的颜色改为新颜色//开始套娃FloodFill(x-1,y,oldcolor,newcolor);//修改这个点周围的4个点的颜色FloodFill(x+1,y,oldcolor,newcolor);//用这个方法逐渐扩散 填完范围内所有颜色FloodFill(x,y+1,oldcolor,newcolor);FloodFill(x,y-1,oldcolor,newcolor);}
}
//功能:可用于填充一个封闭图形
//x,y:在封闭图形任意一点坐标
//oldcolor:封闭图形中旧的颜色
//newcolor:填充的新颜色
void FloodFill2(unsigned char x,unsigned char y,int oldcolor,int newcolor)
{unsigned char h1=0,h2=0;short tempx=x;while(GetPointBuffer(tempx,y)==oldcolor && tempx<128){h1=GetLengthDown(tempx,y,oldcolor);h2=GetLengthUp(tempx,y,oldcolor);FillVerticalLine(tempx,y-h2,h1+h2,newcolor);tempx++;}tempx=x-1;while(GetPointBuffer(tempx,y)==oldcolor&&tempx>0){h1=GetLengthDown(tempx,y,oldcolor);h2=GetLengthUp(tempx,y,oldcolor);FillVerticalLine(tempx,y-h2,h1+h2,newcolor);tempx--;}
}/
unsigned char pgm_read_byte(const unsigned char * addr)
{return *addr;
}
unsigned int oled_pow(unsigned char m,unsigned char n)
{unsigned int result=1;while(n--)result*=m;return result;
}
//功能:固定帧刷新
//OledTimeMs在OledTimeMsFunc()中被1ms中断持续调用 减到0位置
//此函数放在while循环中 符合条件时刷新屏幕
unsigned char FrameRateUpdateScreen(int value)
{if(OledTimeMs==0){UpdateScreen();ClearScreen();OledTimeMs=1000/value;return 1;}return 0;
}/* 原 oled_buffer.c 文件*///定义缓冲 屏幕缓冲区和临时缓冲区
unsigned char ScreenBuffer[SCREEN_PAGE_NUM][SCREEN_COLUMN]={0};	//屏幕缓冲
unsigned char TempBuffer[SCREEN_PAGE_NUM][SCREEN_COLUMN]={0};	//临时操作缓冲
static _Bool _SelectedBuffer=SCREEN_BUFFER;						//当前选择的缓冲区#define BUFFERSIZE  sizeof(ScreenBuffer)
extern void UpdateTempBuffer(void);
extern void UpdateScreenBuffer(void);///
//设置选择 屏幕缓冲
void SetScreenBuffer(void)
{_SelectedBuffer=SCREEN_BUFFER;
}
//设置选择 临时缓冲
void SetTempBuffer(void)
{_SelectedBuffer=TEMP_BUFFER;
}
//获取程序目前选择的缓冲区
unsigned char GetSelectedBuffer(void)
{return _SelectedBuffer;
}
//功能:清除屏幕缓冲数据
void ClearScreenBuffer(unsigned char val)
{memset(ScreenBuffer,val,sizeof(ScreenBuffer));
}
//功能:清除临时缓冲数据
void ClearTempBuffer(void)
{memset(TempBuffer,0,sizeof(TempBuffer));
}//对临时缓冲进行一些操作
//func:执行的功能可选择的参数如下
/*TEMPBUFF_COPY_TO_SCREEN, 		 将temp缓冲复制到屏幕缓冲TEMPBUFF_CLEAN,					 清楚掉temp缓冲数据TEMPBUFF_COVER_L,				 将temp缓冲的数据取反再覆盖掉屏幕上的数据TEMPBUFF_COVER_H				 将temp缓冲的数据覆盖掉屏幕上的数据 */
void TempBufferFunc(int func)
{int i,j;switch (func){case TEMPBUFF_COPY_TO_SCREEN:memcpy(ScreenBuffer,TempBuffer,BUFFERSIZE);break;case TEMPBUFF_CLEAN:ClearTempBuffer();break;case TEMPBUFF_COVER_H:for(i=0;i<8;i++)for(j=0;j<128;j++)ScreenBuffer[i][j] |=TempBuffer[i][j];break;case TEMPBUFF_COVER_L:for(i=0;i<8;i++)for(j=0;j<128;j++)ScreenBuffer[i][j] &=~TempBuffer[i][j];break;default:break;}
}///
//读取选择的缓冲区的8位数据
unsigned char ReadByteBuffer(int page,int x)
{return _SelectedBuffer? ScreenBuffer[page][x] :TempBuffer[page][x];
}
//写入读取选择的缓冲区8位数据
void WriteByteBuffer(int page,int x,unsigned char byte)
{if(_SelectedBuffer){ScreenBuffer[page][x] =byte;}else{TempBuffer[page][x] =byte;}
}//设置当前选择的缓冲区 的 某一个点的亮灭
void SetPointBuffer(int x,int y,int value)
{if(x>SCREEN_COLUMN-1 ||y>SCREEN_ROW-1)   //超出范围return;if(_SelectedBuffer){if(value)ScreenBuffer[y/SCREEN_PAGE_NUM][x] |= 1<<(y%SCREEN_PAGE_NUM);elseScreenBuffer[y/SCREEN_PAGE_NUM][x] &= ~(1<<(y%SCREEN_PAGE_NUM));}else{if(value)TempBuffer[y/SCREEN_PAGE_NUM][x] |= 1<<(y%SCREEN_PAGE_NUM);elseTempBuffer[y/SCREEN_PAGE_NUM][x] &= ~(1<<(y%SCREEN_PAGE_NUM));}
}
//获取当前选择的缓冲区 的 某一点的颜色
unsigned char GetPointBuffer(int x,int y)
{if(x>SCREEN_COLUMN-1 ||y>SCREEN_ROW-1)   //超出范围return 0;if(_SelectedBuffer)return (ScreenBuffer[y/SCREEN_PAGE_NUM][x]>>(y%SCREEN_PAGE_NUM))&0x01;elsereturn (TempBuffer[y/SCREEN_PAGE_NUM][x]>>(y%SCREEN_PAGE_NUM))&0x01;
}
//刷新屏幕显示
void UpdateScreenDisplay(void)
{UpdateScreenBuffer();
}

3、oled_font.c

/*Copyright (c) [2019] [一只程序缘 jiezhuo][https://gitee.com/jiezhuonew/oledlib] is licensed under the Mulan PSL v1.You can use this software according to the terms and conditions of the Mulan PSL v1.You may obtain a copy of Mulan PSL v1 at:http://license.coscl.org.cn/MulanPSLTHIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULARPURPOSE.See the Mulan PSL v1 for more details.此c文件用于对字体进行操作 在oled.draw中被DrawChar()等函数被调用主要有设置字体背景颜色 (字体颜色同划线线条颜色GetDrawColor())字体尺寸基础字符字库(取模方式见字库顶部)汉字字库(取模方式见字库顶部)
*/#include "oled_font.h"static Type_textbk _TextBk=TEXT_BK_NULL;
static unsigned char _FontSize=0;			//默认字体尺寸 为8x6/
//设置字体填充的背景颜色
//1白0黑 
//TEXT_BK_NULL:无背景,TEXT_BK_NOT_NULL:有背景
void SetTextBkMode(Type_textbk value)
{_TextBk=value;
}
Type_textbk GetTextBkMode(void)
{return _TextBk;
}//在显示字体前先设置需要显示的字体的尺寸
//尺寸有 0 1 2 3
//对应像素是 0 8 16 24
//0是默认字体 		也就是F8X16[]		大小8x16
//1是原作者字体 	也就是font5x7[]		大小6x8
//2是1的2倍放大							大小12x16
//3是1的3倍放大							大小18x24
void SetFontSize(unsigned char value)
{_FontSize=value;
}
unsigned char GetFontSize(void)
{return _FontSize;
}//基础图形英文字符字库
//若要显示更大的字符按照此字符比例放大即可
//详情见DrawChar()
const unsigned char font5x7[] =
{0x00, 0x00, 0x00, 0x00, 0x00,0x3E, 0x5B, 0x4F, 0x5B, 0x3E,0x3E, 0x6B, 0x4F, 0x6B, 0x3E,0x1C, 0x3E, 0x7C, 0x3E, 0x1C,0x18, 0x3C, 0x7E, 0x3C, 0x18,0x1C, 0x57, 0x7D, 0x57, 0x1C,0x1C, 0x5E, 0x7F, 0x5E, 0x1C,0x00, 0x18, 0x3C, 0x18, 0x00,0xFF, 0xE7, 0xC3, 0xE7, 0xFF,0x00, 0x18, 0x24, 0x18, 0x00,0xFF, 0xE7, 0xDB, 0xE7, 0xFF,0x30, 0x48, 0x3A, 0x06, 0x0E,0x26, 0x29, 0x79, 0x29, 0x26,0x40, 0x7F, 0x05, 0x05, 0x07,0x40, 0x7F, 0x05, 0x25, 0x3F,0x5A, 0x3C, 0xE7, 0x3C, 0x5A,0x7F, 0x3E, 0x1C, 0x1C, 0x08,0x08, 0x1C, 0x1C, 0x3E, 0x7F,0x14, 0x22, 0x7F, 0x22, 0x14,0x5F, 0x5F, 0x00, 0x5F, 0x5F,0x06, 0x09, 0x7F, 0x01, 0x7F,0x00, 0x66, 0x89, 0x95, 0x6A,0x60, 0x60, 0x60, 0x60, 0x60,0x94, 0xA2, 0xFF, 0xA2, 0x94,0x08, 0x04, 0x7E, 0x04, 0x08,0x10, 0x20, 0x7E, 0x20, 0x10,0x08, 0x08, 0x2A, 0x1C, 0x08,0x08, 0x1C, 0x2A, 0x08, 0x08,0x1E, 0x10, 0x10, 0x10, 0x10,0x0C, 0x1E, 0x0C, 0x1E, 0x0C,0x30, 0x38, 0x3E, 0x38, 0x30,0x06, 0x0E, 0x3E, 0x0E, 0x06,0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x5F, 0x00, 0x00,0x00, 0x07, 0x00, 0x07, 0x00,0x14, 0x7F, 0x14, 0x7F, 0x14,0x24, 0x2A, 0x7F, 0x2A, 0x12,0x23, 0x13, 0x08, 0x64, 0x62,0x36, 0x49, 0x56, 0x20, 0x50,0x00, 0x08, 0x07, 0x03, 0x00,0x00, 0x1C, 0x22, 0x41, 0x00,0x00, 0x41, 0x22, 0x1C, 0x00,0x2A, 0x1C, 0x7F, 0x1C, 0x2A,0x08, 0x08, 0x3E, 0x08, 0x08,0x00, 0x80, 0x70, 0x30, 0x00,0x08, 0x08, 0x08, 0x08, 0x08,0x00, 0x00, 0x60, 0x60, 0x00,0x20, 0x10, 0x08, 0x04, 0x02,0x3E, 0x51, 0x49, 0x45, 0x3E,0x00, 0x42, 0x7F, 0x40, 0x00,0x72, 0x49, 0x49, 0x49, 0x46,0x21, 0x41, 0x49, 0x4D, 0x33,0x18, 0x14, 0x12, 0x7F, 0x10,0x27, 0x45, 0x45, 0x45, 0x39,0x3C, 0x4A, 0x49, 0x49, 0x31,0x41, 0x21, 0x11, 0x09, 0x07,0x36, 0x49, 0x49, 0x49, 0x36,0x46, 0x49, 0x49, 0x29, 0x1E,0x00, 0x00, 0x14, 0x00, 0x00,0x00, 0x40, 0x34, 0x00, 0x00,0x00, 0x08, 0x14, 0x22, 0x41,0x14, 0x14, 0x14, 0x14, 0x14,0x00, 0x41, 0x22, 0x14, 0x08,0x02, 0x01, 0x59, 0x09, 0x06,0x3E, 0x41, 0x5D, 0x59, 0x4E,0x7C, 0x12, 0x11, 0x12, 0x7C,0x7F, 0x49, 0x49, 0x49, 0x36,0x3E, 0x41, 0x41, 0x41, 0x22,0x7F, 0x41, 0x41, 0x41, 0x3E,0x7F, 0x49, 0x49, 0x49, 0x41,0x7F, 0x09, 0x09, 0x09, 0x01,0x3E, 0x41, 0x41, 0x51, 0x73,0x7F, 0x08, 0x08, 0x08, 0x7F,0x00, 0x41, 0x7F, 0x41, 0x00,0x20, 0x40, 0x41, 0x3F, 0x01,0x7F, 0x08, 0x14, 0x22, 0x41,0x7F, 0x40, 0x40, 0x40, 0x40,0x7F, 0x02, 0x1C, 0x02, 0x7F,0x7F, 0x04, 0x08, 0x10, 0x7F,0x3E, 0x41, 0x41, 0x41, 0x3E,0x7F, 0x09, 0x09, 0x09, 0x06,0x3E, 0x41, 0x51, 0x21, 0x5E,0x7F, 0x09, 0x19, 0x29, 0x46,0x26, 0x49, 0x49, 0x49, 0x32,0x03, 0x01, 0x7F, 0x01, 0x03,0x3F, 0x40, 0x40, 0x40, 0x3F,0x1F, 0x20, 0x40, 0x20, 0x1F,0x3F, 0x40, 0x38, 0x40, 0x3F,0x63, 0x14, 0x08, 0x14, 0x63,0x03, 0x04, 0x78, 0x04, 0x03,0x61, 0x59, 0x49, 0x4D, 0x43,0x00, 0x7F, 0x41, 0x41, 0x41,0x02, 0x04, 0x08, 0x10, 0x20,0x00, 0x41, 0x41, 0x41, 0x7F,0x04, 0x02, 0x01, 0x02, 0x04,0x40, 0x40, 0x40, 0x40, 0x40,0x00, 0x03, 0x07, 0x08, 0x00,0x20, 0x54, 0x54, 0x78, 0x40,0x7F, 0x28, 0x44, 0x44, 0x38,0x38, 0x44, 0x44, 0x44, 0x28,0x38, 0x44, 0x44, 0x28, 0x7F,0x38, 0x54, 0x54, 0x54, 0x18,0x00, 0x08, 0x7E, 0x09, 0x02,0x18, 0xA4, 0xA4, 0x9C, 0x78,0x7F, 0x08, 0x04, 0x04, 0x78,0x00, 0x44, 0x7D, 0x40, 0x00,0x20, 0x40, 0x40, 0x3D, 0x00,0x7F, 0x10, 0x28, 0x44, 0x00,0x00, 0x41, 0x7F, 0x40, 0x00,0x7C, 0x04, 0x78, 0x04, 0x78,0x7C, 0x08, 0x04, 0x04, 0x78,0x38, 0x44, 0x44, 0x44, 0x38,0xFC, 0x18, 0x24, 0x24, 0x18,0x18, 0x24, 0x24, 0x18, 0xFC,0x7C, 0x08, 0x04, 0x04, 0x08,0x48, 0x54, 0x54, 0x54, 0x24,0x04, 0x04, 0x3F, 0x44, 0x24,0x3C, 0x40, 0x40, 0x20, 0x7C,0x1C, 0x20, 0x40, 0x20, 0x1C,0x3C, 0x40, 0x30, 0x40, 0x3C,0x44, 0x28, 0x10, 0x28, 0x44,0x4C, 0x90, 0x90, 0x90, 0x7C,0x44, 0x64, 0x54, 0x4C, 0x44,0x00, 0x08, 0x36, 0x41, 0x00,0x00, 0x00, 0x77, 0x00, 0x00,0x00, 0x41, 0x36, 0x08, 0x00,0x02, 0x01, 0x02, 0x04, 0x02,0x3C, 0x26, 0x23, 0x26, 0x3C,0x1E, 0xA1, 0xA1, 0x61, 0x12,0x3A, 0x40, 0x40, 0x20, 0x7A,0x38, 0x54, 0x54, 0x55, 0x59,0x21, 0x55, 0x55, 0x79, 0x41,0x21, 0x54, 0x54, 0x78, 0x41,0x21, 0x55, 0x54, 0x78, 0x40,0x20, 0x54, 0x55, 0x79, 0x40,0x0C, 0x1E, 0x52, 0x72, 0x12,0x39, 0x55, 0x55, 0x55, 0x59,0x39, 0x54, 0x54, 0x54, 0x59,0x39, 0x55, 0x54, 0x54, 0x58,0x00, 0x00, 0x45, 0x7C, 0x41,0x00, 0x02, 0x45, 0x7D, 0x42,0x00, 0x01, 0x45, 0x7C, 0x40,0xF0, 0x29, 0x24, 0x29, 0xF0,0xF0, 0x28, 0x25, 0x28, 0xF0,0x7C, 0x54, 0x55, 0x45, 0x00,0x20, 0x54, 0x54, 0x7C, 0x54,0x7C, 0x0A, 0x09, 0x7F, 0x49,0x32, 0x49, 0x49, 0x49, 0x32,0x32, 0x48, 0x48, 0x48, 0x32,0x32, 0x4A, 0x48, 0x48, 0x30,0x3A, 0x41, 0x41, 0x21, 0x7A,0x3A, 0x42, 0x40, 0x20, 0x78,0x00, 0x9D, 0xA0, 0xA0, 0x7D,0x39, 0x44, 0x44, 0x44, 0x39,0x3D, 0x40, 0x40, 0x40, 0x3D,0x3C, 0x24, 0xFF, 0x24, 0x24,0x48, 0x7E, 0x49, 0x43, 0x66,0x2B, 0x2F, 0xFC, 0x2F, 0x2B,0xFF, 0x09, 0x29, 0xF6, 0x20,0xC0, 0x88, 0x7E, 0x09, 0x03,0x20, 0x54, 0x54, 0x79, 0x41,0x00, 0x00, 0x44, 0x7D, 0x41,0x30, 0x48, 0x48, 0x4A, 0x32,0x38, 0x40, 0x40, 0x22, 0x7A,0x00, 0x7A, 0x0A, 0x0A, 0x72,0x7D, 0x0D, 0x19, 0x31, 0x7D,0x26, 0x29, 0x29, 0x2F, 0x28,0x26, 0x29, 0x29, 0x29, 0x26,0x30, 0x48, 0x4D, 0x40, 0x20,0x38, 0x08, 0x08, 0x08, 0x08,0x08, 0x08, 0x08, 0x08, 0x38,0x2F, 0x10, 0xC8, 0xAC, 0xBA,0x2F, 0x10, 0x28, 0x34, 0xFA,0x00, 0x00, 0x7B, 0x00, 0x00,0x08, 0x14, 0x2A, 0x14, 0x22,0x22, 0x14, 0x2A, 0x14, 0x08,0x95, 0x00, 0x22, 0x00, 0x95,0xAA, 0x00, 0x55, 0x00, 0xAA,0xAA, 0x55, 0xAA, 0x55, 0xAA,0x00, 0x00, 0x00, 0xFF, 0x00,0x10, 0x10, 0x10, 0xFF, 0x00,0x14, 0x14, 0x14, 0xFF, 0x00,0x10, 0x10, 0xFF, 0x00, 0xFF,0x10, 0x10, 0xF0, 0x10, 0xF0,0x14, 0x14, 0x14, 0xFC, 0x00,0x14, 0x14, 0xF7, 0x00, 0xFF,0x00, 0x00, 0xFF, 0x00, 0xFF,0x14, 0x14, 0xF4, 0x04, 0xFC,0x14, 0x14, 0x17, 0x10, 0x1F,0x10, 0x10, 0x1F, 0x10, 0x1F,0x14, 0x14, 0x14, 0x1F, 0x00,0x10, 0x10, 0x10, 0xF0, 0x00,0x00, 0x00, 0x00, 0x1F, 0x10,0x10, 0x10, 0x10, 0x1F, 0x10,0x10, 0x10, 0x10, 0xF0, 0x10,0x00, 0x00, 0x00, 0xFF, 0x10,0x10, 0x10, 0x10, 0x10, 0x10,0x10, 0x10, 0x10, 0xFF, 0x10,0x00, 0x00, 0x00, 0xFF, 0x14,0x00, 0x00, 0xFF, 0x00, 0xFF,0x00, 0x00, 0x1F, 0x10, 0x17,0x00, 0x00, 0xFC, 0x04, 0xF4,0x14, 0x14, 0x17, 0x10, 0x17,0x14, 0x14, 0xF4, 0x04, 0xF4,0x00, 0x00, 0xFF, 0x00, 0xF7,0x14, 0x14, 0x14, 0x14, 0x14,0x14, 0x14, 0xF7, 0x00, 0xF7,0x14, 0x14, 0x14, 0x17, 0x14,0x10, 0x10, 0x1F, 0x10, 0x1F,0x14, 0x14, 0x14, 0xF4, 0x14,0x10, 0x10, 0xF0, 0x10, 0xF0,0x00, 0x00, 0x1F, 0x10, 0x1F,0x00, 0x00, 0x00, 0x1F, 0x14,0x00, 0x00, 0x00, 0xFC, 0x14,0x00, 0x00, 0xF0, 0x10, 0xF0,0x10, 0x10, 0xFF, 0x10, 0xFF,0x14, 0x14, 0x14, 0xFF, 0x14,0x10, 0x10, 0x10, 0x1F, 0x00,0x00, 0x00, 0x00, 0xF0, 0x10,0xFF, 0xFF, 0xFF, 0xFF, 0xFF,0xF0, 0xF0, 0xF0, 0xF0, 0xF0,0xFF, 0xFF, 0xFF, 0x00, 0x00,0x00, 0x00, 0x00, 0xFF, 0xFF,0x0F, 0x0F, 0x0F, 0x0F, 0x0F,0x38, 0x44, 0x44, 0x38, 0x44,0x7C, 0x2A, 0x2A, 0x3E, 0x14,0x7E, 0x02, 0x02, 0x06, 0x06,0x02, 0x7E, 0x02, 0x7E, 0x02,0x63, 0x55, 0x49, 0x41, 0x63,0x38, 0x44, 0x44, 0x3C, 0x04,0x40, 0x7E, 0x20, 0x1E, 0x20,0x06, 0x02, 0x7E, 0x02, 0x02,0x99, 0xA5, 0xE7, 0xA5, 0x99,0x1C, 0x2A, 0x49, 0x2A, 0x1C,0x4C, 0x72, 0x01, 0x72, 0x4C,0x30, 0x4A, 0x4D, 0x4D, 0x30,0x30, 0x48, 0x78, 0x48, 0x30,0xBC, 0x62, 0x5A, 0x46, 0x3D,0x3E, 0x49, 0x49, 0x49, 0x00,0x7E, 0x01, 0x01, 0x01, 0x7E,0x2A, 0x2A, 0x2A, 0x2A, 0x2A,0x44, 0x44, 0x5F, 0x44, 0x44,0x40, 0x51, 0x4A, 0x44, 0x40,0x40, 0x44, 0x4A, 0x51, 0x40,0x00, 0x00, 0xFF, 0x01, 0x03,0xE0, 0x80, 0xFF, 0x00, 0x00,0x08, 0x08, 0x6B, 0x6B, 0x08,0x36, 0x12, 0x36, 0x24, 0x36,0x06, 0x0F, 0x09, 0x0F, 0x06,0x00, 0x00, 0x18, 0x18, 0x00,0x00, 0x00, 0x10, 0x10, 0x00,0x30, 0x40, 0xFF, 0x01, 0x01,0x00, 0x1F, 0x01, 0x01, 0x1E,0x00, 0x19, 0x1D, 0x17, 0x12,0x00, 0x3C, 0x3C, 0x3C, 0x3C,0x00, 0x00, 0x00, 0x00, 0x00,
};/****************************************8*16的点阵************************************/
const unsigned char F8X16[]=	  
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 00x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 10x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 20x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 30x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 40xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 50x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 60x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 70x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 80x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 90x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 100x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 110x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 120x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 130x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 140x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 150x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 160x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 170x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 180x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 190x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 200x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 210x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 220x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 230x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 240x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 250x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 260x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 270x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 280x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 290x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 300x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 310xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 320x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 330x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 340xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 350x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 360x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 370x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 380xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 390x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 400x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 410x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 420x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 430x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 440x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 450x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 460xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 470x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 480xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 490x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 500x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 510x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 520x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 530x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 540xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 550x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 560x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 570x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 580x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 590x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 600x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 610x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 620x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 630x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 640x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 650x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 660x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 670x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 680x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 690x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 700x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 710x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 720x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 730x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 740x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 750x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 760x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 770x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 780x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 790x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 800x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 810x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 820x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 830x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 840x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 850x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 860x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 870x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 880x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 890x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 900x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 910x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 920x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 930x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
};
//使用常用取模软件 PCtoLCD2002
//汉字采用 16x16 阴码 列行式 逆向
//中文字库
struct Cn16CharTypeDef const CN16CHAR[NUM_OFCHINESE]=
{
"一",0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"一",0*/
"只",0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,
0x00,0x80,0x40,0x23,0x19,0x01,0x01,0x01,0x01,0x01,0x09,0x13,0x20,0xC0,0x00,0x00,/*"只",1*/
"程",0x24,0x24,0xA4,0xFE,0x23,0x22,0x00,0x3E,0x22,0x22,0x22,0x22,0x22,0x3E,0x00,0x00,
0x08,0x06,0x01,0xFF,0x01,0x06,0x40,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0x41,0x00,/*"程",2*/
"序",0x00,0x00,0xFC,0x04,0x04,0x04,0x14,0x15,0x56,0x94,0x54,0x34,0x14,0x04,0x04,0x00,
0x40,0x30,0x0F,0x00,0x01,0x01,0x01,0x41,0x81,0x7F,0x01,0x01,0x01,0x05,0x03,0x00,/*"序",3*/
"缘",0x20,0x30,0xAC,0x63,0x30,0x00,0x20,0x2C,0xAB,0x6A,0xAA,0x2A,0x3A,0x26,0xA0,0x00,
0x22,0x67,0x22,0x12,0x12,0x00,0x49,0x49,0x24,0x52,0x89,0x7F,0x02,0x0D,0x10,0x00,/*"缘",4*/};

五、使用教程

1、使用前需先初始化OLED_Init();

2、显示完毕需添加代码UpdateScreen();

3、字体大小范围:0-3

六、巨人之肩

STM32 HAL 硬件IIC+DMA+简单图形库控制OLED

STM32 OLED动画显示DMA+IIC刷新(理论可达42+帧率)

七、源码提供

资源【STM32+HAL】地表最强高刷OLED显示配置

这篇关于【STM32+HAL】地表最强高刷OLED显示配置【I2C】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/824588

相关文章

Linux 安装、配置Tomcat 的HTTPS

Linux 安装 、配置Tomcat的HTTPS 安装Tomcat 这里选择的是 tomcat 10.X ,需要Java 11及更高版本 Binary Distributions ->Core->选择 tar.gz包 下载、上传到内网服务器 /opt 目录tar -xzf 解压将解压的根目录改名为 tomat-10 并移动到 /opt 下, 形成个人习惯的路径 /opt/tomcat-10

uniapp接入微信小程序原生代码配置方案(优化版)

uniapp项目需要把微信小程序原生语法的功能代码嵌套过来,无需把原生代码转换为uniapp,可以配置拷贝的方式集成过来 1、拷贝代码包到src目录 2、vue.config.js中配置原生代码包直接拷贝到编译目录中 3、pages.json中配置分包目录,原生入口组件的路径 4、manifest.json中配置分包,使用原生组件 5、需要把原生代码包里的页面修改成组件的方

JAVA读取MongoDB中的二进制图片并显示在页面上

1:Jsp页面: <td><img src="${ctx}/mongoImg/show"></td> 2:xml配置: <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001

零基础STM32单片机编程入门(一)初识STM32单片机

文章目录 一.概要二.单片机型号命名规则三.STM32F103系统架构四.STM32F103C8T6单片机启动流程五.STM32F103C8T6单片机主要外设资源六.编程过程中芯片数据手册的作用1.单片机外设资源情况2.STM32单片机内部框图3.STM32单片机管脚图4.STM32单片机每个管脚可配功能5.单片机功耗数据6.FALSH编程时间,擦写次数7.I/O高低电平电压表格8.外设接口

IDEA配置Tomcat远程调试

因为不想把本地的Tomcat配置改乱或者多人开发项目想测试,本文主要是记录一下,IDEA使用Tomcat远程调试的配置过程,免得一段时间不去配置到时候忘记(毕竟这次是因为忘了,所以才打算记录的…) 首先在catalina.sh添加以下内容 JAVA_OPTS="-Dcom.sun.management.jmxremote=-Dcom.sun.management.jmxremote.port

据阿谱尔APO Research调研显示,2023年全球髓内钉市场销售额约为4.7亿美元

根据阿谱尔 (APO Research)的统计及预测,2023年全球髓内钉市场销售额约为4.7亿美元,预计在2024-2030年预测期内将以超过3.82%的CAGR(年复合增长率)增长。 髓内钉市场是指涉及髓内钉制造、分销和销售的行业。髓内钉是一种用于整形外科手术的医疗器械,用于稳定长骨骨折,特别是股骨、胫骨和肱骨。髓内钉通常由不銹钢或钛等材料制成,并插入骨的髓管中,以在愈合过程中提供结构支

vue+elementUI下拉框联动显示

<el-row><el-col :span="12"><el-form-item label="主账号:" prop="partyAccountId" :rules="[ { required: true, message: '主账号不能为空'}]"><el-select v-model="detailForm.partyAccountId" filterable placeholder="

Steam邮件推送内容有哪些?配置教程详解!

Steam邮件推送功能是否安全?如何个性化邮件推送内容? Steam作为全球最大的数字游戏分发平台之一,不仅提供了海量的游戏资源,还通过邮件推送为用户提供最新的游戏信息、促销活动和个性化推荐。AokSend将详细介绍Steam邮件推送的主要内容。 Steam邮件推送:促销优惠 每当平台举办大型促销活动,如夏季促销、冬季促销、黑色星期五等,用户都会收到邮件通知。这些邮件详细列出了打折游戏、

微信小程序开发必知必会:文件结构和基本配置

一、微信小程序基本文件结构 1.  project.config.json:项目的基本配置文件,包括项目名称、appid、项目目录、页面文件夹等。     {"setting": {"urlCheck": false,"es6": true,"postcss": true,"nodeModulesPath": "D:\\\\node_modules"},"appid": "wxd678e

【杂记-浅谈DHCP动态主机配置协议】

DHCP动态主机配置协议 一、DHCP概述1、定义2、作用3、报文类型 二、DHCP的工作原理三、DHCP服务器的配置和管理 一、DHCP概述 1、定义 DHCP,Dynamic Host Configuration Protocol,动态主机配置协议,是一种网络协议,主要用于在IP网络中自动分配和管理IP地址以及其他网络配置参数。 2、作用 DHCP允许计算机和其他设备通