本帖最后由 cc1989summer 于 2024-11-9 22:39 编辑
语音识别、人工智能是目前的大热门。
咱们的STM32H7S78-DK是自带有数字麦克风的,也就是U1:MP23DB01
然而要想实现STM32语音识别,涉及到人工智能CNN,我目前还没摸索会。
网上有相关的内容参考:
https://github.com/gk969/stm32-speech-recognition
这里就基于离线语音识别模块:ASR-PRO
模块介绍:本模块是针对低成本离线语音应用方案开发的一款通用、便携、低功耗高性能的语音识 别模组,采用最新的 ASRPRO 芯片,内置神经网络处理器,能支持 DNN\TDNN\RNN 等神 经网络及卷积运算,支持语音识别、声纹识别、语音增强、语音检测等功能,具备强劲的回 声消除和环境噪声抑制能力,语音识别效果优于其它语音芯片。该芯片方案还支持汉语、英 语、日语等多种全球语言,可广泛应用于家电、照明、玩具、可穿戴设备、工业、汽车等产 品领域,搭配天问 Block 图形化编程软件,快速实现语音交互及控制和各类智能语音方案应 用。
大概模式是这样:
使用模块配套的软件:可以自定义语音模型,并下载到芯片中,实现离线语音识别:
下图是我预先定义好的唤醒语句,以及控制语句,生成模型并下载后,就可以开启STM32语音控制之旅了。
STM32H7S78-DK需要设置的主要是串口(UART7,PE8/PE7)以及GPIO。
关于串口(UART7,PE8/PE7),需要注意的是,开发板没有引出,整块开发板只有虚拟串口(UART4)可用。
需要对电路加以改动,详见我的前述帖子:
https://bbs.eeworld.com.cn/thread-1295392-1-1.html
记得一定要开启串口中断。
以下是main.c函数,
记得此语句开启串口接收中断:
HAL_UART_Receive_IT(&huart7, UART_BUF,sizeof(UART_BUF));
int main(void)
{
MPU_Config();
/* USER CODE BEGIN 1 */
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Update SystemCoreClock variable according to RCC registers values. */
SystemCoreClockUpdate();
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_UART7_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart7, UART_BUF,sizeof(UART_BUF));
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
在串口中断语句中,加入控制语句:
此句是把语音识别模块发给MCU的指令,由MCU发给电脑端,做串口监听。
HAL_UART_Transmit(&huart7, UART_BUF,sizeof(UART_BUF),1000);
此句是处理完串口接收中断,再次进入串口中断。
HAL_UART_Receive_IT(&huart7, UART_BUF,sizeof(UART_BUF));
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
HAL_UART_Transmit(&huart7, UART_BUF,sizeof(UART_BUF),1000);
if(UART_BUF[0] == 0x01)
{HAL_GPIO_WritePin(LD1_GPIO_PORT, LD1_Pin,SET);}
if(UART_BUF[0] == 0x02)
{HAL_GPIO_WritePin(LD2_GPIO_PORT, LD2_Pin,SET);}
if(UART_BUF[0] == 0x03)
{HAL_GPIO_WritePin(LD3_GPIO_PORT, LD3_Pin,RESET);}
if(UART_BUF[0] == 0x04)
{HAL_GPIO_WritePin(LD4_GPIO_PORT, LD4_Pin,RESET);}
if(UART_BUF[0] == 0x05)
{HAL_GPIO_WritePin(LD1_GPIO_PORT, LD1_Pin,RESET);}
if(UART_BUF[0] == 0x06)
{HAL_GPIO_WritePin(LD2_GPIO_PORT, LD2_Pin,RESET);}
if(UART_BUF[0] == 0x07)
{HAL_GPIO_WritePin(LD3_GPIO_PORT, LD3_Pin,SET);}
if(UART_BUF[0] == 0x08)
{HAL_GPIO_WritePin(LD4_GPIO_PORT, LD4_Pin,SET);}
if(UART_BUF[0] == 0x09)
{
HAL_GPIO_WritePin(LD1_GPIO_PORT, LD1_Pin,SET);
HAL_GPIO_WritePin(LD2_GPIO_PORT, LD2_Pin,SET);
HAL_GPIO_WritePin(LD3_GPIO_PORT, LD3_Pin,RESET);
HAL_GPIO_WritePin(LD4_GPIO_PORT, LD4_Pin,RESET);
}
if(UART_BUF[0] == 0x10)
{
HAL_GPIO_WritePin(LD1_GPIO_PORT, LD1_Pin,RESET);
HAL_GPIO_WritePin(LD2_GPIO_PORT, LD2_Pin,RESET);
HAL_GPIO_WritePin(LD3_GPIO_PORT, LD3_Pin,SET);
HAL_GPIO_WritePin(LD4_GPIO_PORT, LD4_Pin,SET);
}
HAL_UART_Receive_IT(&huart7, UART_BUF,sizeof(UART_BUF));
}
运行效果:
语音控制
再增加点花样,对于显示屏的颜色给与控制。增加以下指令:
程序代码,参考BSP中的LCD显示:
int main(void)
{
/* MPU Configuration--------------------------------------------------------*/
MPU_Config();
/* Enable the CPU Cache */
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
// SCB_EnableDCache();
/* STM32H7RSxx HAL library initialization:
- Systick timer is configured by default as source of time base, but user
can eventually implement his proper time base source (a general purpose
timer for example or other time source), keeping in mind that Time base
duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
handled in milliseconds basis.
- Set NVIC Group Priority to 4
- Low Level Initialization
*/
HAL_Init();
/* Configure the system clock to 400 MHz */
SystemClock_Config();
/* Initialize leds */
BSP_LED_Init(LED_GREEN);
BSP_LED_Init(LED_RED);
/* Configure the User push-button in EXTI Mode */
BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
MX_UART7_Init();
HAL_UART_Transmit(&huart7, UART_BUF9, sizeof(UART_BUF9),100);
HAL_UART_Receive_IT(&huart7, UART_BUF,sizeof(UART_BUF));
/* Init LCD */
BSP_LCD_Init(0, LCD_ORIENTATION_LANDSCAPE);
BSP_LCD_GetBrightness(0, &Brightness);
BSP_LCD_SetBrightness(0, 40);
BSP_LCD_GetBrightness(0, &Brightness);
UTIL_LCD_SetFuncDriver(&LCD_Driver);
//BSP_LCD_Reload(0, BSP_LCD_RELOAD_VERTICAL_BLANKING);
//Display_DemoDescription();
UTIL_LCD_FillRect(0, 0, 800, 480, UTIL_LCD_COLOR_GREEN);
//AudioPlay_demo();
//BSP_examples[4].DemoFunc();
while (1)
{
}
}
串口中断部分,解析语音指令显示代码:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
HAL_UART_Transmit(&huart7, UART_BUF,sizeof(UART_BUF),1000);
if(UART_BUF[0] == 0x11)
{
/* Display LCD messages */
UTIL_LCD_FillRect(0, 0, 800, 480, UTIL_LCD_COLOR_RED);
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_MAGENTA);
UTIL_LCD_SetFont(&Font24);
UTIL_LCD_DisplayStringAt(0, 200, (uint8_t *)"AUDIO PLAYER by cc1989summer", CENTER_MODE);
}
if(UART_BUF[0] == 0x12)
{
/* Display LCD messages */
UTIL_LCD_FillRect(0, 0, 800, 480, UTIL_LCD_COLOR_GREEN);
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLUE);
UTIL_LCD_SetFont(&Font24);
UTIL_LCD_DisplayStringAt(0, 200, (uint8_t *)"AUDIO PLAYER by cc1989summer", CENTER_MODE);
}
if(UART_BUF[0] == 0x13)
{
/* Display LCD messages */
UTIL_LCD_FillRect(0, 0, 800, 480, UTIL_LCD_COLOR_BLUE);
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLUE);
UTIL_LCD_SetFont(&Font24);
UTIL_LCD_DisplayStringAt(0, 200, (uint8_t *)"AUDIO PLAYER by cc1989summer", CENTER_MODE);
}
if(UART_BUF[0] == 0x14)
{
/* Display LCD messages */
UTIL_LCD_FillRect(0, 0, 800, 480, UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLUE);
UTIL_LCD_SetFont(&Font24);
UTIL_LCD_DisplayStringAt(0, 200, (uint8_t *)"AUDIO PLAYER by cc1989summer", CENTER_MODE);
}
if(UART_BUF[0] == 0x15)
{
/* Display LCD messages */
UTIL_LCD_FillRect(0, 0, 800, 480, UTIL_LCD_COLOR_MAGENTA);
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLUE);
UTIL_LCD_SetFont(&Font24);
UTIL_LCD_DisplayStringAt(0, 200, (uint8_t *)"AUDIO PLAYER by cc1989summer", CENTER_MODE);
}
if(UART_BUF[0] == 0x16)
{
/* Display LCD messages */
UTIL_LCD_FillRect(0, 0, 800, 480, UTIL_LCD_COLOR_BLACK);
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLUE);
UTIL_LCD_SetFont(&Font24);
UTIL_LCD_DisplayStringAt(0, 200, (uint8_t *)"AUDIO PLAYER by cc1989summer", CENTER_MODE);
}
if(UART_BUF[0] == 0x17)
{
/* Display LCD messages */
UTIL_LCD_FillRect(0, 0, 800, 480, UTIL_LCD_COLOR_ORANGE);
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLUE);
UTIL_LCD_SetFont(&Font24);
UTIL_LCD_DisplayStringAt(0, 200, (uint8_t *)"AUDIO PLAYER by cc1989summer", CENTER_MODE);
}
HAL_UART_Receive_IT(&huart7, UART_BUF,sizeof(UART_BUF));
}
运行效果;
语音切换颜色
最后,结合此前的练习:
【STM32H7S78-DK】⑦连接WIFI获取时间(基于ESP8266)
https://bbs.eeworld.com.cn/thread-1295392-1-1.html
加入语音唤醒WIFI时间指令,思路跟上述一样。
在对应的串口中断中加入获取时间的指令。
语音唤醒时间
至此,全部的【STM32H7S78-DK】体验及分享就到这里了。
总计11篇贴文,付出很多时间精力,也收获很多知识和经验,不仅对对STSTM32H7S78开发掌握更深,对ST的各类软件操作也更加熟练。
当然,由于时间关系,很多高端、丰富的功能还没时间体验,转眼就到交作业的截止时间了。
包括 MXCHIP的SPI WIFI模块、数字麦克风、摄像头(坛友有首发)、以太网、DMA、TouchGFX、Free-RTOS、NanoEdge™ AI Studio等等。
有些浅尝辄止,有些还未开始体验,待后续有时间,一定深入学习,进一步发掘和体验STM32H7S78-DK的宝藏功能。
我目前接下来的目标是:做一个基于互联网的网络收音机,结合TouchGFX的丰富界面,功能一定很酷炫。
还有就是视频播放器、将存在SD卡上的视频,比如mp4格式,解码并播放出来。
再有就是目前流行的人工智能,比如基于TouchGFX的手写识别,直接在触摸屏上一边手写,一边自动识别。
想法很多,接下来逐步实践吧,所谓学无止境就是这样吧。
最后,非常感谢EEWORLD和ST给我的这次机会,我很珍惜也很努力,希望EEWORLD越办越好,给我们电子从业人员和电子爱好者提供更多的学习成长机会,也祝愿ST越来越强大!