安信可离线语音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 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添加对当前编译文件的引用。
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的完整度非常高, 代码也非常规范!相信通过这几篇文章你能很快上手安信可的离线语音产品,下期再见~
审核编辑 黄宇
-
PWM
+关注
关注
116文章
5698浏览量
220657 -
安信可
+关注
关注
0文章
201浏览量
4605
发布评论请先 登录
安信可离线语音开发板:二次开发语音控制LED灯

DLP6500想调用API进行自主二次开发,怎么构建开发环境?
怎么配置dlp6500二次开发的环境,可以使用VS2013吗?
【安信可LoRa答疑】Ra-01、Ra-02常见问题
SOLIDWORKS二次开发参数化设计工具? 慧德敏学
SOLIDWORKS二次开发应用范围与实例
什么~FPGA可以自行二次开发了?

评论