开发步骤
- 创建
oled_demo.c,加上头文件 - 封装向I2C写数据函数
- 创建初始化oled函数
- 清空屏幕
- 完成显示数据功能
步骤1
创建 oled_demo.c
头文件如下:
#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include "wifiiot_i2c.h"
#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])
步骤2
通过程序控制 oled 屏幕,就要调用 I2cWrite() 函数向 oled 屏幕发送指令,显示图像,为了简化代码,封装成函数 Write(),如下:
/*
cmdType:指令类型:0x00表示写指令,0x40表示写数据
data:数据。
当cmdType是0x00时,data表示指令内容
当cmdType是0x40时,data表示显示的内容
*/
static uint32_t Write(uint8_t cmdType, uint8_t data)
{
uint8_t buffer[] = {cmdType, data};
WifiIotI2cData i2cData = {0};
i2cData.sendBuf = buffer;
i2cData.sendLen = sizeof(buffer)/sizeof(buffer[0]);
return I2cWrite(WIFI_IOT_I2C_IDX_0, 0x78, &i2cData);
}
代码解释:
步骤3
创建 OledInit() 函数对GPIO管脚及oled进行初始化
/**
* @brief ssd1306 OLED 初始化操作.
*/
uint32_t OledInit(void)
{
// 初始化命令
static const uint8_t initCmds[] = {
0xAE, // --display off
0x00, // ---set low column address
0x10, // ---set high column address
0x40, // --set start line address
0xB0, // --set page address
0x81, // contract control
0xFF, // --128
0xA1, // set segment remap
0xA6, // --normal / reverse
0xA8, // --set multiplex ratio(1 to 64)
0x3F, // --1/32 duty
0xC8, // Com scan direction
0xD3, // -set display offset
0x00, //
0xD5, // set osc division
0x80, //
0xD8, // set area color mode off
0x05, //
0xD9, // Set Pre-Charge Period
0xF1, //
0xDA, // set com pin configuartion
0x12, //
0xDB, // set Vcomh
0x30, //
0x8D, // set charge pump enable
0x14, //
0xAF, // --turn on oled panel
};
// 设置 13 引脚为 SDA 总线
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA);
// 设置 14 引脚为 SCL 时钟线
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL);
// 设置 I2C 波特率,能够与外部 I2C 设备(如 OLED 屏幕、传感器等)正常通信。
I2cInit(WIFI_IOT_I2C_IDX_0, (400*1000)); // 400k
// I2cSetBaudrate(WIFI_IOT_I2C_IDX_0, OLED_I2C_BAUDRATE);
for (size_t i = 0; i < ARRAY_SIZE(initCmds); i++) {
uint32_t status = Write(0x00,initCmds[i]);
if (status != 0) {
return status;
}
}
return 0;
}
步骤4
定义全屏填充函数,用于清空屏幕
/*全屏填充*/
void OledFillScreen(uint8_t fillData)
{
uint8_t m = 0;
uint8_t n = 0;
for (m=0; m < 8; m++) {
Write(0x00,0xb0 + m); // 设置起始行
// Write(0x00,0x00);
// Write(0x00,0x10);
for (n=0; n < 128; n++) {
Write(0x40, fillData); // 显示到屏幕上
}
}
}
代码解释:
Write(0x00,0xb0 + m):向 I2C 设备写指令
0x00:表示写命令0xb0:表示设置起始行为0,0xb0 + 1表示设置起始行为1,共有8行
Write(0x40, fillData):
0x40:向 I2C 设备写数据,即:显示到oled显示屏上。fillData是8位二进制数,0表示像素点灭,0表示像素点亮
主函数
// 小箭头,从左向右逐渐显示
static void OledDemo(void)
{
GpioInit();
OledInit();
OledFillScreen(0x00);
Write(0x00,0xb0 + 1); // 移动到第二页
// 显示箭头尾部
for(uint8_t i = 0 ;i<20;i++){
// 一列8位,1表示亮灯、0表示灭灯
Write(0x40,0b00111100);
usleep(500);
}
// 显示指向右侧的箭头
Write(0x40,0b1111111);
Write(0x40,0b1111111);
usleep(500);
Write(0x40,0b0111110);
Write(0x40,0b0111110);
usleep(500);
Write(0x40,0b0011100);
Write(0x40,0b0011100);
usleep(500);
Write(0x40,0b0001000);
Write(0x40,0b0001000);
}
APP_FEATURE_INIT(OledDemo);
完整代码
#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include "wifiiot_i2c.h"
#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])
/*
cmdType:指令类型:0x00表示写指令,0x40表示写数据
data:数据。
当cmdType是0x00时,data表示指令内容
当cmdType是0x40时,data表示显示的内容
*/
static uint32_t Write(uint8_t cmdType, uint8_t data)
{
uint8_t buffer[] = {cmdType, data};
WifiIotI2cData i2cData = {0};
i2cData.sendBuf = buffer;
i2cData.sendLen = sizeof(buffer)/sizeof(buffer[0]);
return I2cWrite(WIFI_IOT_I2C_IDX_0, 0x78, &i2cData);
}
/**
* @brief ssd1306 OLED 初始化操作.
*/
uint32_t OledInit(void)
{
// 初始化命令
static const uint8_t initCmds[] = {
0xAE, // --display off
0x00, // ---set low column address
0x10, // ---set high column address
0x40, // --set start line address
0xB0, // --set page address
0x81, // contract control
0xFF, // --128
0xA1, // set segment remap
0xA6, // --normal / reverse
0xA8, // --set multiplex ratio(1 to 64)
0x3F, // --1/32 duty
0xC8, // Com scan direction
0xD3, // -set display offset
0x00, //
0xD5, // set osc division
0x80, //
0xD8, // set area color mode off
0x05, //
0xD9, // Set Pre-Charge Period
0xF1, //
0xDA, // set com pin configuartion
0x12, //
0xDB, // set Vcomh
0x30, //
0x8D, // set charge pump enable
0x14, //
0xAF, // --turn on oled panel
};
// 设置 13 引脚为 SDA 总线
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA);
// 设置 14 引脚为 SCL 时钟线
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL);
// 设置 I2C 波特率,能够与外部 I2C 设备(如 OLED 屏幕、传感器等)正常通信。
I2cInit(WIFI_IOT_I2C_IDX_0, 400*1000); // 400k
// I2cSetBaudrate(WIFI_IOT_I2C_IDX_0, OLED_I2C_BAUDRATE);
for (size_t i = 0; i < ARRAY_SIZE(initCmds); i++) {
uint32_t status = Write(0x00,initCmds[i]);
if (status != 0) {
return status;
}
}
return 0;
}
/*全屏填充*/
void OledFillScreen(uint8_t fillData)
{
uint8_t m = 0;
uint8_t n = 0;
for (m=0; m < 8; m++) {
Write(0x00,0xb0 + m); // 设置起始行
// Write(0x00,0x00);
// Write(0x00,0x10);
for (n=0; n < 128; n++) {
Write(0x40, fillData); // 显示到屏幕上
}
}
}
// 小箭头,从左向右逐渐显示
static void OledDemo(void)
{
GpioInit();
OledInit();
OledFillScreen(0x00);
Write(0x00,0xb0 + 1);
// 显示箭头尾部
for(uint8_t i = 0 ;i<20;i++){
// 一列8位,1表示亮灯、0表示灭灯
Write(0x40,0b00111100);
usleep(500);
}
// 显示指向右侧的箭头
Write(0x40,0b1111111);
Write(0x40,0b1111111);
usleep(500);
Write(0x40,0b0111110);
Write(0x40,0b0111110);
usleep(500);
Write(0x40,0b0011100);
Write(0x40,0b0011100);
usleep(500);
Write(0x40,0b0001000);
Write(0x40,0b0001000);
}
APP_FEATURE_INIT(OledDemo);
编辑BUILD.gn文件
编辑1
在代码同级目录创建下面文件:
BUILD.gn
内容:
static_library("oled_demo") {
sources = [
"oled_demo.c",
]
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/components/cmsis/2.0",
"//base/iot_hardware/interfaces/kits/wifiiot_lite",
]
}
编辑2
编辑下面文件:
\\applications\sample\wifi-iot\app\BUILD.gn
内容:
import("//build/lite/config/component/lite_component.gni")
lite_component("app") {
features = [
# "code_v2.0/std_03:hello_demo",
# "code_v2.0/std_04:traffic_demo"
# "code_v2.0/std_07/ssd1306:oled_ssd1306",
# "code_v2.0/std_07/examples:oled_test",
# "code_v2.0/std_07/libm_port:libm_port",
"code_v2.0/std_06:oled_demo",
]
}
启用I2C功能
编译代码
详见链接:
https://www.malaoshi.top/show_1GW1wTyUOMPk.html
烧写固件到芯片
详见链接:
https://www.malaoshi.top/show_1GW1wWWflGbq.html