0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

安信可VC-01/02二次开发篇: PWM输出

AIoT行业洞察 来源:AIoT行业洞察 作者:AIoT行业洞察 2025-08-27 16:06 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

wKgZO2iuvICAUfsJAADZnR7ctsE862.jpg


安信可离线语音VC-01/02:硬件规格书、开发资料、烧录工具、应用开发

安信可离线语音模组 VC-01、VC-02 系列教程 【基础认知篇】
安信可离线语音模组 VC-01、VC-02 系列教程 【快速上手篇】
安信可离线语音模组 VC-01、VC-02 系列教程 【中级入门篇】
安信可离线语音模组 VC-01、VC-02 系列教程 【高级进阶篇】
安信可离线语音模组 VC-01、VC-02 系列教程 【二次开发篇】虚拟开发环境搭建和分享
安信可离线语音模组 VC-01、VC-02 系列教程 【二次开发篇】事件和GPIO控制
安信可离线语音模组 VC-01、VC-02 系列教程 【二次开发篇】PWM输出
安信可离线语音模组 VC-01、VC-02 系列教程 【二次开发篇】串口输出
安信可离线语音模组 VC-01、VC-02 系列教程 【二次开发篇】SDK音频替换失败记录过程
安信可离线语音模组 VC-01、VC-02 系列教程 【二次开发篇】自定义音频播放控制

安信可离线语音模组 VC-01、VC-02 系列教程 【二次开发篇】PWM输出

简介

上一篇文章中我们对SDK的GPIO输出进行了控制, 我们将在本章节对PWM的输出进行控制(如果没有看过上一篇文章的,建议先去看对组件和设计的库函数的介绍),本篇SDK文件还是使用的上一章节的SDK(如无特殊说明,SDK不变)。

默认PWM DEMO输出现象

首先,在user_config.h 文件中开启对PWMLED的宏, 使其用户代码默认烧录USER_DEMO_PWM_LED的例程。

wKgZO2iuvIGAJHK5AAEfoHzIO58145.jpg

根据对应的hb_pwm_led.c 得知, 其线程启动后,主要是控制PWM_NUM_1_A27进行输出。

#define PWM_LED_GPIO_NUM  PWM_NUM_1_A27   // "MOSI" on HB-M demo board

首先对默认的Demo进行编译,并且下载到VC-02中。

示波器连接到开发板背部的GPIOA27上, 那么此时示波器的波形如下所示:

wKgZO2iuvIGAXAVHAAFYOeI3cew186.jpg


占空比缓慢变化

wKgZO2iuvIKAMuAuAAFbmQ6EB9o713.jpg

此时默认的出厂PWM demo已经测试完毕。

如果想控制对应的PWM输出,可以参考user_pwm.h 中的函数定义。函数声明如下所示:

#ifndef USER_INC_USER_PWM_H_
#define USER_INC_USER_PWM_H_
#ifdef __cplusplus
  extern "C" {
#endif
#include "unione.h"
/** @ingroup uni_pwm_def
* PWM管脚号
*/
typedef enum {
  PWM_NUM_1_A27 = 0,
  PWM_NUM_1_B0,
  PWM_NUM_1_B2,      ///< PWM 1 only 1 pin work a time
  PWM_NUM_2_A28,     ///< used for PA enable, don't use it on HB-M demo board
  PWM_NUM_2_B1,
  PWM_NUM_2_B3,      ///< PWM 2 only 1 pin work a time
  PWM_NUM_MAX
}USER_PWM_NUM;
/** @addtogroup uni_pwm_inf
@{*/
/**
*@brief PWM初始化
*@param num PWM管脚号
*@param hz 频率
*@param is_high_duty a TRUE :占空比用高电平持续时间计算; a FALSE :占空比用低电平持续时间计算
*@retval 0  操作成功
*@retval -1 操作失败
*/
int user_pwm_init(USER_PWM_NUM num, uni_u32 hz, uni_bool is_high_duty);
/**
*@brief PWM反初始化
*@param num PWM管脚号
*@retval 0  操作成功
*@retval -1 操作失败
*/
int user_pwm_final(USER_PWM_NUM num);
/**
*@brief 开使PWM输出
*@param num PWM管脚号
*@param duty 占空比
*@retval 0  操作成功
*@retval -1 操作失败
*/
int user_pwm_start(USER_PWM_NUM num, uni_u8 duty);
/**
*@brief 停止PWM输出
*@param num PWM管脚号
*@retval 0  操作成功
*@retval -1 操作失败
*/
int user_pwm_stop(USER_PWM_NUM num);
/**
*@brief 暂停PWM输出
*@param num PWM管脚号
*@retval 0  操作成功
*@retval -1 操作失败
*/
int user_pwm_pause(USER_PWM_NUM num);
/**
*@brief 恢复PWM输出
*@param num PWM管脚号
*@retval 0  操作成功
*@retval -1 操作失败
*/
int user_pwm_resume(USER_PWM_NUM num);
/**
*@brief PWM占空比切换
*@param num PWM管脚号
*@param duty 占空比
*@retval 0  操作成功
*@retval -1 操作失败
*/
int user_pwm_change_duty(USER_PWM_NUM num, uni_u8 duty);
/**
*@brief PWM占空比增加
*@param num PWM管脚号
*@param ch_duty 增加的占空比
*@retval 0  操作成功
*@retval -1 操作失败
*/
int user_pwm_duty_inc(USER_PWM_NUM num, uni_u8 ch_duty);
/**
*@brief PWM占空比减小
*@param num PWM管脚号
*@param ch_duty 减小的占空比
*@retval 0  操作成功
*@retval -1 操作失败
*/
int user_pwm_duty_dec(USER_PWM_NUM num, uni_u8 ch_duty);
/** @}*/
#ifdef __cplusplus
}
#endif
#endif

