简介
买了HI-LINK-V20型号的离线语音识别模块, 为了后面可以做有意思的东西, 现在先来用用, 使用USART2 串口 接收来自我在HI-LINK-V20中预设的动作, 当识别到词条时发送对应的指令到串口, HI-LINK串口接的就是STM32F03ZET6的USART2, 且往下看。
电路原理图
连线图
连线引脚表
板 | ||||
---|---|---|---|---|
STM32F103ZET6 | RX(PA3) | TX(PA2) | 3.3V | GND |
HI-LINK-V20 | TX | RX | VCC | GND |
实物图
其他知识
更新离线词条
海凌科HLK-V2语音识别模块更新词条
协议
协议帧如上图,
头部 三字节
指令 两字节
地址 四字节
值 四字节
尾部 两字节
控灯指令 0x0A、灯的编址1~8\0xFF(全部灯), 灯的状态是值0/1/0xFF(全部灯打开)
控制灯1打开, 指令是: AA BB CC 00 0A 00 00 00 01 00 00 00 01 0A 0D
控制全部灯打开是 : AA BB CC 00 0A 00 00 00 FF 00 00 00 FF 0A 0D
实现步骤
创建项目
参考 普中STM32-PZ6806L开发板(HAL库函数实现-USART2 中断接收)
添加用户代码
hlk_v20.h
#ifndef __HLK_V20_H__
#define __HLK_V20_H__#include "stm32f1xx_hal.h"#define HLK_V20_COMMAND_VERSION 0x01uint8_t HLK_V20_PreActionCheck(uint8_t *dat, uint32_t len);
void HLK_V20_ActionCallback(uint16_t cmd, uint32_t addr, uint32_t value); // 检测到完整指令, 将调用此函数#endif //__HLK_V20_H__
hlk_v20.c
#include "hlk_v20.h"#if HLK_V20_COMMAND_VERSION == 0x01
#define HLK_V20_COMMAND_LENGTH 15#endif__weak void HLK_V20_ActionCallback(uint16_t cmd, uint32_t addr, uint32_t value)
{}/* * HLK_V20_PreActionCheck: 指令预处理1. 检查指令是否完整;2. 解析完完整指令则调用HLK_V20_ActionCallback执行指令dat : buflen : buf有效数据长度return 0 : 命令不完整1 : 命令完整并执行
*/
uint8_t HLK_V20_PreActionCheck(uint8_t *dat, uint32_t len)
{if (HLK_V20_COMMAND_LENGTH > len) // 数据长度要达到指令数据长度return 0;uint16_t cmd = 0;uint32_t addr = 0;uint32_t value = 0;#if HLK_V20_COMMAND_VERSION == 0x01/*Frame:Head : 0xAA 0xBB 0xCC -> 3字节, 第1~3字节CMD : 16bit -> 2 字节, 第4~5字节ADDR : 32bit -> 4字节, 第6~9字节Value: 32bit -> 4字节, 第10~13字节Tail : 0x0A 0x0D-> 2字节, 第14~15字节*/if ( !(0xAA == dat[0] && 0xBB == dat[1] && 0xCC == dat[2] && 0x0A == dat[13] && 0x0D == dat[14]) ){return 0;}cmd = (dat[3]<<8)|dat[4];addr = (dat[5]<<24) | (dat[6]<<16) | (dat[7]<<8) | dat[8];value = (dat[9]<<24) | (dat[10]<<16) | (dat[11]<<8) | dat[12];#endifHLK_V20_ActionCallback(cmd, addr, value);return 1;
}
绑定指令与相关功能
hlk_v20_demo.h
#ifndef __HLK_V20_DEMO_H__
#define __HLK_V20_DEMO_H__#include "usart.h"#define HLK_V20_DEMO_USART huart2void HLK_V20_DEMO_Usart_RxCallback(UART_HandleTypeDef *huart);
void HLK_V20_DEMO_Action_Init(void);#endif // __HLK_V20_DEMO_H__
hlk_v20_demo.c
#include "hlk_v20_demo.h"
#include "hlk_v20.h"
#include "LED/led.h"
#include "BEEP/beep.h"#include <string.h>
#include <stdio.h>static uint8_t gCmdBuffer[1024];
static uint16_t gCmdIndex = 0;static void HLK_V20_Command_Reset(void)
{memset(gCmdBuffer, 0, sizeof(gCmdBuffer)/sizeof(uint8_t));gCmdIndex = 0;
}void HLK_V20_ActionCallback(uint16_t cmd, uint32_t addr, uint32_t value)
{switch (cmd){case 0x0A: {if (addr == 0xff){LED_LightControl(LED_ALL, (LED_Status)(0xFF==value?1:0));printf ("LED_ALL %s!\r\n", value ? "ON":"OFF");}else{LED_LightControl((LED_Number)(addr-1), (LED_Status)value);printf ("LED_%d %s\r\n", addr, value ? "ON":"OFF");}}break;case 0x0B:BEEP_5KHzAction(5000);break;default:break;}
}/*
HLK_V20_DEMO_Usart_RxCallback : 在Usart Ex中断回调函数中调用此函数即可*/
void HLK_V20_DEMO_Usart_RxCallback(UART_HandleTypeDef *huart)
{if (HLK_V20_DEMO_USART.Instance == huart->Instance){if ( !HLK_V20_PreActionCheck(gCmdBuffer, gCmdIndex+1) ){++gCmdIndex;}else{HLK_V20_Command_Reset();}HAL_UART_Receive_IT(&huart2, &gCmdBuffer[gCmdIndex], 1); // USART继续中断接收}
}/*使用此功能前先调用一次, 开始接收任务
*/
void HLK_V20_DEMO_Action_Init(void)
{HLK_V20_Command_Reset();HAL_UART_Receive_IT(&HLK_V20_DEMO_USART, &gCmdBuffer[gCmdIndex], 1); // USART开始中断接收
}
启用功能
main.c
/*串口接收中断函数回调
*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{HLK_V20_DEMO_Usart_RxCallback(huart); // 加入HLK_V20数据处理
}int main()
{....HLK_V20_DEMO_Action_Init();...while(1){HAL_Delay(1000); // 延时获得空闲资源}...
}
共赏
普中STM32-PZ6806L开发板(USART2 串口 + HI-LINK-V20离线语音模块控制LED灯)
代码
不需要下载, 基本代码上面都提供了
参考
普中STM32-PZ6806L开发板(HAL库函数实现-批量操作GPIO引脚实现跑马灯)
海凌科HLK-V2语音识别模块更新词条
普中STM32-PZ6806L开发板(HAL库函数实现-USART2 中断接收)