基于单片机OLED简易图形库开发指南(附源代码)
创作时间:
作者:
@小白创作中心
基于单片机OLED简易图形库开发指南(附源代码)
引用
CSDN
1.
https://m.blog.csdn.net/ybhuangfugui/article/details/140704708
本文将介绍如何使用基于SSD1306驱动器的128x64 OLED显示屏进行温度显示界面的开发。通过详细讲解硬件连接、基本概念、API函数说明以及完整的代码示例,帮助读者快速掌握OLED显示屏的使用方法。
硬件介绍
该128x64 OLED为单色显示屏,基于SSD1306驱动器芯片。常见的尺寸有0.96寸和1.3寸,其中1.3寸屏幕虽然显示效果更好,但价格略贵。
这种显示屏支持I2C和SPI两种通信方式,具体选择取决于实际需求。
显示大小和坐标
128x64显示屏的坐标系统如下:
- 横坐标范围:0-127
- 纵坐标范围:0-63
- 原点(0,0)位于左下角
显示屏分为八个8像素高频段,称为页面,一个字节对应于8像素的垂直列,其位顺序如下图所示:
图形库API说明
初始化和清除显示
void InitDisplay () {
Wire.beginTransmission(address);
Wire.write(commands);
Wire.write(0xA1);
Wire.write(0xAF);
Wire.endTransmission();
}
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();
}
}
}
绘制点和线
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();
}
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; }
}
}
绘制字符和文本
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();
}
}
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;
}
}
实例:温度显示界面
本例程为简单Demo:15分钟记录一次温度,并将其绘制在显示屏上,精度为0.5°C。
电路连接
Demo程序
const int Now = 1547; // 比如设置时间为:15:47
unsigned 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);
}
}
通过这个实例,我们可以看到如何使用上述API函数来实现一个简单的温度显示界面。希望这篇文章能为大家提供一些设计思路,帮助大家在开发类似项目时少走弯路。
热门推荐
AI将如何改变电工职业?未来电工需要掌握哪些技能?
你的膝盖还好吗?探索膝关节炎的奥秘
国家标准:7 个能力域、29 个能力子域,数字化转型的全面指南
老友记第八季:瑞秋生下罗斯的孩子
如何正确放倒后排座位?这种操作有哪些关键步骤和注意事项?
人机协作技能训练方案:协同创新,助力企业智能化升级
五帝钱摆放风水不宜?不挂如何妥善处理?
申请撤销监护人资格的流程与要求
为什么尿毒症越来越多?医生:和烟酒无关,多数是这4件事做多了
交口镇之战:多隆阿入陕后最大的失利,清军兵败黄帝陵
2025年换电车电池新趋势:为何聪明人偏爱铅酸电池?四大理由揭晓
37周产检需要空腹吗?一文读懂产检前的准备事项
机械电子工程是做什么的
聚四氟乙烯(PTFE)涂层技术及其应用领域
废旧动力电池灰色产业链亟待多方协同治理
摄影师花3.5万在北海道买170平米房,为什么北海道房价偏低?
《西江月》写作指南
家庭影院全攻略:从设备选购到布线布置详解
债务人欠款不还,请律师出具律师函催款,这样能把钱要回来吗?
追讨欠款有几种方式?欠债公司破产倒闭如何追债?
战双帕弥什动漫深度解析:热门IP的文化价值与艺术魅力
最古老的一种算法揭秘:辗转相除法为何能准确求出最大公约数?
日本bgm音乐推荐:带你领略充满魅力的日式背景音乐轻松提升生活氛围
云顶之弈中剑魔如何搭配装备才能发挥最大威力?深度解析来了!
世界睡眠日:专家支招调整生物钟,改善睡眠质量
天赋与伤病齐飞,巴萨如何推行伤病管理
离婚纠纷如何调解?跨省离婚怎么办理?复婚能否享受婚假?
企业级 SSD 寿命要怎么看?
如何理解黄金价值的计价单位和价值?这种计价方式如何影响市场交易?
关闭CEP,手动调节电压:B760主板与i9-14900K性能优化攻略