自定义控制命令

尝试使用唤醒命令 “你好小美” 来启动PWM进程, 使用 “打开台灯” 命令来删除这个进程,从而控制PWM进行输出。

由于官方的SDK写的非常规范, 所以建议凡是个人相关的代码都可以写在example目录下。

1、首先在example 目录下创建hb_user_pwm_testing.c 文件,代码如下所示:

#include "user_gpio.h"
#include "user_pwm_led.h"
#include "user_event.h"
#include "user_player.h"
#include "user_config.h"
#define PWM_LED_GPIO_NUM  PWM_NUM_1_A27   // "MOSI" on HB-M demo board
static uni_pthread_t g_pwm_thread_id = 0;
static bool g_pwm_thread_running = false;
// Thread function to update LED brightness levels
static void _pwm_led_process(void *args) {
  LED_BRIGHT_LEVEL level = BRIGHT_LEVEL_0;
  g_pwm_thread_running = true;
  while (g_pwm_thread_running) {
    user_pwm_led_set_brightness(PWM_LED_GPIO_NUM, level);
    level += 1;
    if (level >= BRIGHT_LEVEL_MAX) {
      level = BRIGHT_LEVEL_0;
    }
    // uni_sleep(1); // Optional: slow down effect
  }
}
// Create PWM LED thread
static Result _create_pwm_led_thread(void) {
  if (g_pwm_thread_running) {
    return E_OK;
  }
  thread_param param;
  uni_memset(¶m, 0, sizeof(param));
  param.stack_size = STACK_SMALL_SIZE;
  param.priority = OS_PRIORITY_LOW;
  uni_strncpy(param.task_name, "pwm_led", sizeof(param.task_name) - 1);
  if (0 != uni_pthread_create(&g_pwm_thread_id, ¶m, _pwm_led_process, NULL)) {
    return E_FAILED;
  }
  uni_pthread_detach(g_pwm_thread_id);  // Auto cleanup
  return E_OK;
}
// Stop PWM thread
static void _stop_pwm_led_thread(void) {
  if (!g_pwm_thread_running) {
    return;
  }
  g_pwm_thread_running = false;
  // Destroy thread if supported (may be platform-specific)
  if (g_pwm_thread_id != 0) {
    uni_pthread_destroy(g_pwm_thread_id);  // Hard stop
    g_pwm_thread_id = 0;
  }
  user_pwm_led_set_brightness(PWM_LED_GPIO_NUM, BRIGHT_LEVEL_0);  // Turn off LED
}
// Callback on voice command
static void _on_wakeup_cmd_cb(USER_EVENT_TYPE event, user_event_context_t *context) {
  if (context == NULL) return;
  event_goto_awakend_t *awake = &context->goto_awakend;
  if (strcmp(awake->cmd, "wakeup_uni") == 0) {
    _create_pwm_led_thread();
    user_player_reply_list_random(awake->reply_files);
  }
}
static void _custom_setting_cb(USER_EVENT_TYPE event,
                               user_event_context_t *context) {
  event_custom_setting_t *setting = NULL;
  if (context) {
    setting = &context->custom_setting;
    if (strcmp(setting->cmd, "TurnOn") == 0) {
       _stop_pwm_led_thread();
       user_player_reply_list_random(setting->reply_files);
    }
  }
}
// Register event callback
static void _register_event_callback(void) {
  user_event_subscribe_event(USER_GOTO_AWAKENED, _on_wakeup_cmd_cb);
  user_event_subscribe_event(USER_CUSTOM_SETTING, _custom_setting_cb);
}
// Main entry
int hb_user_pwm_testing(void) {
  if (0 != user_pwm_led_init(PWM_LED_GPIO_NUM)) {
    return -1;
  }
  _register_event_callback();
  return 0;
}

