导航

    全志在线开发者论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 在线文档
    • 社区主页

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

    Wireless & Analog Series
    6
    8
    3282
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • q1215200171
      budbool LV 9 最后由 编辑

      前言
      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目标编译
       ]
      }
      

      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",
         ]
      }
      

      注意:

      • static_library代表生成静态库(.a)文件,其中包含main.c的静态库必须是app_打头,如app_hello,否则虽然可以编译成功,但无法生效;
      • ~~xr806_oled/BUILD.gn中静态库app_oled的命名,需要和ohosdemo/BUILD.gn中的一致;
      • thirdparty/ssd1306/ssd1306:oled_ssd1306 为依赖的开源库

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

      hb build
      

      编译如果遇到以下错误:

      [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
      

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

      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
      

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

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

      库移植
      其实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",
          ]
      }
      

      开源库主要修改如下:

      #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);
      }
      

      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);
      

      运行效果
      最终OLED显示:您好鸿蒙
      1003546875-61b74f422e829.jfif

      参考资料
      【XR806开发板试用】系列之一 - Linux环境下Ubuntu完全开发流程
      https://xr806.docs.aw-ol.com/
      https://aijishu.com/a/1060000000256653

      本贴转自极术社区:https://aijishu.com/a/1060000000284333
      作者:H2O2_H2O2

      1 条回复 最后回复 回复 引用 分享 2
      • Z
        zhugx LV 5 最后由 编辑

        很棒,希望还能open更多的使用示例

        1 条回复 最后回复 回复 引用 分享 0
        • H
          HU_710774265 LV 4 最后由 编辑

          我看了一圈没发现i2c 是 17 18 的介绍。。
          PB14/UART1_TX/UART2_TX/TWI1_SCL/UART0_CTS/EINTB14
          PB15/UART1_RX/UART2_RX/TWI1_SDA/UART0_RTS/EINTB15
          我是遗漏啥了吗? 希楼主告知

          Randolph 1 条回复 最后回复 回复 引用 分享 0
          • Randolph
            Randolph LV 6 @HU_710774265 最后由 Randolph 编辑

            @hu_710774265 可以看看板级配置文件,在

            Harmony\device\xradio\xr806\xr_skylark\project\common\board\xr806_OHOS\board_config.c
            

            可以看到关于i2c的相关端口配置。

            比如我的是这样
            93cd761c-7f63-4e86-b6c4-c9a93ee96c31-image.png

            H 1 条回复 最后回复 回复 引用 分享 0
            • H
              HU_710774265 LV 4 @Randolph 最后由 编辑

              @randolph 收到。。

              1 条回复 最后回复 回复 引用 分享 0
              • L
                ljfly LV 2 最后由 编辑

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

                xr_skylark\project\common\board\xr806_OHOS\board_config.c

                请教一下,我的设备初始化什么的都挺正常,但是过一会就会提示
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address

                确认过设备的地址是0x78
                我直接把宏定义为:

                #define SSD1306_I2C_ADDR        (0x78)
                

                还有哪里需要改嘛?

                详细log:

                console init success
                ssd1306_Init.
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                ssd1306_UpdateScreen send frame data filed: -1!
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                ssd1306_UpdateScreen send frame data filed: -1!
                ssd1306_UpdateScreen, time cost: 6 ms.
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                ssd1306_UpdateScreen send frame data filed: -1!
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                ssd1306_UpdateScreen send frame data filed: -1!
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                ssd1306_UpdateScreen send frame data filed: -1!
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                ssd1306_UpdateScreen send frame data filed: -1!
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                ssd1306_UpdateScreen send frame data filed: -1!
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                ssd1306_UpdateScreen send frame data filed: -1!
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                ssd1306_UpdateScreen send frame data filed: -1!
                [HAL ERR] I2C_IRQHandler():494, Invalid IIC address
                ssd1306_UpdateScreen send frame data filed: -1!
                
                I 1 条回复 最后回复 回复 引用 分享 0
                • I
                  何镜勇 LV 4 @ljfly 最后由 编辑

                  @ljfly SSD1306有两个地址可选,看看选择是哪一个。另外可以用逻辑分析仪看看,是XR806端没有输出,还是说SSD1306没有应答。

                  L 1 条回复 最后回复 回复 引用 分享 0
                  • L
                    ljfly LV 2 @I_A_student 最后由 编辑

                    @i_a_student 非常感谢,地址错误问题确认过了,地址搞错了,屏的地址没有按照他们标的来,太坑了。。。。

                    1 条回复 最后回复 回复 引用 分享 0
                    • 1 / 1
                    • First post
                      Last post

                    Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号

                    行为准则 | 用户协议 | 隐私权政策