驱动 OLED 屏
本文案例代码 | 下载地址 |
---|---|
OLED驱动案例代码 | https://www.aw-ol.com/downloads?cat=24 |
OLED,即有机发光二极管( Organic Light Emitting Diode)。 OLED 由于同时具备自发光,不需背 光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及 制程较简单等优异之特性,被认为是下一代的平面显示器新兴应用技术。
LCD 都需要背光,而 OLED 不需要,因为它是自发光的。这样同样的显示 OLED 效果要来得好一 些。以目前的技术,OLED 的尺寸还难以大型化,但是分辨率确可以做到很高。
在此我们使用的 是0.96寸OLED显示屏,该屏有以下特点:
- 0.96 寸 OLED 有黄蓝,白,蓝三种颜色可选;其中黄蓝是屏上 1/4 部分为黄光,下 3/4 为蓝; 而且是固定区域显示固定颜色,颜色和显示区域均不能修改;白光则为纯白,也就是黑底白字; 蓝色则为纯蓝,也就是黑底蓝字。
- 分辨率为 128*64
- 多种接口方式;OLED 裸屏总共种接口包括:6800、8080 两种并行接口方式、3 线或 4 线的 串行 SPI 接口方式、 IIC 接口方式(只需要 2 根线就可以控制 OLED 了!),这五种接口是通过屏上的 BS0~BS2 来配置的。
本次使用的是四针的IIC 模块,如下图:
引脚配置如下
R128 Devkit | OLED |
---|---|
PA23 | SCL |
PA24 | SDA |
GND | GND |
3V3 | VCC |
载入方案
我们使用的开发板是 R128-Devkit,需要开发 C906 核心的应用程序,所以载入方案选择 r128s2_module_c906
$ source envsetup.sh
$ lunch_rtos 1
)
设置 TWI 驱动
运行 mrtos_menuconfig
进入配置页面。前往下列地址找到 TWI Devices
Drivers Options --->
soc related device drivers --->
TWI Devices --->
-*- enable twi driver
配置 TWI 引脚
打开你喜欢的编辑器,修改文件:board/r128s2/module/configs/sys_config.fex
增加 TWI0 的配置,参考手册可知 PA23,PA24 的 TWI0 复用为 6
[twi0]
twi0_sck = port:PA23<6><1><default><default>
twi0_sda = port:PA24<6><1><default><default>
编写程序
打开你喜欢的编辑器,新增文件:lichee/rtos/projects/r128s2/module_c906/src/oled.c
用于编写 OLED 的驱动。
编写 OLED 驱动
使用一个宏储存 TWI 的地址和使用的 TWI 端口,并定义显存。
#define OLED_IIC_ADDR 0x3c
#define OLED_IIC_PORT 0
uint8_t OLED_GRAM[144][8]; /* 显存 */
编写 OLED 的基础操作驱动 TWI 通讯函数。
#define OLED_CMD 0 /*写命令 */
#define OLED_DATA 1 /* 写数据 */
void OLED_WR_Byte(uint8_t dat, uint8_t mode)
{
twi_msg_t msg;
twi_port_t port = OLED_IIC_PORT;
uint8_t buf[2];
if (mode)
buf[0] = 0x40;
else
buf[0] = 0x00;
buf[1] = dat;
msg.flags = 0;
msg.addr = OLED_IIC_ADDR;
msg.len = 2;
msg.buf = buf;
hal_twi_control(port, I2C_RDWR, &msg);
}
编写 OLED 的驱动函数:显示开关
void OLED_ColorTurn(uint8_t i)
{
if (i == 0) {
OLED_WR_Byte(0xA6, OLED_CMD); /* 正常显示 */
}
if (i == 1) {
OLED_WR_Byte(0xA7, OLED_CMD); /* 反色显示 */
}
}
编写 OLED 的驱动函数:反显设置
void OLED_DisplayTurn(uint8_t i)
{
if (i == 0) {
OLED_WR_Byte(0xC8, OLED_CMD); /* 正常显示 */
OLED_WR_Byte(0xA1, OLED_CMD);
}
if (i == 1) {
OLED_WR_Byte(0xC0, OLED_CMD); /* 反转显示 */
OLED_WR_Byte(0xA0, OLED_CMD);
}
}
编写 OLED 的驱动函数:刷新屏幕
void OLED_Refresh(void)
{
for (int i = 0; i < 8; i++) {
OLED_WR_Byte(0xb0 + i, OLED_CMD); //设置行起始地址
OLED_WR_Byte(0x00, OLED_CMD); //设置低列起始地址
OLED_WR_Byte(0x10, OLED_CMD); //设置高列起始地址
OLED_WR_Byte(0x78, OLED_DATA);
OLED_WR_Byte(0x40, OLED_DATA);
for (int n = 0; n < 128; n++) {
OLED_WR_Byte(OLED_GRAM[n][i], OLED_DATA);
}
}
}