上述代码的主要功能是定义两个用户事件 :

第一个为自定义设置的事件。

另一个则是唤醒事件 (上一篇文章中有介绍)。在识别到 “你好小美” 和 “打开灯光” 的时候控制对应的PWM行为。 如果当前PWM输出的线程没有被创建, 那么当识别到“你好小美”的时候将启动线程。当识别到“打开灯光”的时候则根据上述创建线程时的线程号删除线程。

2、添加编译支持在

/home/vc02/Downloads/uni_hb_m_solution/unione_lite_app_hb_m/build/user/src/examples下的subdir.mk添加对当前编译文件的引用。

wKgZPGiuvIKAF3VQAADeahHReB8051.jpg

3、 修改/home/vc02/Downloads/uni_hb_m_solution/unione_lite_app_hb_m/user/inc/user_config.h文件, 增加对应的demo宏支持。

wKgZPGiuvIOANRKzAADujy2lv0E029.jpg

4、修改

/home/vc02/Downloads/uni_hb_m_solution/unione_lite_app_hb_m/user/src/user_main.c ,增加对上述自定义宏的支持。

wKgZPGiuvISALKSLAADRJEUFmaw369.jpg

wKgZO2iuvISAI098AADg37c4RYc176.jpg

5、编译并且烧录固件。

wKgZPGiuvIWAFPriAADE9OwCBng620.jpg

实验现象

默认上电波形如下(不清楚为什么会有毛刺)

wKgZO2iuvIWAOW16AAFak7M-fT4671.jpg

使用“你好小美” 唤醒,波形如下:

wKgZPGiuvIWAHtEyAAFaQVKi7O0215.jpg

wKgZPGiuvIaAJJ4ZAAFtHvsGndg375.jpg

使用“你好小美”唤醒 + “打开灯光” 关闭PWM,输出如下:

wKgZPGiuvIaADTszAAFdxVhedBE839.jpg

附件

uni_app_release_update.zip(882.62 KB, 下载次数: 0)

总结

在上文中主要结合IO和PWM的example进行了二次开发。其实可以发现,无论什么自定义功能,都是首先找到对应的库函数或者example进行引用。

在明白原理之后定义创建自己的.c 文件,然再将当前文件添加到编译的上下文中,在对应的h文件中开启对自定义C文件的宏定义,即可完成自定义的功能的二次开发。

