功能介绍
OLED(Organic Light-Emitting Diode)显示屏是利用有机电自发光二极管制成的显示屏。由于同时具备自发光有机电激发光二极管,不需背光源、对比度高、厚度薄、视角广、反应速度快等优点。
0.96 OLED显示模块的显示尺寸是0.96寸,像素分辨率是128x64像素,可以用于显示数字、字母、汉字、图片等信息。0.96 OLED显示模块实物如图3.20.1所示。显示一个汉字的最小像素分辨率需要16x16像素,所以,128x64分辨率最多可以显示8x4个汉字。

图3.20.1 0.96 OLED显示模块实物图
0.96 OLED显示模块,常见的驱动芯片是SSD1306,模块接口有4针和7针接口,4针接口是IIC的通信方式,7针接口是SPI的通讯方式。在此推荐使用IIC通信方式的4针接口。0.96寸的OLED显示模块只是常见的尺寸,还有其他不同显示分辨率和大小的显示模块,使用时根据实际需要选择,在此我们以IIC通信方式的0.96寸、128x64分辨率为例介绍,本模块的供电电压为DC3.3V-5V。因为采用IIC通信方式,在IIC总线上的所有设备都有唯一的地址,常见的OLED显示模块的实际地址是0x78或者0x7A,在生产厂商的资料中一般会给出这个地址,还有部分的模块可以通过跳线选择地址,使用时需要注意这个IIC的地址,地址不对,通信就没办法完成。在Arduino编程时,库函数做了IIC地址的处理,使用时需要设置地址为0x3c或者0x3d,常见的0.96寸OLED显示屏的默认地址都是0x3c,在不清楚IIC地址的情况下,首选0x3c测试。
接线说明
| Arduino | 0.96 OLED显示模块(IIC) | 说明 |
|---|---|---|
| VCC/+/5V | VCC/+/5V | 供电引脚 |
| GND/G/- | GND/G/- | 电源地线 |
| A4 | SDA | IIC接口的数据线 |
| A5 | SCL | IIC接口的时钟线 |
使用说明:
1.按照接线说明完成接线,注意供电引脚必须连接正确。注意,此时通电OLED显示屏是不会有任何变化的,原因就是OLED是自发光显示方式,不需要背光灯,所以没有显示信息的时候显示屏上不会有任何变化。
2.通过查看本模块厂家资料,找到IIC通信地址,记下这个地址。
3(a).Arduino IDE 编程
采用Arduino IDE编程时,需要调用到库文件,OLED的库文件有很多,可以在工具菜单中的“库管理器”中自行搜索使用。在此推荐两个库“Adafruit_SSD1306”和“CN_SSD1306_Wire”。“Adafruit_SSD1306”即可满足画线、画圆等图形界面的设计,还可已实现特定图片的显示以及ASICC的显示。如果使用时需要显示中文字符,推荐使用“CN_SSD1306_Wire”库,此库目前在“库管理器”中搜索不到,可以自行到网络上搜索。
3(b).Mixly编程
使用Mixly编程时,OLED显示屏程序模块在“显示器”—>“显示屏”下,展开“显示屏”后,里面有多个显示屏的初始化程序模块,在此我们需要选择“初始化SSD1306(12864)…”程序模块,如图3.20.2所示,此模块是必须模块,是用来初始化OLED的硬件连接等一些基础设置的。在这个程序模块中,第一个参数“SDD1306(12864)”是现在显示屏的型号及显示屏的分辨率,在此我们默认就好;第二个参数“u8g2”是显示屏的名称,可以根据需要修改,在此我们以默认设置为易;第三个参数屏幕旋转的度数,非必要不用设置,默认旋转零度设置;第四、第五两个参数是OLED显示屏和Arduino的硬件连接设置,我们默认OLED屏采用IIC接口连接,采用默认就好;最后一个参数设备地址默认是0x3C,在此默认就好,除非你知道如何设置显示屏上的地址选择跳线。
图3.20.2 OLED显示屏初始化程序模块
如图3.20.2所示,初始化模块下方还有一句语句“显示屏u8g2刷新显示页面page1”,这里的“page1”是我们实际需要显示的程序模块所在的地方,在展开的“显示屏”程序模块中,有一个紫色的程序块“page1”,如图3.20.3所示。默认程序块中有两条程序块,分别是设置显示的字体字号和显示的实际文本信息。在实际使用时,我们需要根据需要修改内部的程序实现我们所想要得显示效果,具体使用方法请参照参考程序。还有很多正对OLED显示屏的程序模块,比如汉字显示、图片显示、画圆、画线等基础的GUI程序模块,使用时可以根据需求自行选择。
图3.20.3 OLED显示程序模块
参考程序:
Arduino IDE参考程序
/***************************************************************************@mainpage Arduino库,用于基于SSD1306驱动程序的单色OLED。------> http://www.adafruit.com/category/63_98是一个基于SSD1306驱动程序的单色OLED示例**************************************************************************/#include <SPI.h>#include <Wire.h>#include <Adafruit_GFX.h>#include <Adafruit_SSD1306.h>#define SCREEN_WIDTH 128 // OLED 显示屏横向(宽)的像素点数量#define SCREEN_HEIGHT 64 // OLED 显示屏纵向(高)的像素点数量// 创建一个IIC接口的一个OLED对象,名称是display#define OLED_RESET 4 // Reset 引脚,默认就好Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);#define NUMFLAKES 10 // 动画示例中雪花的数量#define LOGO_HEIGHT 16#define LOGO_WIDTH 16static const unsigned char PROGMEM logo_bmp[] ={ B00000000, B11000000,B00000001, B11000000,B00000001, B11000000,B00000011, B11100000,B11110011, B11100000,B11111110, B11111000,B01111110, B11111111,B00110011, B10011111,B00011111, B11111100,B00001101, B01110000,B00011011, B10100000,B00111111, B11100000,B00111111, B11110000,B01111100, B11110000,B01110000, B01110000,B00000000, B00110000 };void setup() {Serial.begin(9600);// 显示屏采用内部3.3V电压,IIC地址是0x3cif(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c)) {Serial.println(F("SSD1306 allocation failed"));for(;;); // 如果失败,则一直循环,不会进入继续向下}// 显示缓冲区内的内容display.display();delay(2000);//清除缓冲区内容display.clearDisplay();//点亮两个像素点,白色(100,10)(101,10)display.drawPixel(100, 10, SSD1306_WHITE);display.drawPixel(101, 10, SSD1306_WHITE);// 显示缓冲区内容,需要调用display.display();display.display();delay(2000);testdrawline(); // 画线,很多线testdrawrect(); // 绘制矩形轮廓testfillrect(); // 绘制矩形(填充)testdrawcircle(); // 画圆(轮廓)testfillcircle(); // 画圆(填充)testdrawroundrect(); // 绘制圆角矩形(轮廓)testfillroundrect(); // 绘制圆角矩形(填充)testdrawtriangle(); // 绘制三角形(轮廓)testfilltriangle(); // 绘制三角形(填充)testdrawchar(); // 绘制默认字体的字符 ASICC码表显示testdrawstyles(); // 绘制“样例”字符testscrolltext(); // 显示滚动文本testdrawbitmap(); // 画一个小位图图像// 反转并恢复显示,中间暂停display.invertDisplay(true);delay(1000);display.invertDisplay(false);delay(1000);testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); //设置位图动画,内部已经循环}void loop() {}//############################// 画线,很多线//############################void testdrawline() {int16_t i;display.clearDisplay(); // 清除显示缓冲区for(i=0; i<display.width(); i+=4) {display.drawLine(0, 0, i, display.height()-1, SSD1306_WHITE);display.display(); // 更新显示delay(1);}for(i=0; i<display.height(); i+=4) {display.drawLine(0, 0, display.width()-1, i, SSD1306_WHITE);display.display();delay(1);}delay(250);display.clearDisplay();for(i=0; i<display.width(); i+=4) {display.drawLine(0, display.height()-1, i, 0, SSD1306_WHITE);display.display();delay(1);}for(i=display.height()-1; i>=0; i-=4) {display.drawLine(0, display.height()-1, display.width()-1, i, SSD1306_WHITE);display.display();delay(1);}delay(250);display.clearDisplay();for(i=display.width()-1; i>=0; i-=4) {display.drawLine(display.width()-1, display.height()-1, i, 0, SSD1306_WHITE);display.display();delay(1);}for(i=display.height()-1; i>=0; i-=4) {display.drawLine(display.width()-1, display.height()-1, 0, i, SSD1306_WHITE);display.display();delay(1);}delay(250);display.clearDisplay();for(i=0; i<display.height(); i+=4) {display.drawLine(display.width()-1, 0, 0, i, SSD1306_WHITE);display.display();delay(1);}for(i=0; i<display.width(); i+=4) {display.drawLine(display.width()-1, 0, i, display.height()-1, SSD1306_WHITE);display.display();delay(1);}delay(2000); // Pause for 2 seconds}//###########################// 绘制矩形轮廓testdrawrect();//###########################void testdrawrect(void) {display.clearDisplay();for(int16_t i=0; i<display.height()/2; i+=2) {display.drawRect(i, i, display.width()-2*i, display.height()-2*i, SSD1306_WHITE);display.display(); // Update screen with each newly-drawn rectangledelay(1);}delay(2000);}//###########################// testfillrect(); // 绘制矩形(填充)//###########################void testfillrect(void) {display.clearDisplay();for(int16_t i=0; i<display.height()/2; i+=3) {// 使用反向颜色,使矩形交替为白色/黑色display.fillRect(i, i, display.width()-i*2, display.height()-i*2, SSD1306_INVERSE);display.display();delay(1);}delay(2000);}//############################// 画圆(轮廓) testdrawcircle();//############################void testdrawcircle(void) {display.clearDisplay();for(int16_t i=0; i<max(display.width(),display.height())/2; i+=2) {display.drawCircle(display.width()/2, display.height()/2, i, SSD1306_WHITE);display.display();delay(1);}delay(2000);}//############################// 画圆(填充) testfillcircle();//############################void testfillcircle(void) {display.clearDisplay();for(int16_t i=max(display.width(),display.height())/2; i>0; i-=3) {// 反转色,实现黑白显示display.fillCircle(display.width() / 2, display.height() / 2, i, SSD1306_INVERSE);display.display();delay(1);}delay(2000);}//############################// 绘制圆角矩形(轮廓) testdrawroundrect();//############################void testdrawroundrect(void) {display.clearDisplay();for(int16_t i=0; i<display.height()/2-2; i+=2) {display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i,display.height()/4, SSD1306_WHITE);display.display();delay(1);}delay(2000);}//############################// 绘制圆角矩形(填充)testfillroundrect();//############################void testfillroundrect(void) {display.clearDisplay();for(int16_t i=0; i<display.height()/2-2; i+=2) {// 使用反向颜色,黑白交替显示display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i,display.height()/4, SSD1306_INVERSE);display.display();delay(1);}delay(2000);}//############################// 绘制三角形(轮廓) testdrawtriangle();//############################void testdrawtriangle(void) {display.clearDisplay();for(int16_t i=0; i<max(display.width(),display.height())/2; i+=5) {display.drawTriangle(display.width()/2 , display.height()/2-i,display.width()/2-i, display.height()/2+i,display.width()/2+i, display.height()/2+i, SSD1306_WHITE);display.display();delay(1);}delay(2000);}//############################// 绘制三角形(填充) testfilltriangle();//############################void testfilltriangle(void) {display.clearDisplay();for(int16_t i=max(display.width(),display.height())/2; i>0; i-=5) {// 使用反向颜色,使三角形交替为白色/黑色display.fillTriangle(display.width()/2 , display.height()/2-i,display.width()/2-i, display.height()/2+i,display.width()/2+i, display.height()/2+i, SSD1306_INVERSE);display.display();delay(1);}delay(2000);}//############################// 绘制默认字体的字符 ASICC码表显示 testdrawchar();//############################void testdrawchar(void) {display.clearDisplay();display.setTextSize(1); // 显示字号1display.setTextColor(SSD1306_WHITE); // 白色显示display.setCursor(0, 0); // 初始坐标display.cp437(true); // 使用完整的256字符“代码页437”字体// Not all the characters will fit on the display. This is normal.// Library will draw what it can and the rest will be clipped.for(int16_t i=0; i<256; i++) {if(i == '\n') display.write(' ');else display.write(i);}display.display();delay(2000);}//############################// 显示ASICC字符 testdrawstyles();//############################void testdrawstyles(void) {display.clearDisplay();display.setTextSize(1); // 显示字号1display.setTextColor(SSD1306_WHITE); // 白色显示display.setCursor(0,0); // 显示起始坐标display.println(F("Hello, world!"));display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // 显示反向文本display.println(3.141592,7);//显示3.14,7个有效数字display.setTextSize(2); // 显示字号2display.setTextColor(SSD1306_WHITE);//显示十六进制数display.print(F("0x"));display.println(0xDEADBEEF, HEX);display.display();delay(2000);}//############################// 显示滚动文本 testscrolltext();//############################void testscrolltext(void) {display.clearDisplay();display.setTextSize(2); // 显示字号为2display.setTextColor(SSD1306_WHITE);display.setCursor(0, 0);//起始显示坐标display.println(F("Arduino"));display.display(); // Show initial textdelay(100);// 滚动显示display.startscrollright(0x00, 0x0f);delay(2000);display.stopscroll();delay(1000);display.startscrollleft(0x00, 0x0f);delay(2000);display.stopscroll();delay(1000);display.startscrolldiagright(0x00, 0x07);delay(2000);display.startscrolldiagleft(0x00, 0x07);delay(2000);display.stopscroll();delay(1000);}//############################// 画一个小位图图像 testdrawbitmap();//############################void testdrawbitmap(void) {display.clearDisplay();display.drawBitmap((display.width() - LOGO_WIDTH ) / 2,(display.height() - LOGO_HEIGHT) / 2,logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);display.display();delay(1000);}#define XPOS 0#define YPOS 1#define DELTAY 2//############################//设置位图动画 testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT);//############################void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {int8_t f, icons[NUMFLAKES][3];// 初始化雪花片的位置for(f=0; f< NUMFLAKES; f++) {icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());icons[f][YPOS] = -LOGO_HEIGHT;icons[f][DELTAY] = random(1, 6);Serial.print(F("x: "));Serial.print(icons[f][XPOS], DEC);Serial.print(F(" y: "));Serial.print(icons[f][YPOS], DEC);Serial.print(F(" dy: "));Serial.println(icons[f][DELTAY], DEC);}for(;;) { // 死循环display.clearDisplay(); // 清除显示// 绘制每个雪花for(f=0; f< NUMFLAKES; f++) {display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, SSD1306_WHITE);}display.display(); // Show the display buffer on the screendelay(200); // Pause for 1/10 second// 更新每个雪花的坐标for(f=0; f< NUMFLAKES; f++) {icons[f][YPOS] += icons[f][DELTAY];// 雪花落到底部if (icons[f][YPOS] >= display.height()) {// Reinitialize to a random position, just off the topicons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());icons[f][YPOS] = -LOGO_HEIGHT;icons[f][DELTAY] = random(1, 6);}}}}
本例程是库文件中的示例程序,实现显示LOGO图片,完成画线,画圆,画矩形等图形的绘制,最后循环显示多片雪花下落的动画。
Mixly参考程序

此例程实现了再OLED显示屏上显示一个横向的三角符号,并在坐标位(40,30)处显示了一个变量的值,此变量将会每500ms自动加一。在显示过程中,当变量值小于等于10的时候,显示的横向三角形是向左的,大于10后,横向三角形变为向右显示。
