[文章]【HarmonyOS HiSpark Wi-Fi IoT 套件试用连载】播放音乐

阅读量0
0
1

【HarmonyOS HiSpark Wi-Fi IoT 套件试用连载】从零开始HarmonyOS

【HarmonyOS HiSpark Wi-Fi IoT 套件试用连载】会唱歌的红绿灯

前面因为北海的疫情,科室抽搞了人员去支援,所单位的事一直在超负荷工作,这一个月都没有时间写文章,现在恢复正常,接上面的继续学习套件的学习,并分享给大家。

前面自己用pwm写过一个可以播放音乐的帖子,是用liteos来写的,这次学习了HarmonyOS来实现这一功能。

1、新建工程,按下图

image.png

image.png

然后点击创建:

image.png

等待下载结束,在弹出的对话框中选择当前窗口:

image.png

2、主要代码分析:

#define IOT_TEST_PWM_GPIO9 9 // 指定蜂鸣器的pwm输出IO
#define IOT_PWM_PORT0 0

#define IOT_IO_NAME_GPIO_8 8    // 按键检测IO
#define PWM_DUTY 50      //占空比
#define M_INTERVAL_TIME_TICK 60  
#define TICKS_DELAY  125*1000

3、频率与音符的对应:

static const uint16 g_tuneFreqs[] = {
    0,        // 40M Hz 对应的分频系数:
    1046 * 4, // 1046.50  1
    1174 * 4, // 1174.66  2
    1318 * 4, // 1318.51  3
    1396 * 4, // 1396.91  4
    1567 * 4, // 1567.99  5
    1760 * 4, // 1760.00  6
    1975 * 4, // 1975.53  7
    523 * 4,  // 523.25   1-  低一个8度的1
    587 * 4,  // 587.33   2-
    659 * 4,  // 659.26   3-   
    698 * 4,   // 698.46  4-
    783 * 4,  // 783.99   5-
    880 * 4,   // 880.00  6-
    987 * 4,  // 987.77   7-    
};

4、定义音符与节拍:

typedef enum
{
    D_DO = 1,  // 1
    D_RE,      // 2
    D_MI,      // 3
    D_FA,      // 4
    D_SO,      // 5
    D_LA,      // 6
    D_SI,      // 7
    C_DO,      // 1- 
    C_RE,      // 2- 
    C_MI,      // 3-
    C_FA,      // 4- 
    C_SO,      // 5- 
    C_LA,      // 6- 
    C_SI       // 7-     
} MusicTuneNotes;

typedef enum
{
    BEAT_1X4B = 1,   //4分之1拍为基础值1
    BEAT_1X2B,
    BEAT_3X4B,
    BEAT_1B,
    BEAT_3X2B = 6,
    BEAT_2B = 8,
    BEAT_3B = 12,
    BEAT_4B = 16
} MusicTuneInterval;

/*音符与时间间隔结构体*/
typedef struct
{
    MusicTuneNotes tuneNotes;       //音符
    MusicTuneInterval interval;     //时间间隔
} MusicNotesInterval;

5、曲谱,数组里面定义了音符与节拍:

*曲谱*/
static const MusicNotesInterval g_interval[] = {
    {D_MI,BEAT_1X2B},{D_SO,BEAT_1X2B},{D_SO,BEAT_3X4B},{D_LA,BEAT_1X4B},{D_SO,BEAT_1X2B},{D_MI,BEAT_1X2B},{D_DO,BEAT_1X2B},
    {D_DO,BEAT_1X4B},{D_RE,BEAT_1X4B},{D_MI,BEAT_1X2B},{D_MI,BEAT_1X2B},{D_RE,BEAT_1X2B},{D_DO,BEAT_1X2B},{D_RE,BEAT_2B},
    {D_MI,BEAT_1X2B},{D_SO,BEAT_1X2B},{D_SO,BEAT_3X4B},{D_LA,BEAT_1X4B},{D_SO,BEAT_1X2B},{D_MI,BEAT_1X2B},{D_DO,BEAT_1X2B},
    {D_DO,BEAT_1X4B},{D_RE,BEAT_1X4B},{D_MI,BEAT_1X2B},{D_MI,BEAT_1X2B},{D_RE,BEAT_1X2B},{D_RE,BEAT_1X2B},{D_DO,BEAT_2B},
    {D_FA,BEAT_1B},{D_FA,BEAT_1B},{D_FA,BEAT_1X2B},{D_LA,BEAT_3X2B},{D_SO,BEAT_1B},{D_SO,BEAT_3X4B},{D_MI,BEAT_1X4B},
    {D_RE,BEAT_2B},{D_MI,BEAT_1X2B},{D_SO,BEAT_1X2B},{D_SO,BEAT_3X4B},{D_LA,BEAT_1X4B},{D_SO,BEAT_1X2B},{D_MI,BEAT_1X2B},
    {D_DO,BEAT_1X2B},{D_DO,BEAT_1X4B},{D_RE,BEAT_1X4B},{D_MI,BEAT_1X2B},{D_MI,BEAT_1X2B},{D_RE,BEAT_1X2B},{D_RE,BEAT_1X2B},
    {D_DO,BEAT_2B}
};

