大数跨境
0
0

【离线语音】安信可VC-01/02二次开发篇: PWM输出

【离线语音】安信可VC-01/02二次开发篇: PWM输出 安信可科技
2025-08-25
0
导读:更多教程可前往安信可论坛

图片


安信可离线语音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的例程。



根据对应的 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上, 那么此时示波器的波形如下所示:



占空比缓慢变化


此时默认的出厂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 boardstatic uni_pthread_t g_pwm_thread_id = 0;static bool g_pwm_thread_running = false;// Thread function to update LED brightness levelsstatic 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 threadstatic Result _create_pwm_led_thread(void) {  if (g_pwm_thread_running) {    return E_OK;  }  thread_param param;  uni_memset(&param, 0sizeof(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, &param, _pwm_led_process, NULL)) {    return E_FAILED;  }  uni_pthread_detach(g_pwm_thread_id);  // Auto cleanup  return E_OK;}// Stop PWM threadstatic 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 commandstatic void _on_wakeup_cmd_cb(USER_EVENT_TYPE event, user_event_context_t *context) {  if (context == NULLreturn;  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 callbackstatic 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 entryint 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添加对当前编译文件的引用。


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


4、修改

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




5、编译并且烧录固件。





实验现象




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



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



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





附件



附件

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


总结




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

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

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


1.gif


微信宣传推广动态二维码(1).gif

AI-Thinker-logo-原版-转曲.png

更多信息请点击:





产品https://docs.ai-thinker.com/


教程https://blog.csdn.net/Boantong_


官网www.ai-thinker.com


社区https://bbs.ai-thinker.com


业务咨询请联系:18022036575



未命名(3) (2).gif

【声明】内容源于网络
0
0
安信可科技
全球领先的联网模组、智能家居等物联网硬件方案提供商。
内容 393
粉丝 0
安信可科技 全球领先的联网模组、智能家居等物联网硬件方案提供商。
总阅读94
粉丝0
内容393