使用U8g2库进行OLED的显示十分简单,首先要包含两个库,U8g2lib和Wire,后者是IIC通信需要用。
对于IIC接口的OLED,需要在程序中指定一下引脚的接口定义,如果是SPI接口,可以参考U8g2库自带例程中SPI接口是使用方法。




在Ardunio的setup中进行u8g2的初始化。
#include
#include #define SCL 5
#define SDA 4U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /*clock=*/SCL, /*data=*/SDA, /*reset=*/U8X8_PIN_NONE); void setup()
{u8g2.begin();
} 初始化显示器, 清屏, 唤醒屏幕
/*** 初始化U8g2库* @Note 关联方法 initDisplay clearDisplay setPowerSave*/
bool U8G2::begin(void)只是初始化显示器, 并不清屏, 也不唤醒屏幕
/**
* 初始化显示控制器
*/
void U8G2::initDisplay(void)
/*** 清除屏幕*/
void U8G2::clearDisplay(void)/*** 清除显示缓冲区* @param is_enable* 1 表示启用显示器的省电模式,屏幕上看不到任何东西* 0 表示禁用省电模式*/
void U8G2::setPowerSave(uint8_t is_enable)/*** 清除屏幕显示,清除缓冲区,光标回到左上角原点位置(0,0)* @Note 关联方法 home clearDisplay clearBuffer*/
void U8G2::clear(void)/*** 清除内存中数据缓冲区*/
void U8G2::clearBuffer(void)/*** 禁用Arduino平台下支持输出UTF8字符集,默认是开启*/
void U8G2::disableUTF8Print(void)/*** 开启Arduino平台下支持输出UTF8字符集*/
void U8G2::enableUTF8Print(void)开启UTF-8后,我们可以使用其UTF-8字库
#include
#include U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE, /* clock=*/22, /* data=*/21); // ESP32 Thing, HW I2C with pin remappingvoid setup(void)
{u8g2.begin();u8g2.enableUTF8Print(); // enable UTF8 support for the Arduino print() function
}
void loop(void)
{u8g2.setFont(u8g2_font_unifont_t_chinese2); // use chinese2u8g2.firstPage();do{u8g2.setCursor(0, 20);u8g2.print("helloworld"); // Chinese "Hello World"u8g2.setCursor(0, 40);u8g2.print("你好世界"); // Chinese "Hello World"} while (u8g2.nextPage());delay(1000);
} /*** 重置显示光标的位置,回到原点(0,0)* @Note 关联方法 print clear*/
void U8G2::home(void)在Ardunio的loop中编写自己想要的代码逻辑,温馨提醒,在U8g2库在loop中的通用写法是使用do{}while()的形式:
u8g2.firstPage();do{//自己的的逻辑} while (u8g2.nextPage());delay(1000);font:u8g2的字体,比较常用的有u8g2_font_unifont_t_symbols(通常使用这个)和u8g2_font_wqy12_t_gb2312b(用于显示汉字)等
num:启用(1)透明模式
num:禁用(0)透明模式
color:0(显示RAM中的清晰像素值)
color:1(设置像素值)
color:2(异或模式)
x、y:像素点的坐标
例如我们可以显示所有的点:
#include
#include #define SCL 5
#define SDA 4
//定义了一个宏定义,用于延时显示每一次的画图,方便观察OLED的显示过程:
#define SEND_BUFFER_DISPLAY_MS(ms)\do {\u8g2.sendBuffer(); \delay(ms);\}while(0);U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /*clock=*/SCL, /*data=*/SDA, /*reset=*/U8X8_PIN_NONE); void setup()
{u8g2.begin();u8g2.enableUTF8Print(); // enable UTF8 support for the Arduino print() function
}//画像素点-填充屏幕
void testDrawPixelToFillScreen()
{int t = 1000;u8g2.clearBuffer();for (int j = 0; j < 64; j++){for (int i = 0; i < 128; i++){u8g2.drawPixel(i, j);}}SEND_BUFFER_DISPLAY_MS(t);
}
void loop()
{testDrawPixelToFillScreen();} x0,y0线的起点
x1,y1线的终点
x,y线的起点
w水平线的长度(宽度)
x,y线的起点
h竖直线的长度(高度)
//画直线
void testDrawLine()
{int t = 500;u8g2.clearBuffer();u8g2.drawStr(33, 14, "drawLine");u8g2.drawLine(0, 0, 127, 63);SEND_BUFFER_DISPLAY_MS(t);u8g2.drawLine(0, 0, 127, 0);SEND_BUFFER_DISPLAY_MS(t);u8g2.drawLine(32, 15, 127, 15);SEND_BUFFER_DISPLAY_MS(t);u8g2.drawLine(33, 16, 127, 16);SEND_BUFFER_DISPLAY_MS(t);u8g2.drawLine(127, 0, 127, 15);SEND_BUFFER_DISPLAY_MS(t);u8g2.drawLine(127, 16, 127, 63);SEND_BUFFER_DISPLAY_MS(t);
}x,y起点坐标
w,h框的宽度和高度
r圆角的半径
//画空心圆角矩形
void testDrawRFrame()
{int t = 500;int x = 16;int y = 32;int w = 50;int h = 20;int r = 3;u8g2.clearBuffer();u8g2.drawStr(0, 15, "drawRFrame");u8g2.drawRFrame(x, y, w, h, r);SEND_BUFFER_DISPLAY_MS(t);u8g2.drawRFrame(x+w+5, y-10, w-20, h+20, r);SEND_BUFFER_DISPLAY_MS(t);
}x,y为圆心坐标
rad为圆的半径
opt为选择画的部分,分为:
U8G2_DRAW_UPPER_RIGHT(右上)
U8G2_DRAW_UPPER_LEFT(左上)
U8G2_DRAW_LOWER_LEFT(左下)
U8G2_DRAW_LOWER_RIGHT(右下)
U8G2_DRAW_ALL(全部)
空心圆:
//画空心圆
void testDrawCircle()
{int t = 500;int stx = 0; //画图起始xint sty = 16; //画图起始yint with = 16;//一个图块的间隔int r = 15; //圆的半径u8g2.clearBuffer();u8g2.drawStr(0, 15, "drawCircle");u8g2.drawCircle(stx, sty - 1 + with, r, U8G2_DRAW_UPPER_RIGHT); //右上SEND_BUFFER_DISPLAY_MS(t);u8g2.drawCircle(stx + with, sty, r, U8G2_DRAW_LOWER_RIGHT); //右下SEND_BUFFER_DISPLAY_MS(t);u8g2.drawCircle(stx - 1 + with * 3, sty - 1 + with, r, U8G2_DRAW_UPPER_LEFT); //左上SEND_BUFFER_DISPLAY_MS(t);u8g2.drawCircle(stx - 1 + with * 4, sty, r, U8G2_DRAW_LOWER_LEFT); //左下SEND_BUFFER_DISPLAY_MS(t);u8g2.drawCircle(stx - 1 + with * 2, sty - 1 + with * 2, r, U8G2_DRAW_ALL);//整个圆SEND_BUFFER_DISPLAY_MS(t);
}
注意,U8g2库画出的圆,因像素点的显示原理,圆的直径占用的宽度不是半径的2倍,而是2倍再加一个像素点。
x,y为圆心坐标
rx,ry为与椭圆x和y方向的半径
opt与画圆时的作用一致
椭圆的显示与圆的显示类似,只是椭圆可以分别指定x和y方向的半径
字符串的显示,可以使用drawStr函数,也可以使用通用风格的print函数。
x,y起点坐标
string字符串
需要先设置字体,调用setFont方法;
这个方法不能绘制encoding超过256的,超过256需要用drawUTF8或者drawGlyph;说白了就是一般用来显示英文字符;
如果想要使用print显示汉子,需要先设置如下两句:
u8g2.enableUTF8Print();//enable UTF8
u8g2.setFont(u8g2_font_wqy12_t_gb2312b);//设置中文字符集如果想要显示变量,使用print函数即可。
//字符串/文字/变量显示测试
void testDrawStr()
{int t = 1000;u8g2.clearBuffer();u8g2.setFont(u8g2_font_wqy12_t_gb2312b);//设置中文字符集u8g2.drawStr(0, 14, "drawStr / print");SEND_BUFFER_DISPLAY_MS(t);u8g2.drawStr(0, 32, "~!@#$%^&*()_+");SEND_BUFFER_DISPLAY_MS(t);u8g2.enableUTF8Print();//enable UTF8u8g2.setFont(u8g2_font_wqy12_t_gb2312b);//设置中文字符集u8g2.setCursor(0, 48);u8g2.print("码农爱学习");SEND_BUFFER_DISPLAY_MS(t);int a = 234;u8g2.setCursor(0, 64);u8g2.print("int a = ");u8g2.setCursor(40, 64);u8g2.print(a);//显示变量SEND_BUFFER_DISPLAY_MS(t);
}x,y起点坐标
addr内置图标的地址
U8g2库内置了需要预先定义的图形,通过drawGlyp函数以及指定的地址,即可看OLED上显示对应的图标:
各个图形的地址定义如下:

void testGlyph()
{int t = 1000;u8g2.clearBuffer();u8g2.drawStr(0, 14, "drawGlyph");u8g2.drawGlyph(0, 32, 0x23f0);SEND_BUFFER_DISPLAY_MS(t);u8g2.drawGlyph(16, 32, 0x23f3);SEND_BUFFER_DISPLAY_MS(t);u8g2.drawGlyph(32, 32, 0x2603);SEND_BUFFER_DISPLAY_MS(t);u8g2.drawGlyph(48, 32, 0x2615);SEND_BUFFER_DISPLAY_MS(t);u8g2.drawGlyph(64, 32, 0x2618);SEND_BUFFER_DISPLAY_MS(t);
}x,y起点坐标
w,h图片的宽度和高度`
addr图片(数组)的地址
// width: 128, height: 48
const unsigned char bilibili[] U8X8_PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ... 省略若干行 };void testDrawXBM()
{int t = 1000;u8g2.clearBuffer();u8g2.drawStr(0, 14, "drawXBM");u8g2.drawXBM(0, 16, 128, 48, bilibili);SEND_BUFFER_DISPLAY_MS(t);
}/*** 获取基准线以上的高度* @return 返回高度值* @Note 关联方法 setFont getDescent setFontRefHeightAll*/
int8_t U8G2::getAscent(void)跟字体有关(setFont)
示例:下面例子,ascent是18

/*** 获取基准线以下的高度* @return 返回高度值* @Note 关联方法 setFont setFontRefHeightAll*/
int8_t U8G2::getDescent(void)跟字体有关(setFont);
示例:下面例子,descent是-5

/*** 获取显示器的宽度* @return 返回宽度值*/
u8g2_uint_t getDisplayWidth(void) /*** 获取显示器的宽度* @return 返回宽度值*/
u8g2_uint_t getDisplayWidth(void)/*** 获取当前字体里的最大字符的高度* @return 返回高度值* @Note 关联方法 setFont*/
u8g2_uint_t getMaxCharHeight(void)/*** 获取当前字体里的最大字符的宽度* @return 返回宽度值* @Note 关联方法 setFont*/
u8g2_uint_t getMaxCharWidth(void)/*** 获取字符串的像素宽度* @param s 绘制字符串* @return 返回字符串的像素宽度值* @Note 关联方法 setFont drawStr*/
u8g2_uint_t U8G2::getStrWidth(const char *s)/*** 获取UTF-8字符串的像素宽度* @param s 绘制字符串* @return 返回字符串的像素宽度值* @Note 关联方法 setFont drawStr*/
u8g2_uint_t U8G2::getUTF8Width(const char *s)/*** 是否自动清除缓冲区* @param mode 0 表示关闭* 1 表示开启,默认是开启*/
void U8G2::setAutoPageClear(uint8_t mode)建议该方法保持默认就好,如果用户禁止了,那么需要自己维护缓冲区的状态或者手动调用clearBuffer;
/*** 设置位图模式(定义drawXBM方法是否绘制背景颜色)* @param is_transparent* 0 绘制背景颜色,不透明,默认是该值* 1 不绘制背景颜色,透明* @Note 关联方法 drawXBM*/
void U8G2::setBitmapMode(uint8_t is_transparent)/*** 设置总线时钟(I2C SPI)* @param mode clock_speed 总线时钟频率(Hz)* @Note 关联方法 begin*/
void U8G2::setBusClock(uint32_t clock_speed);仅仅Arduino平台支持;
必须在u8g2.begin() 或者 u8g2.initDisplay()之前调用;
/*** 设置采集窗口,窗口范围从左上角(x0,y0)到右下角(x1,y1)* 也就是我们绘制的内容只能在规范范围内显示* @param x0 左上角x坐标* @param y0 左上角y坐标* @param x1 右下角x坐标* @param y1 右下角y坐标* @Note 关联方法 begin*/void U8G2::setClipWindow(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t x1, u8g2_uint_t y1 );可以通过 setMaxClipWindow 去掉该限制
/*** 设置绘制光标位置(x,y)* @Note 关联方法 print*/void U8G2::setCursor(u8g2_uint_t x, u8g2_uint_t y) /*** 设置显示器的旋转角度* @param u8g2_cb 旋转选项* U8G2_R0 不做旋转 水平* U8G2_R1 旋转90度* U8G2_R2 旋转180度* U8G2_R3 旋转270度* U8G2_MIRROR 不做旋转 水平,显示内容是镜像的,暂时不理解*/void setDisplayRotation(const u8g2_cb_t *u8g2_cb) /*** 设置绘制颜色(暂时还没有具体去了解用法)*/void U8G2::setDrawColor(uint8_t color) /*** 设置字体集(字体集用于字符串绘制方法或者glyph绘制方法)* @param font 具体的字体集* @Note 关联方法 drawUTF8 drawStr drawGlyph print*/void U8G2::setFont(const uint8_t *font)启用(1)或禁用(0)透明模式
/*** 定义字符串绘制或者图形绘制的方向* @param dir 方向* @param 关联方法 drawStr*/void U8G2::setFontDirection(uint8_t dir)
/*** 获取缓存空间的地址* @return 返回缓存空间起始地址* @Note 关联方法 getBufferTileHeight, getBufferTileWidth, clearBuffer*/uint8_t *U8G2::getBufferPtr(void) /*** 获取缓冲区的Tile高度* @return 返回高度值*/uint8_t U8G2::getBufferTileHeight(void)一个tile等于8个像素点.
/*** 获取缓冲区的Tile宽度* @return 返回宽度值*/uint8_t U8G2::getBufferTileWidth(void) /*** 获取缓冲区的当前Tile row行数* @return 返回当前的tilerow*/uint8_t U8G2::getBufferCurrTileRow(void)5. u8g2.setBufferCurrTileRow() —— 设置缓冲区的当前Tile row
/*** 设置缓冲区的当前Tile row* @param 当前的tilerow*/void U8G2::setBufferCurrTileRow(uint8_t row)在 firstPage/nextPage 循环时,由于底层调用了setBufferCurrTileRow,所以尽量不要自己手动调用该方法
U8g2支持三种绘制模式:
Full screen buffer mode,全屏缓存模式
Page mode (This is the U8glib picture loop) 分页模式
U8x8, character only mode 仅仅支持普通字符
特点:
绘制速度快
所有的绘制方法都可以使用
需要大量的ram空间
用法:
清除缓冲区 u8g2.clearBuffer()
操作一些绘制方法
发送缓冲区的内容到显示器 u8g2.sendBuffer().
特点:
绘制速度慢
所有的绘制方法都可以使用
需要少量的ram空间
特点:
绘制速度快
并不是对所有的显示器都有效
图形绘制不可用
不需要ram空间
使用U8X8构造器,比如:
U8X8_ST7565_EA_DOGM128_4W_SW_SPI(clock, data, cs, dc [, reset])
下一篇:Nessus介绍与安装