Hi3861 硬件 i2c 驱动 oled

本文记录了使用3861芯片(Hi3861)通过i2c驱动OLED显示器的开发过程。作者首先介绍了硬件平台Bearpi-Nano和润和sdk,然后详细说明了如何借用STM32CubeMX的OLED接口并替换为Hi3861的i2c接口。文章还提到了SDK提供的两层驱动接口,并展示了简单的I2C初始化和OLED显示的代码示例。最后,作者给出了代码编译和下载的方法以及调试中的现象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言

最近想用 3861 做个有意思的东西,记录一下开发过程。今天使用 3861 的硬件 i2c 驱动 oled。

硬件平台:Bearpi-Nano

软件SDK:润和sdk

二、搬一个 OLED 轮子

我之前写过一篇基于 stm32cubemx 快速使用 iic 接口 oled 的过程,里面有现成的 oled 接口,我们只要直接拿过来替换掉底层接口就行。

 STM32CubeMX驱动4脚OLED模块

替换的接口位置如下位置:

三、Hi3861 i2c 接口

SDK提供了两层接口封装,一层是芯片级的 driver 驱动,由原厂sdk提供:

另一层 open Harmony 级的驱动,是操作系统对原厂sdk的封装,主要为了兼容不同芯片开发:

原厂的 driver 接口更加细致,系统层的driver其实就是对原厂的一层封装,简单开发可以直接使用系统提供的driver接口,复杂开发则推荐研究一下原厂的接口,因为sdk不是很完善,不符合需求的可以直接改原厂的sdk。

我们简单驱动个i2c,使用系统封装的接口:

unsigned int IoTI2cInit(unsigned int id, unsigned int baudrate);

unsigned int IoTI2cDeinit(unsigned int id);

unsigned int IoTI2cWrite(unsigned int id, unsigned short deviceAddr, const unsigned char *data, unsigned int dataLen);

unsigned int IoTI2cRead(unsigned int id, unsigned short deviceAddr, unsigned char *data, unsigned int dataLen);

unsigned int IoTI2cSetBaudrate(unsigned int id, unsigned int baudrate);

用上面的读写接口替换掉 oled 轮子里面的 i2c 接口

四、使用驱动代码

在主函数中创建一个线程,调用 i2c、oled初始化接口,将初始化代码注册到系统运行回调中

#include <unistd.h>

#include "stdio.h"

#include "ohos_init.h"

#include "cmsis_os2.h"

#include "hi_io.h"

#include "hi_i2c.h"

#include "iot_errno.h"

#include "iot_i2c.h"

#include "iot_gpio.h"

#define OLED_I2C_BAUDRATE 400000

static void iot_i2c_init(void)

{

    IoTGpioInit(HI_IO_NAME_GPIO_0);

    IoTGpioInit(HI_IO_NAME_GPIO_1);

    //将引脚功能设置为 I2C 引脚

    hi_io_set_func(HI_IO_NAME_GPIO_0, HI_IO_FUNC_GPIO_0_I2C1_SDA);

    hi_io_set_func(HI_IO_NAME_GPIO_1, HI_IO_FUNC_GPIO_1_I2C1_SCL);

    //初始化 I2C0

    uint32_t ret = IoTI2cInit(HI_I2C_IDX_1, OLED_I2C_BAUDRATE);

    if (ret != IOT_SUCCESS) {

        printf("[OLED_TASK] Init i2c Fail. ret = %d\n", ret);

    }

    printf("[OLED_TASK] Init i2c succ.\n");

}

void oled_i2c_init(void)

{

    iot_i2c_init();

    OLED_Init();

    OLED_Clear();

}

void *oled_demo(const char *arg)

{

    (void)arg;

    char i = 0;

    char dat[10] = { 0 };

    oled_i2c_init();

    while (1) {

        printf("[OLED_TASK] i = %d!\n", i);

        OLED_ShowNum(10, 10, i++, 1, 8);

        osDelay(100);

    }

}

void oled_demo_init(void)

{

    osThreadAttr_t attr;

    attr.name = "OLED_Task";

    attr.attr_bits = 0U;

    attr.cb_mem = NULL;

    attr.cb_size = 0U;

    attr.stack_mem = NULL;

    attr.stack_size = 2048;

    attr.priority = 26;

    if (osThreadNew((osThreadFunc_t)oled_demo, NULL, &attr) == NULL) {

        printf("[OLED_TASK] Falied to create OLED_TASK!\n");

    }

}

SYS_RUN(oled_demo_init);

编译后通过 uart 下载代码

hb build -f

五、调试现象

### STM32 硬件 I2C 配置 OLED 显示器教程 #### 1. 系统准备 为了实现 STM32 和 OLED 的连接,需准备好硬件资源以及软件环境。确保拥有一个带有 I2C 接口的 STM32 开发板和一块兼容 I2C 协议的 OLED 屏幕。 #### 2. 硬件连接 通常情况下,OLED 屏幕的数据线 SDA 和时钟线 SCL 应分别接到 STM32 控制器对应的 I2C 数据线 (SDA) 及时钟线 (SCL)[^1]。具体引脚定义取决于所使用的开发板型号及其管脚分配情况。 #### 3. 软件设置 对于 STM32 来说,在 HAL 库的支持下可以很方便地初始化并操作 I2C 设备。下面是一个简单的例子来说明如何配置: ```c // 初始化 I2C 外设 void MX_I2C1_Init(void) { hi2c1.Instance = I2C1; hi2c1.Init.Timing = 0x20909CEC; // 设置通信速度与时序参数 hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); } } ``` 这段代码展示了如何使用 HAL 库函数 `MX_I2C1_Init` 对 I2C 进行基本配置。 #### 4. 使用 U8G2 库驱动 OLED U8G2 是一款广泛应用于单片机系统的图形库,能够很好地支持多种类型的 OLED/LCD 显示屏。这里给出一段基于该库的例子程序片段用于显示文字信息到屏幕上: ```cpp #include "u8g2.h" U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); void setup() { u8g2.begin(); } void loop() { u8g2.clearBuffer(); // clear the internal memory of the U8glib // pixel buffer and not the screen. u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font u8g2.drawStr(0,10,"Hello World!"); // write something to the internal memory // note that this does NOT send data to the display yet! u8g2.sendBuffer(); // transfer internal memory content to the display delay(1000); } ``` 上述 C++ 代码实现了通过调用 U8G2 类的方法完成屏幕清空、字体设定、字符串绘制等一系列动作,并最终将缓冲区中的图像数据发送给实际设备进行渲染[^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Top嵌入式

投喂个鸡腿

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值