【HarmonyOS HiSpark Wi-Fi IoT 套件试用连连载】第五篇、点亮LED及OLED屏 - HarmonyOS技术社区 - 电子技术论坛 - 广受欢迎的专业电子论坛
分享 收藏 返回

【HarmonyOS HiSpark Wi-Fi IoT 套件试用连连载】第五篇、点亮LED及OLED屏

` 本帖最后由 学海沙粒 于 2020-11-5 23:46 编辑

        第一篇个人代码是参考鸿蒙官方教程编写调试的,本篇文章将在“Hello World”基础上,点亮LED和OLED屏。
一、点亮LED
        官方源代码中已经写好LED驱动,用户只要稍加修改便可点亮LED,本小节目的在于梳理设备开发流程。
        1、找到源代码中关于LED驱动文件。打开applications/sample/wifi-iot/app/iothardware/led_example.c文件,如下所示。
  1. #include
  2. #include

  3. #include "ohos_init.h"
  4. #include "cmsis_os2.h"
  5. #include "wifiiot_gpio.h"
  6. #include "wifiiot_gpio_ex.h"

  7. #define LED_INTERVAL_TIME_US 300000    //延时时间
  8. #define LED_TASK_STACK_SIZE 512        //申请堆空间
  9. #define LED_TASK_PRIO 25                //LED任务优先级

  10. //LED状态
  11. enum LedState {
  12.     LED_ON = 0,   //亮
  13.     LED_OFF,        //灭
  14.     LED_SPARK,   //闪烁
  15. };

  16. enum LedState g_ledState = LED_SPARK;    //选择LED状态

  17. static void *LedTask(const char *arg)
  18. {
  19.     (void)arg;
  20.     while (1) {
  21.         switch (g_ledState) {
  22.             case LED_ON:
  23.                 GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 1);
  24.                 usleep(LED_INTERVAL_TIME_US);
  25.                 break;
  26.             case LED_OFF:
  27.                 GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 0);
  28.                 usleep(LED_INTERVAL_TIME_US);
  29.                 break;
  30.             case LED_SPARK:
  31.                 GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 0);
  32.                 usleep(LED_INTERVAL_TIME_US);
  33.                 GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 1);
  34.                 usleep(LED_INTERVAL_TIME_US);
  35.                 break;
  36.             default:
  37.                 usleep(LED_INTERVAL_TIME_US);
  38.                 break;
  39.         }
  40.     }

  41.     return NULL;
  42. }

  43. static void LedExampleEntry(void)
  44. {
  45.     osThreadAttr_t attr;

  46.     GpioInit();  //管脚初始化
  47.     IoSetFunc(WIFI_IOT_IO_NAME_GPIO_9, WIFI_IOT_IO_FUNC_GPIO_9_GPIO);  //配置9号管脚作为GPIO
  48.     GpioSetDir(WIFI_IOT_IO_NAME_GPIO_9, WIFI_IOT_GPIO_DIR_OUT);        //配置9号管脚为输出

  49.     attr.name = "LedTask";
  50.     attr.attr_bits = 0U;
  51.     attr.cb_mem = NULL;
  52.     attr.cb_size = 0U;
  53.     attr.stack_mem = NULL;
  54.     attr.stack_size = LED_TASK_STACK_SIZE;
  55.     attr.priority = LED_TASK_PRIO;

  56.     if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL) {
  57.         printf("[LedExample] Falied to create LedTask!
  58. ");
  59.     }
  60. }

  61. SYS_RUN(LedExampleEntry);
      
函数说明:  
   (1)unsigned int GpioSetOutputVal(WifiIotGpioIdx id, WifiIotGpioValue val)
        功能:指定引脚输出高低电平
        --id:引脚号
        --val:输出电平
    (2)unsigned int IoSetFunc(WifiIotIoName id, unsigned char val)
        功能:设置GPIO引脚的复用功能。
        --id:引脚号
        --val:指示I / O复用功能
    (3)unsigned int GpioSetDir(WifiIotGpioIdx id, WifiIotGpioDir dir)
       功能:设置GPIO引脚的方向
        --id:引脚号
        --val:指示GPIO输入/输出方向
    (4)osThreadId_t osThreadNew(osThreadFunc_t func, void *argument, const osThreadAttr_t *attr)
       功能:线程管理函数,或理解为任务注册函数

        2、打开applications/sample/wifi-iot/app/iothardware/BUILD.c
  1. static_library("led_example") {
  2.     sources = [
  3.         "led_example.c"
  4.     ]

  5.     include_dirs = [
  6.         "//utils/native/lite/include",
  7.         "//kernel/liteos_m/components/cmsis/2.0",
  8.         "//base/iot_hardware/interfaces/kits/wifiiot_lite",
  9.     ]
  10. }
  • static_library中指定业务模块的编译结果,为静态库文件led_example.a。
  • sources中指定静态库.a所依赖的.c文件及其路径,若路径中包含"//"则表示绝对路径(此处为代码根路径),若不包含"//"则表示相对路径。
  • include_dirs中指定source所需要依赖的.h文件路径。

    3、打开applications/sample/wifi-iot/app/BUILD.gn文件
  1. import("//build/lite/config/component/lite_component.gni")
  2. lite_component("app") {
  3.     features = [
  4.         "iothardware:led_example"
  5.     ]
  6. }
        在features字段中增加索引,使目标模块参与编译。features字段指定业务模块的路径和目标,此处就填写"iothardware:led_example"。

    4、编译、烧录后,可以看见开发板LED闪烁。

二、点亮OLED屏
        OLED的开发流程与点亮LED的流程大体是一致的,只是OLED需要用户自己编写驱动。        1、首先在applications/sample/wifi-iot/app下建立oled_demo文件夹,然后在applications/sample/wifi-iot/app/oled_demo下建立oled_demo.c(OLED驱动)、oled_demo.h(OLED头文件)、oled_font.h(OLED字库)、BUILD.gn(编译脚本)四个文件。
oled_demo文件夹.png
         2、OLED采用I2C驱动,所以在编写驱动代码前要使能I2C。找到vender/hisi/hi3861/hi3861/app/wifiiot_app/init/app_io_init.c文件,修改I2C引脚定义,板卡上 引脚是GPIO13(I2C0_SDA)和GPIO14(I2C0_SCL),所以将I2C引脚修改如下。
I2C引脚定义.png
        然后再找到vendor/hisi/hi3861/hi3861/build/config/usr_config.mk文件,添加"CONFIG_I2C_SUPPORT=y",使能I2C功能,类似宏使能。至此3861可以使用I2C功能了。
    使能I2C引脚.png
        3、开发板上oled屏驱动芯片为ssd1306,打开上面新建的oled_demo.c文件,开始编写oled驱动。

  1. void oled_demo(void)
  2. {
  3.     //I2C初始化
  4.     hi_i2c_init(HI_I2C_IDX_0, 100000); /* baudrate: 100000 */

  5. oled_init();

  6.     OLED_ColorTurn(0);    //0 正常显示;1 反色显示
  7.     OLED_DisplayTurn(0);  //0 正常显示;1 屏幕翻转显示

  8.     OLED_ShowString(8,16,"hello world",16);

  9.     OLED_Refresh();
  10. }
  • 首先是I2C初始化——hi_i2c_init(hi_i2c_idx id, hi_u32 baudrate),该函数由hi3861库提供;
  • oled_init(),oled初始化,通过I2C写函数对oled寄存器进行设置;
  • OLED_ColorTurn(0),设置屏幕背景色,实际也是通过I2C写函数对oled寄存器进行写数据;
  • OLED_DisplayTurn (0),设置显示是否翻转180度;
  • OLED_ShowString(8,16,"hello world",16),在指定位置显示字符;
  • OLED_Refresh(),刷新显示屏。

        oled_demo.h文件用于存放各种宏以及c文件中要用到其他数据,用户可以自由设计;oled_font.h用于存放字符。


        BUILD.gn文件用于设置编译脚本。
  1. static_library("oled_demo") {
  2.     sources = [
  3.         "oled_demo.c"
  4.     ]

  5.     include_dirs = [
  6.         "//utils/native/lite/include",
  7.         "//kernel/liteos_m/components/cmsis/2.0",
  8.     ]
  9. }
        以上是oled驱动的大体流程,实际代码很多,包括对I2C写函数封装、判断是输入数据还是输入指令,显示字符功能还需要编写画点函数、字符大小整理等,详细代码见附件(说明:代码来源于连志安老师)。

` LED闪烁.gif
oled_demo.zip (6.77 KB)
(下载次数: 1, 2020-11-5 23:39 上传)

更多回帖

×
发帖