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

    文章

    5698

    浏览量

    220657
  • 安信可
    +关注

    关注

    0

    文章

    201

    浏览量

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

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

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

    系列教程 【二次开发】虚拟开发环境搭建和分享 离线语音模组
    的头像 发表于 08-19 14:02 ?229次阅读
    <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 ?330次阅读
    【离线语音】<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>

    云MES系统源码,支持 SaaS 多租户,支持二次开发

    万界星空科技MES生产制造执行系统源码,有演示,多个项目应用案例,成熟稳定。支持二次开发,商业授权后商用。
    的头像 发表于 05-07 11:14 ?318次阅读
    云MES系统源码,支持 SaaS 多租户,支持<b class='flag-5'>二次开发</b>

    离线语音开发板:二次开发语音控制LED灯

    前言 经过前面的学习,相信大家已经了解离线语音开发环境的搭建流程。甚至已经编译过固件,并进行了测试。本文将从产品创建开始讲起,一步一步实现语音控制LED的功能。 语音开放平台:
    的头像 发表于 03-19 10:53 ?483次阅读
    <b class='flag-5'>安</b><b class='flag-5'>信</b><b class='flag-5'>可</b>离线语音<b class='flag-5'>开发</b>板:<b class='flag-5'>二次开发</b>语音控制LED灯

    DLP6500想调用API进行自主二次开发,怎么构建开发环境?

    请问一下,我购置了DLP6500型号产品,想利用该产品进行开发,实现高速投影的功能。 但是我现在只找到了GUI界面,请问一下,如果我想调用API进行自主二次开发,怎么构建开发环境? 最好有相关的技术指导文件,谢谢。
    发表于 03-03 07:03

    怎么配置dlp6500二次开发的环境,可以使用VS2013吗?

    我想请问一下,怎么配置dlp6500二次开发的环境,可以使用VS2013吗?有没有什么可以参考的文件,感谢!
    发表于 02-28 06:39

    请问LDC1312EVM和TI提供的软件GUI能被二次开发吗?

    请问LDC1312EVM和TI提供的软件GUI能被二次开发吗,想做个测试台供车间员工使用。
    发表于 02-26 06:35

    DLP4500-C350REF如何在linux下借助SDK二次开发

    请问在哪里有二次开发环境配置文档
    发表于 02-18 08:24

    深居浅出AutoCAD二次开发

    深居浅出AutoCAD二次开发,net版
    发表于 01-06 14:12 ?9次下载

    TSW14J56EVM板卡提供二次开发的接口怎么使用的?

    TSW14J56EVM板卡提供二次开发的接口怎么使用的,有没有详细的使用说明文档?
    发表于 01-03 07:29

    LoRa答疑】Ra-01、Ra-02常见问题

    LoRa 系列模块Ra-01、Ra-02,其射频芯片 SX1278 主要采用 LoRa?远程调制解调器,用于超长距离扩频通信,抗干扰
    的头像 发表于 12-29 10:49 ?1393次阅读

    SOLIDWORKS二次开发参数化设计工具? 慧德敏学

    SOLIDWORKS二次开发参数化设计工具?涵盖选型、建模、装配、出图、编码、报表、集成等众多环节和任务的整合,我们除了提供专业培训,还可针对实际产品提供项目导入,实现交钥匙工程,消除企业的所有风险
    的头像 发表于 12-20 16:21 ?575次阅读

    SOLIDWORKS二次开发应用范围与实例

    SOLIDWORKS二次开发为企业和设计师们提供了广阔的定制化空间,能够更好地满足复杂多变的设计需求,帮助工程师和设计师提高工作效率,实现更复杂的自动化任务。如您有SOLIDWORKS二次开发需求,欢迎咨询Solidkits
    的头像 发表于 12-13 16:33 ?1165次阅读

    可以改TSW1405内部程序或者是修改HSDC PRO的程序做二次开发吗?

    可以改TSW1405内部程序或者是修改HSDC PRO 的程序做二次开发吗?
    发表于 11-27 07:29

    什么~FPGA可以自行二次开发了?

    什么!FPGA可以自行二次开发了? 目前市场上的标准采集卡通常不支持用户自行开发FPGA。但因为应用环境的需要,不仅仅只需要单一的数据采集流程,往往还需要在其中嵌入更复杂的运行和分析逻辑。为了解
    的头像 发表于 10-14 15:47 ?686次阅读
    什么~FPGA可以自行<b class='flag-5'>二次开发</b>了?