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);
}
}
}
编写 OLED 的驱动函数:清屏
void OLED_Clear(void)
{
for (int i = 0; i < 8; i++) {
OLED_WR_Byte(0xb0 + i, OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte(0x00, OLED_CMD); //设置显示位置—列低地址
OLED_WR_Byte(0x10, OLED_CMD); //设置显示位置—列高地址
for (int n = 0; n < 128; n++)
OLED_GRAM[n][i] = 0;
OLED_Refresh(); //刷新GRAM内容
}
}
编写 OLED 的驱动函数:画点
void OLED_DrawPoint(uint8_t x, uint8_t y, uint8_t t)
{
uint8_t i, m, n;
i = y / 8;
m = y % 8;
n = 1 < < m;
if (t) {
OLED_GRAM[x][i] |= n;
}
else {
OLED_GRAM[x][i] = ~OLED_GRAM[x][i];
OLED_GRAM[x][i] |= n;
OLED_GRAM[x][i] = ~OLED_GRAM[x][i];
}
}
编写 OLED 的驱动函数:画线
void OLED_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t mode)
{
int xerr = 0, yerr = 0, delta_x, delta_y, distance;
int incx, incy, uRow, uCol;
delta_x = x2 - x1; //计算坐标增量
delta_y = y2 - y1;
uRow = x1; //画线起点坐标
uCol = y1;
if (delta_x > 0)
incx = 1; //设置单步方向
else if (delta_x == 0)
incx = 0; //垂直线
else {
incx = -1;
delta_x = -delta_x;
}
if (delta_y > 0)
incy = 1;
else if (delta_y == 0)
incy = 0; //水平线
else {
incy = -1;
delta_y = -delta_x;
}
if (delta_x > delta_y)
distance = delta_x; //选取基本增量坐标轴
else
distance = delta_y;
for (uint16_t t = 0; t < distance + 1; t++) {
OLED_DrawPoint(uRow, uCol, mode); //画点
xerr += delta_x;
yerr += delta_y;
if (xerr > distance) {
xerr -= distance;
uRow += incx;
}
if (yerr > distance) {
yerr -= distance;
uCol += incy;
}
}
}
编写 OLED 的驱动函数:画园
void OLED_DrawCircle(uint8_t x, uint8_t y, uint8_t r)
{
int a, b, num;
a = 0;
b = r;
while (2 * b * b >= r * r) {
OLED_DrawPoint(x + a, y - b, 1);
OLED_DrawPoint(x - a, y - b, 1);
OLED_DrawPoint(x - a, y + b, 1);
OLED_DrawPoint(x + a, y + b, 1);
OLED_DrawPoint(x + b, y + a, 1);
OLED_DrawPoint(x + b, y - a, 1);
OLED_DrawPoint(x - b, y - a, 1);
OLED_DrawPoint(x - b, y + a, 1);
a++;
num = (a * a + b * b) - r * r; //计算画的点离圆心的距离
if (num > 0) {
b--;
a--;
}
}
}
编写 OLED 的驱动函数:显示字符
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t size1, uint8_t mode)
{
uint8_t temp, size2, chr1;
uint8_t x0 = x, y0 = y;
if (size1 == 8)
size2 = 6;
else
size2 = (size1 / 8 + ((size1 % 8) ? 1 : 0)) * (size1 / 2); //得到字体一个字符对应点阵集所占的字节数
chr1 = chr - ' '; //计算偏移后的值
for (uint8_t i = 0; i < size2; i++) {
if (size1 == 8) {
temp = asc2_0806[chr1][i];
} //调用0806字体
else if (size1 == 12) {
temp = asc2_1206[chr1][i];
} //调用1206字体
else if (size1 == 16) {
temp = asc2_1608[chr1][i];
} //调用1608字体
else if (size1 == 24) {
temp = asc2_2412[chr1][i];
} //调用2412字体
else
return;
for (uint8_t m = 0; m < 8; m++) {
if (temp & 0x01)
OLED_DrawPoint(x, y, mode);
else
OLED_DrawPoint(x, y, !mode);
temp > >= 1;
y++;
}
x++;
if ((size1 != 8) && ((x - x0) == size1 / 2)) {
x = x0;
y0 = y0 + 8;
}
y = y0;
}
}
编写 OLED 的驱动函数:显示字符串
void OLED_ShowString(uint8_t x, uint8_t y, uint8_t* chr, uint8_t size1, uint8_t mode)
{
while ((*chr >= ' ') && (*chr <= '~')) //判断是不是非法字符!
{
OLED_ShowChar(x, y, *chr, size1, mode);
if (size1 == 8)
x += 6;
else
x += size1 / 2;
chr++;
}
}
编写 OLED 的驱动函数:显示数字
void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size1, uint8_t mode)
{
uint8_t temp, m = 0;
if (size1 == 8)
m = 2;
for (uint8_t t = 0; t < len; t++) {
temp = (num / OLED_Pow(10, len - t - 1)) % 10;
if (temp == 0) {
OLED_ShowChar(x + (size1 / 2 + m) * t, y, '0', size1, mode);
}
else {
OLED_ShowChar(x + (size1 / 2 + m) * t, y, temp + '0', size1, mode);
}
}
}
编写 OLED 的驱动函数:配置位置
void OLED_Set_Pos(uint8_t x, uint8_t y)
{
OLED_WR_Byte(0xb0 + y, OLED_CMD);
OLED_WR_Byte(((x & 0xf0) > > 4) | 0x10, OLED_CMD);
OLED_WR_Byte((x & 0x0f), OLED_CMD);
}
编写 OLED 的驱动函数:初始化屏幕
void OLED_Init(void)
{
hal_twi_init(OLED_IIC_PORT); //-- init TWI
OLED_WR_Byte(0xAE, OLED_CMD);//--turn off oled panel
OLED_WR_Byte(0x00, OLED_CMD);//---set low column address
OLED_WR_Byte(0x10, OLED_CMD);//---set high column address
OLED_WR_Byte(0x40, OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
OLED_WR_Byte(0x81, OLED_CMD);//--set contrast control register
OLED_WR_Byte(0xCF, OLED_CMD); // Set SEG Output Current Brightness
OLED_WR_Byte(0xA1, OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
OLED_WR_Byte(0xC8, OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
OLED_WR_Byte(0xA6, OLED_CMD);//--set normal display
OLED_WR_Byte(0xA8, OLED_CMD);//--set multiplex ratio(1 to 64)
OLED_WR_Byte(0x3f, OLED_CMD);//--1/64 duty
OLED_WR_Byte(0xD3, OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLED_WR_Byte(0x00, OLED_CMD);//-not offset
OLED_WR_Byte(0xd5, OLED_CMD);//--set display clock divide ratio/oscillator frequency
OLED_WR_Byte(0x80, OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
OLED_WR_Byte(0xD9, OLED_CMD);//--set pre-charge period
OLED_WR_Byte(0xF1, OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_WR_Byte(0xDA, OLED_CMD);//--set com pins hardware configuration
OLED_WR_Byte(0x12, OLED_CMD);
OLED_WR_Byte(0xDB, OLED_CMD);//--set vcomh
OLED_WR_Byte(0x40, OLED_CMD);//Set VCOM Deselect Level
OLED_WR_Byte(0x20, OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
OLED_WR_Byte(0x02, OLED_CMD);//
OLED_WR_Byte(0x8D, OLED_CMD);//--set Charge Pump enable/disable
OLED_WR_Byte(0x14, OLED_CMD);//--set(0x10) disable
OLED_WR_Byte(0xA4, OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
OLED_WR_Byte(0xA6, OLED_CMD);// Disable Inverse Display On (0xa6/a7)
OLED_Clear();
OLED_WR_Byte(0xAF, OLED_CMD); /*display ON*/
}
我们把这些驱动放到一个单独的文件里,命名为 oled.c
,完整内容如下:
#include < sunxi_hal_twi.h >
#include "oledfont.h"
#define OLED_IIC_ADDR 0x3c
#define OLED_IIC_PORT 0
#define OLED_CMD 0 /*写命令 */
#define OLED_DATA 1 /* 写数据 */
uint8_t OLED_GRAM[144][8]; /* 显存 */
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);
}
uint32_t OLED_Pow(uint8_t m, uint8_t n)
{
uint32_t result = 1;
while (n--)
result *= m;
return result;
}
void OLED_ColorTurn(uint8_t i)
{
if (i == 0) {
OLED_WR_Byte(0xA6, OLED_CMD); /* 正常显示 */
}
if (i == 1) {
OLED_WR_Byte(0xA7, OLED_CMD); /* 反色显示 */
}
}
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);
}
}
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);
}
}
}
void OLED_Clear(void)
{
for (int i = 0; i < 8; i++) {
OLED_WR_Byte(0xb0 + i, OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte(0x00, OLED_CMD); //设置显示位置—列低地址
OLED_WR_Byte(0x10, OLED_CMD); //设置显示位置—列高地址
for (int n = 0; n < 128; n++)
OLED_GRAM[n][i] = 0;
OLED_Refresh(); //刷新GRAM内容
}
}
void OLED_DrawPoint(uint8_t x, uint8_t y, uint8_t t)
{
uint8_t i, m, n;
i = y / 8;
m = y % 8;
n = 1 < < m;
if (t) {
OLED_GRAM[x][i] |= n;
}
else {
OLED_GRAM[x][i] = ~OLED_GRAM[x][i];
OLED_GRAM[x][i] |= n;
OLED_GRAM[x][i] = ~OLED_GRAM[x][i];
}
}
void OLED_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t mode)
{
int xerr = 0, yerr = 0, delta_x, delta_y, distance;
int incx, incy, uRow, uCol;
delta_x = x2 - x1; //计算坐标增量
delta_y = y2 - y1;
uRow = x1; //画线起点坐标
uCol = y1;
if (delta_x > 0)
incx = 1; //设置单步方向
else if (delta_x == 0)
incx = 0; //垂直线
else {
incx = -1;
delta_x = -delta_x;
}
if (delta_y > 0)
incy = 1;
else if (delta_y == 0)
incy = 0; //水平线
else {
incy = -1;
delta_y = -delta_x;
}
if (delta_x > delta_y)
distance = delta_x; //选取基本增量坐标轴
else
distance = delta_y;
for (uint16_t t = 0; t < distance + 1; t++) {
OLED_DrawPoint(uRow, uCol, mode); //画点
xerr += delta_x;
yerr += delta_y;
if (xerr > distance) {
xerr -= distance;
uRow += incx;
}
if (yerr > distance) {
yerr -= distance;
uCol += incy;
}
}
}
void OLED_DrawCircle(uint8_t x, uint8_t y, uint8_t r)
{
int a, b, num;
a = 0;
b = r;
while (2 * b * b >= r * r) {
OLED_DrawPoint(x + a, y - b, 1);
OLED_DrawPoint(x - a, y - b, 1);
OLED_DrawPoint(x - a, y + b, 1);
OLED_DrawPoint(x + a, y + b, 1);
OLED_DrawPoint(x + b, y + a, 1);
OLED_DrawPoint(x + b, y - a, 1);
OLED_DrawPoint(x - b, y - a, 1);
OLED_DrawPoint(x - b, y + a, 1);
a++;
num = (a * a + b * b) - r * r; //计算画的点离圆心的距离
if (num > 0) {
b--;
a--;
}
}
}
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t size1, uint8_t mode)
{
uint8_t temp, size2, chr1;
uint8_t x0 = x, y0 = y;
if (size1 == 8)
size2 = 6;
else
size2 = (size1 / 8 + ((size1 % 8) ? 1 : 0)) * (size1 / 2); //得到字体一个字符对应点阵集所占的字节数
chr1 = chr - ' '; //计算偏移后的值
for (uint8_t i = 0; i < size2; i++) {
if (size1 == 8) {
temp = asc2_0806[chr1][i];
} //调用0806字体
else if (size1 == 12) {
temp = asc2_1206[chr1][i];
} //调用1206字体
else if (size1 == 16) {
temp = asc2_1608[chr1][i];
} //调用1608字体
else if (size1 == 24) {
temp = asc2_2412[chr1][i];
} //调用2412字体
else
return;
for (uint8_t m = 0; m < 8; m++) {
if (temp & 0x01)
OLED_DrawPoint(x, y, mode);
else
OLED_DrawPoint(x, y, !mode);
temp > >= 1;
y++;
}
x++;
if ((size1 != 8) && ((x - x0) == size1 / 2)) {
x = x0;
y0 = y0 + 8;
}
y = y0;
}
}
void OLED_ShowString(uint8_t x, uint8_t y, uint8_t* chr, uint8_t size1, uint8_t mode)
{
while ((*chr >= ' ') && (*chr <= '~')) //判断是不是非法字符!
{
OLED_ShowChar(x, y, *chr, size1, mode);
if (size1 == 8)
x += 6;
else
x += size1 / 2;
chr++;
}
}
void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size1, uint8_t mode)
{
uint8_t temp, m = 0;
if (size1 == 8)
m = 2;
for (uint8_t t = 0; t < len; t++) {
temp = (num / OLED_Pow(10, len - t - 1)) % 10;
if (temp == 0) {
OLED_ShowChar(x + (size1 / 2 + m) * t, y, '0', size1, mode);
}
else {
OLED_ShowChar(x + (size1 / 2 + m) * t, y, temp + '0', size1, mode);
}
}
}
void OLED_Set_Pos(uint8_t x, uint8_t y)
{
OLED_WR_Byte(0xb0 + y, OLED_CMD);
OLED_WR_Byte(((x & 0xf0) > > 4) | 0x10, OLED_CMD);
OLED_WR_Byte((x & 0x0f), OLED_CMD);
}
void OLED_Init(void)
{
hal_twi_init(OLED_IIC_PORT); //-- init TWI
OLED_WR_Byte(0xAE, OLED_CMD);//--turn off oled panel
OLED_WR_Byte(0x00, OLED_CMD);//---set low column address
OLED_WR_Byte(0x10, OLED_CMD);//---set high column address
OLED_WR_Byte(0x40, OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
OLED_WR_Byte(0x81, OLED_CMD);//--set contrast control register
OLED_WR_Byte(0xCF, OLED_CMD); // Set SEG Output Current Brightness
OLED_WR_Byte(0xA1, OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
OLED_WR_Byte(0xC8, OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
OLED_WR_Byte(0xA6, OLED_CMD);//--set normal display
OLED_WR_Byte(0xA8, OLED_CMD);//--set multiplex ratio(1 to 64)
OLED_WR_Byte(0x3f, OLED_CMD);//--1/64 duty
OLED_WR_Byte(0xD3, OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLED_WR_Byte(0x00, OLED_CMD);//-not offset
OLED_WR_Byte(0xd5, OLED_CMD);//--set display clock divide ratio/oscillator frequency
OLED_WR_Byte(0x80, OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
OLED_WR_Byte(0xD9, OLED_CMD);//--set pre-charge period
OLED_WR_Byte(0xF1, OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_WR_Byte(0xDA, OLED_CMD);//--set com pins hardware configuration
OLED_WR_Byte(0x12, OLED_CMD);
OLED_WR_Byte(0xDB, OLED_CMD);//--set vcomh
OLED_WR_Byte(0x40, OLED_CMD);//Set VCOM Deselect Level
OLED_WR_Byte(0x20, OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
OLED_WR_Byte(0x02, OLED_CMD);//
OLED_WR_Byte(0x8D, OLED_CMD);//--set Charge Pump enable/disable
OLED_WR_Byte(0x14, OLED_CMD);//--set(0x10) disable
OLED_WR_Byte(0xA4, OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
OLED_WR_Byte(0xA6, OLED_CMD);// Disable Inverse Display On (0xa6/a7)
OLED_Clear();
OLED_WR_Byte(0xAF, OLED_CMD); /*display ON*/
}
同时提供对应的头文件 oled.h
,oledfont.h
由于较大,见文章末尾。
#ifndef __OLED_H
#define __OLED_H
/* 发送一个字节
* mode:数据/命令标志 0,表示命令;1,表示数据;
*/
void OLED_WR_Byte(uint8_t dat, uint8_t mode);
/* Pow 函数 */
uint32_t OLED_Pow(uint8_t m, uint8_t n);
/* 反显函数 */
void OLED_ColorTurn(uint8_t i);
/* 屏幕旋转180度 */
void OLED_DisplayTurn(uint8_t i);
/* 更新显存到OLED */
void OLED_Refresh(void);
/* OLED 清屏 */
void OLED_Clear(void);
/* 画点
* x: 0~127
* y: 0~63
* t: 1 填充 0,清空
*/
void OLED_DrawPoint(uint8_t x, uint8_t y, uint8_t t);
/* 画线
* x1, y1: 起点坐标
* x2, y2: 结束坐标
*/
void OLED_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t mode);
/* 画圆
* x, y: 圆心坐标
* r: 圆的半径
*/
void OLED_DrawCircle(uint8_t x, uint8_t y, uint8_t r);
/* 在指定位置显示一个字符,包括部分字符
* x: 0 ~ 127
* y: 0 ~ 63
* size1: 选择字体 6x8/6x12/8x16/12x24
* mode: 0,反色显示; 1,正常显示
*/
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t size1, uint8_t mode);
/* 显示字符串
* x: 0 ~ 127
* y: 0 ~ 63
* *chr: 字符串起始地址
* size1: 选择字体 6x8/6x12/8x16/12x24
* mode: 0,反色显示; 1,正常显示
*/
void OLED_ShowString(uint8_t x, uint8_t y, uint8_t* chr, uint8_t size1, uint8_t mode);
/* 显示数字
* x: 0 ~ 127
* y: 0 ~ 63
* num: 要显示的数字
* len: 数字的位数
* size1: 选择字体 6x8/6x12/8x16/12x24
* mode: 0,反色显示; 1,正常显示
*/
void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size1, uint8_t mode);
/* 初始化 OLED */
void OLED_Init(void);
#endif
然后把 oled.c
加入编译,修改 lichee/rtos/projects/r128s2/module_c906/Makefile
加入
obj-y += src/oled.o
编写主程序
打开你喜欢的编辑器,修改文件:lichee/rtos/projects/r128s2/module_c906/src/main.c
OLED_Init();
OLED_ShowString(12, 16, "====AWOL====", 16, 1);
OLED_ShowString(20, 32, "2023/08/24", 16, 1);
OLED_Refresh();
初始化 OLED,然后显示字符串。
结果
驱动了 OLED 屏
评论
查看更多