当前位置:   article > 正文

【XR806开发板试用】系列之二 - I2C外设使用及控制OLED屏显示

【XR806开发板试用】系列之二 - I2C外设使用及控制OLED屏显示

本文参与极术社区的《基于安谋科技STAR-MC1的XR806开发板试用》活动。

前言

XR806硬件上支持SPI,I2C等其他外设接口,且DDR和FLASH,满足常见应用场景的开发,适合开发者进行方案评估、DIY或小规模产品研发使用。本篇文章,将使用到I2C接口,去控制OLED屏幕的显示。

OLED屏幕规格: 0.96英寸 主控SSD1306 I2C接口 地址 0x3C
XR806外设:I2C1

创建工程

参考device/xradio/xr806/ohosdemo目录下的wlan_demo,

拷贝wlan_demo为xr806_oled,并同步修改ohosdemo和xr806_oled目录下的BUILD.gn。

主要修改如下:

  1. device/xradio/xr806/ohosdemo/BUILD.gn

    group("ohosdemo") {
     deps = [
         #"hello_demo:app_hello",
         #"iot_peripheral:app_peripheral",
         #"wlan_demo:app_WlanTest",
         "xr806_oled:app_oled", #增加app_oled目标编译
     ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  2. device/xradio/xr806/ohosdemo/xr806_oled/BUILD.gn

    static_library("app_oled") {
       configs = []
    
       sources = [
      "main.c",
       ]
    
       cflags = board_cflags
    
       include_dirs = board_include_dirs
       include_dirs += [
        ".",
        "thirdparty/ssd1306/ssd1306",
        "//utils/native/lite/include",
        "//foundation/communication/wifi_lite/interfaces/wifiservice",
       ]
    
       deps = [
        "thirdparty/ssd1306/ssd1306:oled_ssd1306",
       ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    注意:
    1.static_library代表生成静态库(.a)文件,其中包含main.c的静态库必须是app_打头,如app_hello,否则虽然可以编译成功,但无法生效;

    1. xr806_oled/BUILD.gn中静态库app_oled的命名,需要和ohosdemo/BUILD.gn中的一致;
    2. thirdparty/ssd1306/ssd1306:oled_ssd1306 为依赖的开源库

工程编译

创建工程后,如果非首次编译,执行以下命令便可以编译:

hb build
  • 1

编译如果遇到以下错误:

[OHOS ERROR] /*
[OHOS ERROR]  *
[OHOS ERROR]  * Automatically generated file; DO NOT EDIT.
[OHOS ERROR]  * XR806 SDK Configuration
[OHOS ERROR]  *
[OHOS ERROR]  */
[OHOS ERROR] /*
[OHOS ERROR]  *
[OHOS ERROR]  * Automatically generated file; DO NOT EDIT.
[OHOS ERROR]  * XR806 SDK Configuration
[OHOS ERROR]  *
[OHOS ERROR]  */
[OHOS ERROR] {
[OHOS ERROR]     "magic" : "AWIH",
[OHOS ERROR]     "version" : "0.5",
[OHOS ERROR]     "image" : {"max_size": "1532K"},
[OHOS ERROR]     "section" :[
[OHOS ERROR]   {"id": "0xa5ff5a00", "bin" :"boot_40M.bin", "cert": "null", "flash_offs": "0K", "sram_offs": "0x00230000", "ep": "0x00230101", "attr":"0x1"},
[OHOS ERROR]   {"id": "0xa5fe5a01", "bin" :"app.bin", "cert": "null", "flash_offs": "32K", "sram_offs": "0x00201000", "ep": "0x00201101", "attr":"0x1"},
[OHOS ERROR]   {"id": "0xa5fd5a02", "bin" :"app_xip.bin", "cert": "null", "flash_offs": "99K", "sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x2"},
[OHOS ERROR]   {"id": "0xa5fa5a05", "bin" :"wlan_bl.bin", "cert": "null", "flash_offs": "1170K", "sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"},
[OHOS ERROR]   {"id": "0xa5f95a06", "bin" :"wlan_fw.bin", "cert": "null", "flash_offs": "1173K", "sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"},
[OHOS ERROR]   {"id": "0xa5f85a07", "bin" :"sys_sdd_40M.bin", "cert": "null", "flash_offs": "1198K", "sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"},
[OHOS ERROR]   {}
[OHOS ERROR]  ]
[OHOS ERROR] }
[OHOS ERROR] 
[OHOS ERROR] make[2]: *** [../../../../project/project.mk:520:image] 错误 255
[OHOS ERROR] make[2]: 离开目录“/home/algo/openharmony/xr806/device/xradio/xr806/xr_skylark/project/demo/audio_demo/gcc”
[OHOS ERROR] make[1]: *** [../../../../project/project.mk:493:__build] 错误 2
[OHOS ERROR] make[1]: 离开目录“/home/algo/openharmony/xr806/device/xradio/xr806/xr_skylark/project/demo/audio_demo/gcc”
[OHOS ERROR] make: *** [Makefile:164:build] 错误 2
[OHOS ERROR] you can check build log in /home/algo/openharmony/xr806/out/xr806/wifi_skylark/build.log
[OHOS ERROR] /home/algo/.local/bin/ninja -w dupbuild=warn -C /home/algo/openharmony/xr806/out/xr806/wifi_skylark failed, return code is 1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

执行以下命令后,再次编译即可:

cp  device/xradio/xr806/xr_skylark/project/demo/audio_demo/image/xr806/image_auto_cal.cfg  device/xradio/xr806/xr_skylark/project/demo/audio_demo/image/xr806/image.cfg
  • 1

编译后生成的镜像,便可以烧录验证。

注:以上基础工程是基于wlan_demo,oled屏幕显示需要使用I2C外设和移植oled库
  • 1

库移植

其实XR806本身自带了OLED主控为SSD1306的驱动(采用的是SPI接口方式),移植基于I2C接口的库也相对简单,可以参考开源库
harmonyos-ssd1306,将其中的I2C相关头文件和API替换为XR806 OpenHarmony中的相关头文件和API,编译通过即可。

其中涉及到BUID.gn的修改如下:

static_library("oled_ssd1306") {
    sources = [
        "ssd1306.c",
        "ssd1306_fonts.c",
    ]

    include_dirs = [
        ".",
        "//kernel/liteos_m/kernel/arch/include",
        "//utils/native/lite/include",
        "//base/iot_hardware/peripheral/interfaces/kits",
    ]
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

开源库主要修改如下:

#include "iot_i2c.h"
#include "iot_errno.h"

/**
 * @brief Defines I2C data transmission attributes.
 */
typedef struct {
    /** Pointer to the buffer storing data to send */
    unsigned char *sendBuf;
    /** Length of data to send */
    unsigned int  sendLen;
    /** Pointer to the buffer for storing data to receive */
    unsigned char *receiveBuf;
    /** Length of data received */
    unsigned int  receiveLen;
} IotI2cData;  


static uint32_t ssd1306_SendData(uint8_t* data, size_t size)
{
    uint32_t id = SSD1306_I2C_IDX;
    IotI2cData i2cData = {0};
    i2cData.sendBuf = data;
    i2cData.sendLen = size;

    return IoTI2cWrite(id, SSD1306_I2C_ADDR, i2cData.sendBuf, i2cData.sendLen);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

ssd1306.h头文件定义SSD1306_I2C_IDX为1

显示程序

程序部分参考了上面提到的OLED库,完整的测试程序,可以参考harmonyos-ssd1306里的example.

/*
 * Copyright (c) 2021-2031, AlgoIdeas
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2020-12-13     AlgoIdeas    the first version
 */

#include <stdio.h>
#include "ohos_init.h"
#include "kernel/os/os.h"
#include "ssd1306.h"

#define OLED_I2C_BAUDRATE       100000

static OS_Thread_t g_main_thread;


static void DrawChinese(void)
{
    const uint32_t W = 12, H = 12, S = 16;
    uint8_t fonts[][24] = {
        {
            /*-- ID:0,字符:"您",ASCII编码:C4FA,对应字:宽x高=12x12,画布:宽W=16 高H=12,共24字节*/
            0x14,0x00,0x24,0x00,0x2F,0xF0,0x71,0x20,0xA5,0x40,0x29,0x20,0x33,0x10,0x20,0x00,
            0x54,0x40,0x52,0xA0,0x90,0x90,0x0F,0x80,
        },{
            /*-- ID:1,字符:"好",ASCII编码:BAC3,对应字:宽x高=12x12,画布:宽W=16 高H=12,共24字节*/
            0x20,0x00,0x27,0xE0,0x20,0x40,0xF8,0x80,0x48,0x80,0x48,0xA0,0x57,0xF0,0x50,0x80,
            0x30,0x80,0x28,0x80,0x4A,0x80,0x81,0x00,
        },{
            /*-- ID:2,字符:"鸿",ASCII编码:BAE8,对应字:宽x高=12x12,画布:宽W=16 高H=12,共24字节*/
            0x00,0x40,0x80,0x80,0x5D,0xE0,0x09,0x20,0xC9,0xA0,0x09,0x60,0x29,0x00,0xCD,0xF0,
            0x58,0x10,0x43,0xD0,0x40,0x10,0x40,0x60,
        },{
            /*-- ID:3,字符:"蒙",ASCII编码:C3C9,对应字:宽x高=12x12,画布:宽W=16 高H=12,共24字节*/
            0x09,0x00,0x7F,0xE0,0x09,0x00,0x7F,0xF0,0x80,0x10,0x7F,0xE0,0x0C,0x40,0x32,0x80,
            0xC7,0x00,0x0A,0x80,0x32,0x70,0xC6,0x20
        }
    };

    ssd1306_Fill(Black);
    for (size_t i = 0; i < sizeof(fonts)/sizeof(fonts[0]); i++) {
        ssd1306_DrawRegion(i * H + 32, 26, W, H, fonts[i], sizeof(fonts[0]), S);
    }
    ssd1306_UpdateScreen();
    sleep(1);
}

static void MainThread(void *arg)
{
    IoTI2cInit(SSD1306_I2C_IDX, OLED_I2C_BAUDRATE);

    usleep(20*1000);

    printf("ssd1306_Init.\n");
    ssd1306_Init();
    ssd1306_Fill(Black);
    ssd1306_SetCursor(22, 27);
    ssd1306_DrawString("Hello XR806!", Font_7x10, White);

    uint32_t start = HAL_GetTick();
    ssd1306_UpdateScreen();
    uint32_t end = HAL_GetTick();
    printf("ssd1306_UpdateScreen, time cost: %d ms.\n", end - start);

    usleep(2000*1000);

    while (1) {
        DrawChinese();
    }
}

void OledMain(void)
{
     if (OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL,
                OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK) {
         printf("[ERR] Create MainThread Failed\n");
     }
}

SYS_RUN(OledMain);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84

运行效果

最终OLED显示:您好鸿蒙
在这里插入图片描述

参考资料

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/288245
推荐阅读
相关标签
  

闽ICP备14008679号