转载自https://blog.csdn.net/dpjcn1990/article/details/92831760
u8g2学习 Arduino平台上使用最广泛的OLED库
像素点点阵
OLED其实就是一个M x n 的像素点阵,想显示什么就得把具体位置的像素点亮起来。对于每一个像素点,有可能是1点亮,也有可能是0点亮;
坐标系
在坐标系中,左上角是原点,向右是X轴,向下是Y轴。
U8g2是什么 U8g2是嵌入式设备的单色图形库,一句话简单明了。主要应用于嵌入式设备,包括我们常见的单片机;
U8g2支持的显示控制器 U8g2支持单色OLED和LCD,包括以下控制器:SSD1305,SSD1306,SSD1309,SSD1322,SSD1325,SSD1327,SSD1329,SSD1606,SSD1607,SH1106,SH1107,SH1108,SH1122,T6963,RA8835,LC7981,PCD8544,PCF8812,HX1230 ,UC1601,UC1604,UC1608,UC1610,UC1611,UC1701,ST7565,ST7567,ST7588,ST75256,NT7534,IST3020,ST7920,LD7032,KS0108,SED1520,SBN1661,IL3820,MAX7219等
可以说,基本上主流的显示控制器都支持,比如我们常见的SSD1306 12864
U8g2支持的Arduino主板 可以说基本上所有Arduino API的主板都得到U8g2的支持
Aruino Zero,Uno,Mega,Due,101,MKR Zero以及所有其他Arduino官方主板
基于Arduino平台的STM32
基于Arduino平台的ESP8266和ESP32
甚至其他不知名的基于Arduino平台的开发板
U8g2的优势 为什么要运用U8g2库?也就是说U8g2库能带给我们什么样的开发便利
U8g2库平台支持性好,基本上支持绝大部分Arduino开发板;
U8g2库显示控制器支持性好,基本上市面上的OLED都完美支持;
U8g2库 API众多,特别支持了中文,支持了不同字体,这是一个对于开发者俩说不小的福利。
U8g2库函数详解 基本函数
u8g2.begin() —— 构造U8G2
1 2 3 4 5 bool U8G2::begin (void )
1 2 3 4 5 6 7 bool begin (void ) { initDisplay(); clearDisplay(); setPowerSave(0 ); return 1 ; }
u8g2.beginSimple() —— 构造U8G2
1 2 3 4 5 void U8G2::beginSimple (void ) ;
1 2 3 4 5 void beginSimple (void ) { initDisplay(); }
u8g2.initDisplay() —— 初始化显示控制器
1 2 3 4 void U8G2::initDisplay (void )
这个方法不需要我们单独调用,会在begin函数主动调用一次
u8g2.clearDisplay() —— 清除屏幕内容
1 2 3 4 void U8G2::clearDisplay (void )
这个方法不需要我们单独调用,会在begin函数主动调用一次,我们主要理解即可;
不要在 firstPage 和 nextPage 函数之间调用该方法;
u8g2.setPowerSave() —— 是否开启省电模式
1 2 3 4 5 6 7 void U8G2::setPowerSave (uint8_t is_enable)
不管是启用还是禁用,显示器需要的内存消耗是不会变的,说到底就是为了关闭屏幕,做到省电;
所以这里就可以理解为什么初始化需要 setPowerSave(0);
u8g2.clear() —— 清除操作
1 2 3 4 5 void U8G2::clear (void )
1 2 3 4 5 void clear (void ) { home(); clearDisplay(); clearBuffer(); }
u8g2.clearBuffer() —— 清除缓冲区
1 2 3 4 void U8G2::clearBuffer (void )
1 2 3 4 5 6 void loop (void ) { u8g2.clearBuffer(); u8g2.sendBuffer(); delay(1000 ); }
u8g2.disableUTF8Print() —— 禁用 UTF8打印
1 2 3 4 void U8G2::disableUTF8Print (void )
1 2 3 4 5 6 7 8 9 10 11 12 13 void setup (void ) { u8g2.begin(); u8g2.enableUTF8Print(); }void loop (void ) { u8g2.setFont(u8g2_font_unifont_t_chinese2); u8g2.firstPage(); do { u8g2.setCursor(0 , 40 ); u8g2.print("你好世界" ); } while ( u8g2.nextPage() ); delay(1000 ); }
u8g2.home() —— 重置显示光标的位置
1 2 3 4 5 void U8G2::home (void )
绘制相关函数
u8g2.drawBox() —— 画实心方形
1 2 3 4 5 6 7 8 9 void U8G2::drawBox (u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)
如果支持绘制颜色(也就是不是单色显示器),那么由setDrawColor设置
1 u8g2.drawBox(3 ,7 ,25 ,15 );
u8g2.drawCircle() —— 画空心圆
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 void U8G2::drawCircle (u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t opt = U8G2_DRAW_ALL)
如果支持绘制颜色(也就是不是单色显示器),那么由setDrawColor设置;
直径等于2rad + 1;
1 u8g2.drawCircle(20 , 25 , 10 , U8G2_DRAW_ALL);
u8g2.drawDisc() —— 画实心圆
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 void U8G2::drawDisc (u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t opt = U8G_DRAW_ALL)
如果支持绘制颜色(也就是不是单色显示器),那么由setDrawColor设置;
直径等于2rad + 1;
u8g2.drawEllipse() —— 画空心椭圆
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void U8G2::drawEllipse (u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t opt)
1 u8g2.drawEllipse(20 , 25 , 15 , 10 , U8G2_DRAW_ALL);
u8g2.drawFilledEllipse() —— 画实心椭圆
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void U8G2::drawFilledEllipse (u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t opt)
u8g2.drawFrame() —— 画空心方形
1 2 3 4 5 6 7 8 9 void U8G2::drawFrame (u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)
如果支持绘制颜色(也就是不是单色显示器),那么由setDrawColor设置
1 u8g2.drawFrame(3 ,7 ,25 ,15 );
u8g2.drawGlyph() —— 绘制字体字集的符号
1 2 3 4 5 6 7 8 void U8G2::drawGlyph (u8g2_uint_t x, u8g2_uint_t y, uint16_t encoding)
U8g2支持16位以内的unicode字符集,也就是说encoding的范围为0-65535,drawGlyph方法只能绘制存在于所使用的字体字集中的unicode值;
这个绘制方法依赖于当前的字体模式和绘制颜色
u8g2.drawHLine() —— 绘制水平线
1 2 3 4 5 6 7 8 void U8G2::drawHLine (u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w)
如果支持绘制颜色(也就是不是单色显示器),那么由setDrawColor设置
u8g2.drawLine() —— 两点之间绘制线
1 2 3 4 5 6 7 8 9 void U8G2::drawLine (u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t x1, u8g2_uint_t y1)
如果支持绘制颜色(也就是不是单色显示器),那么由setDrawColor设置;
1 u8g2.drawLine(20 , 5 , 5 , 32 );
u8g2.drawPixel() —— 绘制像素点
1 2 3 4 5 6 7 void U8G2::drawPixel (u8g2_uint_t x, u8g2_uint_t y)
如果支持绘制颜色(也就是不是单色显示器),那么由setDrawColor设置;
你会发现很多绘制方法的底层都是调用drawPixel,毕竟像素属于最小颗粒度;
我们可以利用这个绘制方法自定义自己的图形显示;
u8g2.drawRBox() —— 绘制圆角实心方形
1 2 3 4 5 6 7 8 9 void U8G2::drawRBox (u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r)
如果支持绘制颜色(也就是不是单色显示器),那么由setDrawColor设置;
要求,w >= 2*(r+1) 并且 h >= 2*(r+1),这是显而易见的限制;
u8g2.drawRFrame() —— 绘制圆角空心方形
1 2 3 4 5 6 7 8 9 void U8G2::drawRFrame (u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r)
如果支持绘制颜色(也就是不是单色显示器),那么由setDrawColor设置;
要求,w >= 2*(r+1) 并且 h >= 2*(r+1),这是显而易见的限制
1 u8g2.drawRFrame(20 ,15 ,30 ,22 ,7 );
u8g2.drawStr() —— 绘制字符串
1 2 3 4 5 6 7 8 u8g2_uint_t U8g2::drawStr (u8g2_uint_t x, u8g2_uint_t y, const char *s)
需要先设置字体,调用setFont方法;
这个方法不能绘制encoding超过256的,超过256需要用drawUTF8或者drawGlyph;说白了就是一般用来显示英文字符;
x,y属于字符串左下角的坐标;
1 2 u8g2.setFont(u8g2_font_ncenB14_tr); u8g2.drawStr(0 ,15 ,"Hello World!" );
u8g2.drawTriangle() —— 绘制实心三角形
1 2 3 4 void U8G2::drawTriangle (int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2)
1 u8g2.drawTriangle(20 ,5 , 27 ,50 , 5 ,32 );
u8g2.drawUTF8() —— 绘制UTF8编码的字符
1 2 3 4 5 6 7 8 u8g2_uint_t U8g2::drawUTF8 (u8g2_uint_t x, u8g2_uint_t y, const char *s)
使用该方法,有两个前提。首先是你的编译器需要支持UTF-8编码,对于绝大部分Arduino板子已经支持;其次,显示的字符串需要存为“UTF-8”编码,Arduino IDE上默认支持;
该方法需要依赖于fontMode(setFont)以及drawing Color,也就是说如果你传进来的字符串编码必须在font定义里面;
1 2 u8g2.setFont(u8g2_font_unifont_t_symbols); u8g2.drawUTF8(5 , 20 , "Snowman: ☃" );
u8g2.drawVLine() —— 绘制竖直线
1 2 3 4 5 6 7 void U8G2::drawVLine (u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t h)
u8g2.drawXBM()/drawXBMP() —— 绘制图像
1 2 3 4 5 6 7 8 9 10 11 void U8G2::drawXBM (u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, const uint8_t *bitmap) void U8G2::drawXBMP (u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, const uint8_t *bitmap)
drawXBM和drawXBMP区别在于 XBMP支持PROGMEM
u8g2.firstPage()/nextPage() —— 绘制命令
1 2 3 4 5 void U8G2::firstPage (void ) uint8_t U8G2::nextPage (void )
1 2 3 4 5 6 u8g2.firstPage();do { u8g2.setFont(u8g2_font_ncenB14_tr); u8g2.drawStr(0 ,20 ,"Hello World!" ); } while ( u8g2.nextPage() );
u8g2.print() —— 绘制内容
1 2 3 4 5 void U8G2::print (...)
1 2 3 u8g2.setFont(u8g2_font_ncenB14_tr); u8g2.setCursor(0 , 15 ); u8g2.print("Hello World!" );
u8g2.sendBuffer() —— 绘制缓冲区的内容
1 2 3 4 5 void U8G2::sendBuffer (void )
sendBuffer的RAM占用空间大,需要结合构造器的buffer选项使用;
不管是fistPage、nextPage还是sendBuffer,都涉及到一个叫做 current page position的概念;
显示配置相关函数
u8g2.getAscent() —— 获取基准线以上的高度
1 2 3 4 5 6 int8_t U8G2::getAscent (void )
u8g2.getDescent() —— 获取基准线以下的高度
1 2 3 4 5 6 int8_t U8G2::getDescent (void )
u8g2.getDisplayHeight() —— 获取显示器的高度
1 2 3 4 5 u8g2_uint_t getDisplayHeight (void )
u8g2.getDisplayWidth() —— 获取显示器的宽度
1 2 3 4 5 u8g2_uint_t getDisplayWidth (void )
u8g2.getMaxCharHeight() —— 获取当前字体里的最大字符的高度
1 2 3 4 5 6 u8g2_uint_t getMaxCharHeight (void )
每一个字符在font字集中都是一个位图,位图有高度和宽度;
u8g2.getMaxCharWidth() —— 获取当前字体里的最大字符的宽度
1 2 3 4 5 6 u8g2_uint_t getMaxCharWidth (void )
u8g2.getStrWidth() —— 获取字符串的像素宽度
1 2 3 4 5 6 7 u8g2_uint_t U8G2::getStrWidth (const char *s)
u8g2.getUTF8Width() —— 获取UTF-8字符串的像素宽度
1 2 3 4 5 6 7 u8g2_uint_t U8G2::getUTF8Width (const char *s)
u8g2.setAutoPageClear() —— 设置自动清除缓冲区
1 2 3 4 5 6 void U8G2::setAutoPageClear (uint8_t mode)
该方法用于 firstPage 和 nextPage;
建议该方法保持默认就好,如果用户禁止了,那么需要自己维护缓冲区的状态或者手动调用clearBuffer;
u8g2.setBitmapMode() —— 设置位图模式
1 2 3 4 5 6 7 8 void U8G2::setBitmapMode (uint8_t is_transparent)
1 2 3 4 u8g2.setDrawColor(1 ); u8g2.setBitmapMode(0 ); u8g2.drawXBM(4 ,3 , u8g2_logo_97x51_width, u8g2_logo_97x51_height, u8g2_logo_97x51_bits); u8g2.drawXBM(12 ,11 , u8g2_logo_97x51_width, u8g2_logo_97x51_height, u8g2_logo_97x51_bits);
1 2 3 4 u8g2.setDrawColor(1 ); u8g2.setBitmapMode(1 ); u8g2.drawXBM(4 ,3 , u8g2_logo_97x51_width, u8g2_logo_97x51_height, u8g2_logo_97x51_bits); u8g2.drawXBM(12 ,11 , u8g2_logo_97x51_width, u8g2_logo_97x51_height, u8g2_logo_97x51_bits);
u8g2.setBusClock() —— 设置总线时钟
1 2 3 4 5 6 void U8G2::setBusClock (uint32_t clock_speed) ;
仅仅Arduino平台支持;
必须在u8g2.begin() 或者 u8g2.initDisplay()之前调用;
u8g2.setClipWindow() —— 设置采集窗口大小
1 2 3 4 5 6 7 8 9 10 void U8G2::setClipWindow (u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t x1, u8g2_uint_t y1 ) ;
可以通过 setMaxClipWindow 去掉该限制
1 void U8G2::setMaxClipWindow (void )
1 2 3 u8g2.setClipWindow(10 , 10 , 85 , 30 ); u8g2.setDrawColor(1 ); u8g2.drawStr(3 , 32 , "U8g2" );
u8g2.setCursor() —— 设置绘制光标位置
1 2 3 4 5 void U8G2::setCursor (u8g2_uint_t x, u8g2_uint_t y)
1 2 3 u8g2.setFont(u8g2_font_ncenB14_tr); u8g2.setCursor(0 , 15 ); u8g2.print("Hello World!" );
u8g2.setDisplayRotation() —— 设置显示器的旋转角度
1 2 3 4 5 6 7 8 9 10 void setDisplayRotation (const u8g2_cb_t *u8g2_cb)
u8g2.setDrawColor() —— 设置绘制颜色
1 2 3 4 void U8G2::setDrawColor (uint8_t color)
u8g2.setFont() —— 设置字体集
1 2 3 4 5 6 void U8G2::setFont (const uint8_t *font)
中文字符集消耗内存大,请谨慎使用,可以用在Arduino 101等ram空间比较大的板子上;
u8g2.setFontDirection() —— 设置字体方向
1 2 3 4 5 6 void U8G2::setFontDirection (uint8_t dir)
Argument
String Rotation
Description
0
0 degree
Left to right
1
90 degree
Top to down
2
180 degree
Right to left
3
270 degree
Down to top
1 2 3 4 5 u8g2.setFont(u8g2_font_ncenB14_tf); u8g2.setFontDirection(0 ); u8g2.drawStr(15 , 20 , "Abc" ); u8g2.setFontDirection(1 ); u8g2.drawStr(15 , 20 , "Abc" );
缓存相关函数
缓存相关函数,一般不会去操作
u8g2.getBufferPtr() —— 获取缓存空间的地址
1 2 3 4 5 6 uint8_t *U8G2::getBufferPtr (void )
缓存大小等于 8 * u8g2.getBufferTileHeight() * u8g2.getBufferTileWidth().
u8g2.getBufferTileHeight() —— 获取缓冲区的Tile高度
1 2 3 4 5 uint8_t U8G2::getBufferTileHeight (void )
u8g2.getBufferTileWidth() —— 获取缓冲区的Tile宽度
1 2 3 4 5 uint8_t U8G2::getBufferTileWidth (void )
u8g2.getBufferCurrTileRow() —— 获取缓冲区的当前Tile row
1 2 3 4 5 uint8_t U8G2::getBufferCurrTileRow (void )
u8g2.setBufferCurrTileRow() —— 设置缓冲区的当前Tile row
1 2 3 4 5 void U8G2::setBufferCurrTileRow (uint8_t row)
在 firstPage/nextPage 循环时,由于底层调用了setBufferCurrTileRow,所以尽量不要自己手动调用该方法
1 2 3 4 5 6 7 8 9 u8g2.setBufferCurrTileRow(0 ); u8g2.clearBuffer(); u8g2.setFont(u8g2_font_helvB08_tr); u8g2.drawStr(2 , 8 , "abcdefg" ); u8g2.setBufferCurrTileRow(2 ); u8g2.sendBuffer(); u8g2.setBufferCurrTileRow(4 ); u8g2.sendBuffer();