实际上这个SDK的完整度非常高, 代码也非常规范!相信通过这几篇文章你能很快上手安信可的离线语音产品,下期再见~

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • PWM
    PWM
    +关注

    关注

    116

    文章

    5911

    浏览量

    227217
  • 安信可
    +关注

    关注

    0

    文章

    244

    浏览量

    5210
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    【请教】FPGA烧录软件工具二次开发问题

    请教各位大佬: Vivado 2018.3和Pango Design Suite 2025.1 这两款FPGA烧录软件工具能够二次开发吗?实现上位机控制软件调用它们,实现自动化的FPGA测试程序烧录和烧录成功的反馈信号。
    发表于 03-17 16:34

    宇树人形机器人的配置,核心代码,调试方法,二次开发接口

    宇树人形机器人的配置,核心代码,调试方法,二次开发接口
    的头像 发表于 12-10 09:05 6941次阅读

    先楫芯片赋能HPM生态灵巧手二次开发,工业控制/实验室原型速落地

    手动作精准度,更有HPMSDK提供FreeRTOS/ROS等丰富中间件,从底层驱动到应用层开发全流程覆盖,配合100万空载开合测试验证的稳定硬件,让二次开发既高效又可靠
    的头像 发表于 12-02 10:01 936次阅读
    先楫芯片赋能HPM生态灵巧手<b class='flag-5'>二次开发</b>,工业控制/实验室原型速落地

    小智AI语音模组实测:实现语音控制关灯

    ,完整复现一智能语音产品的测试流程。 No01、开箱与硬件初探 很幸运收到送测试的Ai-WV01
    的头像 发表于 11-19 16:09 1457次阅读
    <b class='flag-5'>安</b><b class='flag-5'>信</b><b class='flag-5'>可</b>小智AI语音模组实测:实现语音控制关灯

    基于Ai-WV01-32S模组打造的小智语音硬件

    基于 Ai-WV01-32S 模组打造的小智语音硬件。
    的头像 发表于 11-13 17:33 2094次阅读
    基于<b class='flag-5'>安</b><b class='flag-5'>信</b><b class='flag-5'>可</b>Ai-WV<b class='flag-5'>01</b>-32S模组打造的小智语音硬件

    将蜂鸟E203的内核移植到fpga之后该怎么进行二次开发呢?

    你们好!请问一下我将蜂鸟E203的内核移植到fpga之后该怎么进行二次开发呢?比如我想点亮板子上的led?驱动摄像头进行图像识别?这些该如何进行呢?蜂鸟有类似freedom studio这样的嵌入式开发平台吗?
    发表于 11-10 07:09

    直播回顾 | 掌握车载通信核心技术,虹科CAN总线实战:PCAN二次开发技术直播助您轻松拿捏总线开发“创新引擎

    •1CAN总线二次开发:构建智能汽车“神经网络”的核心能力在“软件定义汽车”的时代,整车电子电气架构正从分布走向集中,车载网络的数据量和复杂度呈指数级增长。基于PCAN等专业工具的二次开发能力
    的头像 发表于 10-09 17:33 871次阅读
    直播回顾 | 掌握车载通信核心技术,虹科CAN总线实战:PCAN<b class='flag-5'>二次开发</b>技术直播助您轻松拿捏总线<b class='flag-5'>开发</b>“创新引擎

    【离线语音】VC-01/02二次开发:自定义音频播放控制

    系列教程 【二次开发】虚拟开发环境搭建和分享 离线语音模组
    的头像 发表于 09-25 16:34 1066次阅读
    【离线语音】<b class='flag-5'>安</b><b class='flag-5'>信</b><b class='flag-5'>可</b><b class='flag-5'>VC-01</b>/<b class='flag-5'>02</b><b class='flag-5'>二次开发</b><b class='flag-5'>篇</b>:自定义音频播放控制

    如何使用SDK进行自定义音频播放功能

    在上一文章离线语音模组 VC-01VC-02 系列教程 【
    的头像 发表于 09-25 15:52 4596次阅读
    如何使用SDK进行自定义音频播放功能

    SDK音频替换失败记录过程

    离线语音模组 VC-01VC-02 系列教程 【中级入门】中根据设置的不同回复词和命
    的头像 发表于 09-25 15:50 2208次阅读
    SDK音频替换失败记录过程

    轻松配置小智AI语音开发板,IOT小程序功能更新

    版使用教程: AI语音开发板全面升级商用版!(附教程) 为了让开发体验更加流畅,
    的头像 发表于 08-19 17:46 1652次阅读
    轻松配置小智AI语音<b class='flag-5'>开发</b>板,<b class='flag-5'>安</b><b class='flag-5'>信</b><b class='flag-5'>可</b>IOT小程序功能更新

    VC-01/02二次开发: 事件和GPIO控制

    系列教程 【二次开发】虚拟开发环境搭建和分享 离线语音模组
    的头像 发表于 08-19 14:02 1512次阅读
    <b class='flag-5'>安</b><b class='flag-5'>信</b><b class='flag-5'>可</b><b class='flag-5'>VC-01</b>/<b class='flag-5'>02</b><b class='flag-5'>二次开发</b><b class='flag-5'>篇</b>: 事件和GPIO控制

    【离线语音】VC-01/02教程:中级入门

    系列教程 【二次开发】虚拟开发环境搭建和分享 离线语音模组
    的头像 发表于 07-31 09:33 1070次阅读
    【离线语音】<b class='flag-5'>安</b><b class='flag-5'>信</b><b class='flag-5'>可</b><b class='flag-5'>VC-01</b>/<b class='flag-5'>02</b>教程:中级入门<b class='flag-5'>篇</b>

    解锁LuatOS新世界:二次开发必备的3个核心常识

    踏入LuatOS的二次开发领域,掌握关键常识是开启高效编程之旅的第一步。本文将揭示三个不可或缺的核心要点,助你快速突破技术壁垒,深度挖掘系统潜力,让开发效率与创造力同步飙升。 本期一起
    的头像 发表于 06-23 16:08 510次阅读
    解锁LuatOS新世界:<b class='flag-5'>二次开发</b>必备的3个核心常识

    支持二次开发的工业级维码扫码读头选购指南

    在快节奏的工业环境中,如何让维码识别速度提升200%?面对复杂多变的扫码需求,普通扫码设备往往力不从心,而支持二次开发的工业级扫码读头正成为企业降本增效的秘密武器。本文将为您揭开选购工业级扫码读头
    的头像 发表于 06-11 16:05 915次阅读
    支持<b class='flag-5'>二次开发</b>的工业级<b class='flag-5'>二</b>维码扫码读头选购指南