6、按键响应函数,当按键按下后更新标志位music:

/*按键响应函数*/
static void OnButtonPressed(char *arg)
{
    (void)arg;
    IoTGpioUnregisterIsrFunc(IOT_IO_NAME_GPIO_8);

    music = 1;
    printf("
>>>>>>>>>>button is enter >>>.[%d]
", music);

    IoTGpioRegisterIsrFunc(IOT_IO_NAME_GPIO_8, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW, 
    OnButtonPressed, NULL);
}

7、音乐处理函数:

static void *BeeperMusicTask(const char *arg)
{
    (void)arg;
    
    printf("BeeperMusicTask start!
");

    hi_pwm_set_clock(PWM_CLK_XTAL); // 设置时钟源为晶体时钟(40MHz,默认时钟源160MHz)

    while (1)
    {
        osDelay(M_INTERVAL_TIME_TICK);
        /*第一次点击按键播放,播放完以后按键才能继续生效*/
        if (music == 1)
        {
            for (size_t i = 0; i < sizeof(g_interval) / sizeof(g_interval[0]); i++)
            {  
                uint32 tune = g_interval[i].tuneNotes; // 音符
                uint16 freqDivisor = g_tuneFreqs[tune];
                uint32 tuneInterval = g_interval[i].interval * (TICKS_DELAY); // 音符时间
                IoTPwmStart(IOT_PWM_PORT0, PWM_DUTY, freqDivisor);
                usleep(tuneInterval);
                IoTPwmStop(IOT_PWM_PORT0);
                music = 0;
            }
        }
    }

    return NULL;
}

8、创建音乐播放任务:

static void BeepMusicEntry(void)
{
    osThreadAttr_t attr;
    /* 初始化按键 */
    IoTGpioInit(IOT_IO_NAME_GPIO_8);   //button
    IoTGpioSetDir(IOT_IO_NAME_GPIO_8, IOT_GPIO_DIR_IN);
    /* 注册按键中断回调 */
    IoTGpioRegisterIsrFunc(IOT_IO_NAME_GPIO_8, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW, OnButtonPressed, NULL);
    /* 初始化蜂鸣器输出IO */
    IoTGpioInit(IOT_TEST_PWM_GPIO9);      //BWM
    IoTGpioSetDir(IOT_TEST_PWM_GPIO9, IOT_GPIO_DIR_OUT);
    IoTPwmInit(IOT_PWM_PORT0);

    IoTWatchDogDisable();

    attr.name = "BeeperMusicTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 1024;
    attr.priority = osPriorityNormal;

    if (osThreadNew((osThreadFunc_t)BeeperMusicTask, NULL, &attr) == NULL)
    {
        printf("[BeeperMusicTask] Falied to create BeepTask!
");
    }
}

9、开机创建启动:APP_FEATURE_INIT(BeepMusicEntry);

【设置编译选项】

1、在applications/sample/wifi-iot/app/demo_beep下的BUILD.gn创建jison:

static_library("demo_beep") {
    sources = [
        "beep_music_demo.c"
    ]

    include_dirs = [
        "//utils/native/lite/include",
        "//kernel/liteos_m/components/cmsis/2.0",
        "//base/iot_hardware/peripheral/interfaces/kits",
    ]
}

2、在applications/sample/wifi-iot/app下面创建BUILD.gn:

import("//build/lite/config/component/lite_component.gni")

lite_component("app") {
    features = [
        "demo_beep",
    ]
    deps = []
}

【编译】:

image.png

到这一步就显示编译成功了:

image.png

【拷贝文件到HiBurn目录下面】输出的文件在/home/hihope/Documents/DevEco/Projects/lyevk_hm_beep/out/hispark_pegasus/wifiiot_hispark_pegasus目录下面:

1660288320029.png

将Hi3861_wifiiot_app_allinone.bin复制到win下面。然后烧录到开发板就OK了。

image.png

重启开发板,按下按键,就可以播放音乐了。

image.png

回帖

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
链接复制成功,分享给好友