文章目录
OLED屏应用IIC协议
1.IIC协议概述
IIC全称Inter-Integrated Circuit (集成电路总线) 是由PHILIPS公司在80年代开发的两线式串行总线,用于连接微控制器及其外围设备。IIC属于半双 工同步通信方式
1.1.特点
- 简单性和有效性。
由于接口直接在组件之上,因此IIC总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。总线的长度可高达25英尺,并且能够以10Kbps的最大传输速率支持40个组件
- 多主控(multimastering)
其中任何能够进行发送和接收的设备都可以成为主总线。一个主控能够控制信号的传输和时钟频率。当 然,在任何时间点上只能有一个主控。
1.2.构成
IIC串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL,其时钟信号是由主控 器件产生。所有接到IIC总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线 的SCL上。对于并联在一条总线上的每个IC都有唯一的地址。
2.IIC协议
IIC总线在传输数据的过程中一共有三种类型信号,分别为:开始信号、结束信号和应答信号。 //起始位,停止位,数据位,速度 这些信号中,起始信号是必需的,结束信号和应答信号
-
起始信号
-
终止信号
- 应答信号
发送器每发送一个字节(8个bit),就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。 应答信号为低电平时,规定为有效应答位(ACK,简称应答位),表示接收器已经成功地接收了该字 节; 应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。
- 数据发送的时序
3.OLED写命令
4.OLED的寻址模式
如何显示一个点? 有三种,分别位页地址模式,水平地址模式和垂直地址模式,可以通过一下表格进行配置 内存管理
4.1页地址模式
4.2.水平地址模式
4.3.垂直地址模式
5.列地址选择
如果写入0x08(b00001000)会显示什么呢 一个字节负责一个Page的一列显示
64 | 0列 | 1列 | 2列 | 3列 | . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . | 124列 | 125列 | 126列 | 127列 | ||
---|---|---|---|---|---|---|---|---|---|---|---|
Page0 | bit0 | 0行 | 0 | ||||||||
bit1 | 1行 | 0 | |||||||||
bit2 | 2行 | 0 | |||||||||
bit3 | 3行 | 1 | |||||||||
bit4 | 4行 | 0 | |||||||||
bit5 | 5行 | 0 | |||||||||
bit6 | 6行 | 0 | |||||||||
bit7 | 7行 | 0 | |||||||||
Page1 | 8 到 1 5行 | ||||||||||
Page2 | 1 6 到 2 3 行 | ||||||||||
Page3 | . . . . . . | ||||||||||
Page4 | . . . . . . | ||||||||||
Page5 | . . . . . . | ||||||||||
Page6 | . . . . . . | ||||||||||
Page7 | 5 6 行 到 6 3 行 |
6.OLED屏幕
6.1.Orangepi的IIC接口
-
由 26pin 的原理图可知, Orange Pi Zero 2 可用的 i2c 为 i2c3
6.2.接线
根据上面OLED屏和原理图显示,接到对应的标号,不要接反了。刚开始接上去屏幕是黑色的,里面没有代码。
- 启动 linux 系统后, 先确认下/dev 下存在 i2c-3 的设备节点
从命令运行结果能观察到系统支持I2C-3和I2C-5的驱动,而H616的外设我们看到只有一个IIC接口, 用的是IIC-3 Linux一切皆文件,每个硬件设备“对应”一个文件,由驱动程序提供映射。
- 开始测试 i2c, 首先安装 i2c-tools
sudo apt-get install i2c-tools
/*i2c设备访问,访问出来的是设备识别出来的,如果接其他的i2c设备访问出来的可能就是5A,或者5C*/
sudo i2cdetect -y 3
6.3.OLED功能代码阅读
/*Source Insight4 看源码非常便捷 */
/*根目录文件下有OLED原码程序*/
/home/orangepi/wiringPiFromWindows/wiringOP-/oled_demo.c
/*要将dev底下的i2c设备驱动连接起来,才能正常的显示*/
sudo ./a.out /dev/i2c-3
/*
* 版权所有 (c) 2015, Vladimir Komendantskiy
* 本程序使用 MIT 许可证
*
* 这是 SSD1306 OLED 显示屏的块和字体绘制演示程序
*/
//
// 由 HypHop 修改以适配 OrangePiZero
//
#include <errno.h> // 包含错误号定义
#include <string.h> // 包含字符串操作相关函数
#include <stdio.h> // 包含标准输入输出函数
#include <stdlib.h> // 包含动态内存分配等函数
#include <time.h> // 包含时间相关函数
#include <stdint.h> // 包含标准整型定义
// 引入 OLED 显示和字体相关的自定义头文件
#include "oled.h"
#include "font.h"
// OLED 显示屏演示函数
int oled_demo(struct display_info *disp) {
int i; // 循环变量
char buf[100]; // 用于存放字符串的缓冲区
// 以下代码被注释掉了,它们原本用于在 OLED 屏幕上显示文本
// putstrto(disp, 0, 0, "Spnd spd 2468 rpm");
// oled_putstrto(disp, 0, 9+1, "Spnd cur 0.46 A");
oled_putstrto(disp, 0, 9+1, "Welcome to"); // 在屏幕上显示欢迎信息
disp->font = font1; // 设置字体为 font1
// oled_putstrto(disp, 0, 18+2, "Spnd tmp 53 C");
oled_putstrto(disp, 0, 18+2, "----OrangePi----"); // 显示关于 OrangePi 的信息
disp->font = font2; // 设置字体为 font2
// oled_putstrto(disp, 0, 27+3, "DrvX tmp 64 C");
oled_putstrto(disp, 0, 27+3, "This is 0.96OLED"); // 显示 OLED 屏幕的型号信息
oled_putstrto(disp, 0, 36+4, ""); // 清空屏幕上的某些行
oled_putstrto(disp, 0, 45+5, "");
disp->font = font1; // 重新设置字体为 font1
// oled_putstrto(disp, 0, 54, "Total cur 2.36 A");
oled_putstrto(disp, 0, 54, "*****************"); // 显示星号图案
oled_send_buffer(disp); // 发送缓冲区数据到 OLED 屏幕
disp->font = font3; // 设置字体为 font3
for (i=0; i<100; i++) { // 循环显示变化的转速信息
sprintf(buf, "Spnd spd %d rpm", i); // 格式化字符串
oled_putstrto(disp, 0, 0, buf); // 显示转速信息
oled_putstrto(disp, 135-i, 36+4, "==="); // 显示分隔符
oled_putstrto(disp, 100, 0+i/2, "."); // 显示点
oled_send_buffer(disp); // 发送缓冲区数据到 OLED 屏幕
}
// oled_putpixel(disp, 60, 45); // 被注释掉的代码,用于在屏幕上绘制单个像素
// oled_putstr(disp, 1, "hello"); // 被注释掉的代码,用于在屏幕上显示文本
return 0; // 函数返回0,表示成功
}
// 显示错误信息的函数
void show_error(int err, int add) {
// const gchar* errmsg;
// errmsg = g_strerror(errno); // 获取错误信息的字符串描述
printf("\nERROR: %i, %i\n\n", err, add); // 打印错误代码和附加信息
// printf("\nERROR\n"); // 被注释掉的打印错误信息的代码
}
// 显示程序使用方法的函数
void show_usage(char *progname) {
printf("\nUsage:\n%s <I2C bus device node >\n", progname); // 打印程序的使用方法
}
// 主函数,程序的入口点
int main(int argc, char **argv) {
int e; // 错误代码变量
char filename[32]; // 用于存储 I2C 设备文件名的字符数组
struct display_info disp; // OLED 显示屏信息结构体
// 检查命令行参数数量是否足够
if (argc < 2) {
show_usage(argv[0]); // 参数不足时,显示使用方法
return -1; // 返回错误代码 -1
}
// 初始化 disp 结构体
memset(&disp, 0, sizeof(disp));
sprintf(filename, "%s", argv[1]); // 将命令行参数转换为字符串
disp.address = OLED_I2C_ADDR; // 设置 OLED 显示屏的 I2C 地址
disp.font = font2; // 设置默认字体为 font2
// 尝试打开 OLED 显示屏
e = oled_open(&disp, filename);
if (e < 0) {
show_error(1, e); // 打开失败,显示错误信息
} else {
// 如果打开成功,尝试初始化 OLED 显示屏
e = oled_init(&disp);
if (e < 0) {
show_error(2, e); // 初始化失败,显示错误信息
} else {
printf("---------start--------\n"); // 初始化成功,开始演示
if (oled_demo(&disp) < 0) // 如果演示函数执行失败
show_error(3, 777); // 显示错误信息
printf("----------end---------\n"); // 演示结束
}
}
return 0; // 如果程序执行到这里,表示一切正常,返回0
}
OLED内容显示:
6.4.OLED显示自己想要的字符
// 包含标准库头文件
#include <errno.h> // 错误号定义
#include <string.h> // 字符串操作函数
#include <stdio.h> // 标准输入输出库
#include <stdlib.h> // 通用工具库,如内存分配
#include <time.h> // 时间操作
#include <stdint.h> // 整数类型定义
// 包含自定义头文件,可能是OLED显示和字体相关的库
#include "oled.h"
#include "font.h"
// 显示函数,接收一个显示信息结构体指针作为参数
int oled_show(struct display_info *disp) {
int i;
char buf[100];
// 在OLED屏幕上显示欢迎信息
oled_putstrto(disp, 0, 9+1, "Welcome to My HomeAssitant");
// 设置字体为font2
disp->font = font2;
// 在OLED屏幕上显示版权信息
oled_putstrto(disp, 0, 20, " --Mr.qiao HenShuai-- ");
// 再次设置字体为font2,可能是为了确保文本使用正确的字体
disp->font = font2;
// 发送缓冲区内容到OLED屏幕
oled_send_buffer(disp);
return 0;
}
// 显示错误信息的函数
void show_error(int err, int add) {
printf("\nERROR: %i, %i\n\n", err, add);
}
// 显示程序使用方法的函数
void show_usage(char *progname) {
printf("\nUsage:\n%s <I2C bus device node >\n", progname);
}
// 主函数,程序的入口点
int main(int argc, char **argv) {
int e;
char filename[32];
struct display_info disp;
// 检查命令行参数数量是否至少为2(程序名和I2C设备节点)
if (argc < 2) {
show_usage(argv[0]);
return -1;
}
// 初始化显示信息结构体
memset(&disp, 0, sizeof(disp));
// 将命令行参数中的I2C设备节点名称复制到filename数组
sprintf(filename, "%s", argv[1]);
// 设置OLED的I2C地址
disp.address = OLED_I2C_ADDR;
// 设置默认字体为font2
disp.font = font2;
// 打开OLED设备
e = oled_open(&disp, filename);
// 初始化OLED设备
e = oled_init(&disp);
// 调用oled_show函数显示信息
oled_show(&disp);
return 0;
}