医疗电子技术网|技术阅读
登录|注册

您现在的位置是:医疗电子技术网 > 技术阅读 > 分享一个OLED上的简易图形库(附源代码)

分享一个OLED上的简易图形库(附源代码)


类似封面这种128x64的OLED屏,大家有用过吗?
我以前用这种OLED屏开发过几款产品,当时设计产品需求比较简单,界面除了简易的图形之外,就是文字信息,都是自己设计的UI界面。
今天给大家分享一下用128x64 OLED做的温度显示界面,如下图:


1

介绍该128x64 OLED为单色显示屏,基于SSD1306驱动器芯片的OLED显示器。
这种128x64 OLED常见有0.96寸的,也有1.3英寸的,以前有的客户嫌0.96寸太小,所以就用了1.3英寸的屏幕,但价格略贵一点。
在这种类型的显示器上执行图形命令的通常方法是使用RAM缓冲区:将所有图形绘制到该缓冲区中。然后,当你要更新显示时,将整个缓冲区复制到显示中。
和这种模组通信,有I2C,也有SPI,具体看你需求。
显示大小和坐标:128x64,顾名思义就是横坐标128个点,纵坐标64个点,图形库假定原点(0,0)在左下角,因此右上角是(127,63)。
显示屏分为八个8像素高频段,称为页面,一个字节对应于8像素的垂直列,其位顺序如下图所示:
下面开始讲述图形库:


2

API接口说明

底层的通信和驱动,这里就不描述了,讲述主要的API接口:


ClearDisplay():清除显示。
InitDisplay():初始化显示。
PlotPoint(x,y):在(x,y)处绘制一个点。
MoveTo(x,y):将绘图位置移动到(x,y)。
DrawTo(x,y):从绘图位置到(x,y)画一条线。
PlotCharacter(c,x,y):绘制ASCII字符c,坐标为(x,y)。
PlotText(s):从当前绘图位置开始,绘制缓存中的文本字符串。


3

API源码

1.InitDisplay()初始化显示

void InitDisplay () { Wire.beginTransmission(address); Wire.write(commands); Wire.write(0xA1); Wire.write(0xAF); Wire.endTransmission();}


2.single()写命令
void Single (uint8_t x) { Wire.write(onecommand); Wire.write(x);}
3.ClearDisplay() 清楚显示
void ClearDisplay () { for (int p = 0 ; p < 8; p++) { Wire.beginTransmission(address); Single(0xB0 + p); Wire.endTransmission(); for (int q = 0 ; q < 8; q++) { Wire.beginTransmission(address); Wire.write(data); for (int i = 0 ; i < 20; i++) Wire.write(0); Wire.endTransmission(); } }}
4.PlotPoint()画一个点
void PlotPoint (int x, int y) { Wire.beginTransmission(address); //地址 Single(0x00 + ((x + 2) & 0x0F)); Single(0x10 + ((x + 2)>>4));  Single(0xB0 + (y >> 3)); Single(0xE0); //读取并修改写入 Wire.write(onedata); Wire.endTransmission(); Wire.requestFrom(address, 2); Wire.read(); int j = Wire.read(); Wire.beginTransmission(address); Wire.write(onedata); Wire.write((1<<(y & 0x07)) | j); Single(0xEE); // Cancel read modify write Wire.endTransmission();}
5.MoveTo()移动绘图位置
void MoveTo (int x, int y) { x0 = x; y0 = y;}
6.DrawTo() 画一条线
void DrawTo (int x, int y) { int sx, sy, e2, err; int dx = abs(x - x0); int dy = abs(y - y0); if (x0 < x) sx = 1; else sx = -1; if (y0 < y) sy = 1; else sy = -1; err = dx - dy; for (;;) { PlotPoint(x0, y0); if (x0==x && y0==y) return; e2 = err<<1; if (e2 > -dy) { err = err - dy; x0 = x0 + sx; } if (e2 < dx) { err = err + dx; y0 = y0 + sy; } }}
7.PlotChar()写一个字符
void PlotChar (int c, int x, int y) { int h = y & 0x07; for (int p = 0; p < 2; p++) { Wire.beginTransmission(address); Single(0xB0 + (y >> 3) + p); // Page for (int col=0; col<6; col++) { Single(0x00 + ((x+2+col) & 0x0F)); // Column low nibble Single(0x10 + ((x+2+col)>>4)); // Column high nibble Single(0xE0); // Read modify write Wire.write(onedata); Wire.endTransmission(); Wire.requestFrom(address, 2); Wire.read(); // Dummy read int j = Wire.read(); Wire.beginTransmission(address); Wire.write(onedata); int bits = ReverseByte(pgm_read_byte(&CharMap[c-32][col])); Wire.write((bits<<h)>>(p<<3) | j); Single(0xEE); // Cancel read modify write } Wire.endTransmission(); }}
7.PlotText() 写文本
void PlotText(PGM_P s) { int p = (int)s; while (1) { char c = pgm_read_byte(p++); if (c == 0) return; PlotChar(c, x0, y0); x0 = x0 + 6; }}


3

实例1.说明本例程为简单Demo:15分钟记录一次温度,并将其绘制在显示屏上,精度为0.5°C。
电路:
2.Demo程序
const int Now = 1547; // 比如设置时间为:15:47unsigned long StartMins = (unsigned long)((Now/100)*60 + (Now%100));
void loop () { unsigned int SampleNo = StartMins/15;   // 绘制温度图 int x1 = 16, y1 = 11; int yscale = 2; MoveTo(26, 56); PlotText(PSTR("Temperature ~C")); //横轴 MoveTo(x1, y1); DrawTo(x1+96, y1); for (int i=0; i<=24; i=i+4) { int mark = x1+i*4; MoveTo(mark, y1); DrawTo(mark, y1-2); int tens = i/10; if (tens != 0) { PlotChar(tens+'0', mark-6, y1-12); PlotChar(i%10+'0', mark, y1-12); } else PlotChar(i%10+'0', mark-3, y1-12); } //纵轴 MoveTo(x1, y1); DrawTo(x1, y1+50); for (int i=5; i<=25; i=i+5) { int mark = y1+i*yscale-10; MoveTo(x1, mark); DrawTo(x1-2, mark); int tens = i/10; if (tens != 0) PlotChar(tens+'0', x1-15, mark-3); PlotChar(i%10+'0', x1-9, mark-3); } for (;;) {    //每15分钟更新一下 while ((unsigned long) ((StartMins + millis()/60000)/15)%96 == SampleNo); // Time to take a new reading SampleNo = (SampleNo+1)%96;    int Temperature = (analogRead(A2)*25)/233; PlotPoint(SampleNo+x1, Temperature-10+y1); }}
结合Demo例子是不是很简单,分享本文目的是为了让大家多借鉴别人的一些设计思路,自己开发产品的时候不至于陷入僵局。
如果大家喜欢,我争取今后多分享一些类似小例子,为大家提供一些设计思路。

~END~

版权声明:文章转自网络。版权归原作者所有,如有侵权,请联系我们删除!


关注我们,收获更多电子技术

好文推荐

【点击图片阅读】






您的点赞和在看,是对我最大的鼓励!