基于STM32F1系列和LDV5语音模块的语音控制LCD屏幕的点亮
Posted 岩草psq
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于STM32F1系列和LDV5语音模块的语音控制LCD屏幕的点亮相关的知识,希望对你有一定的参考价值。
本文章是基于野火指南者F103板载LCD屏的控制,如有不妥之处,欢迎指正交流!
基于STM32F1系列和LDV5语言模块的语音控制LCD屏幕的点亮
前言
本文章先简单介绍STM32外部中断EXTI原理及初始化以及LDV5语音模块,再利用外部中断EXTI控制野火指南针F103板载RGB灯的亮灭,最后将其推广至LCD屏上,实现语音点亮LCD屏幕的预期。
一、STM32外部中断EXTI
1.什么是外部中断EXTI
a.异常(中断)类型
F103 在内核水平上搭载了一个异常响应系统, 支持为数众多的系统异常和外部中断。其中系统异常有 8 个(如果把 Reset 和 HardFault 也算上的话就是 10 个),外部中断有 60个。除了个别异常的优先级被定死外,其它异常的优先级都是可编程的。有关具体的系统异常和外部中断可在标准库文件stm32f10x.h 这个头文件查询到,在 IRQn_Type 这个结构体里面包含了 F103 系列全部的异常声明。
b.EXTI简介
EXTI(External interrupt/event controller)—外部中断/事件控制器,管理了控制器的 20个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。EXTI 可以实现对每个中断/事件线进行单独配置,可以单独配置为中断或者事件,以及触发事件的属性。
c.EXTI功能框图
2.NVIC简介
NVIC 是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。
以下为NVIC 结构体定义,来自固件库头文件:core_cm3.h
/** @addtogroup CMSIS_CM3_NVIC CMSIS CM3 NVIC
memory mapped structure for Nested Vectored Interrupt Controller (NVIC)
@{
*/
typedef struct
{
__IO uint32_t ISER[8]; /*!< Offset: 0x000 Interrupt Set Enable Register 中断使能寄存器 */
uint32_t RESERVED0[24];
__IO uint32_t ICER[8]; /*!< Offset: 0x080 Interrupt Clear Enable Register 中断清除寄存器 */
uint32_t RSERVED1[24];
__IO uint32_t ISPR[8]; /*!< Offset: 0x100 Interrupt Set Pending Register 中断使能悬起寄存器 */
uint32_t RESERVED2[24];
__IO uint32_t ICPR[8]; /*!< Offset: 0x180 Interrupt Clear Pending Register 中断清除悬起寄存器 */
uint32_t RESERVED3[24];
__IO uint32_t IABR[8]; /*!< Offset: 0x200 Interrupt Active bit Register 中断有效位寄存器 */
uint32_t RESERVED4[56];
__IO uint8_t IP[240]; /*!< Offset: 0x300 Interrupt Priority Register (8Bit wide) 中断优先级寄存器*/
uint32_t RESERVED5[644];
__O uint32_t STIR; /*!< Offset: 0xE00 Software Trigger Interrupt Register 软件触发中断寄存器 */
} NVIC_Type;
/*@}*/ /* end of group CMSIS_CM3_NVIC */
在配置中断的时候我们一般只用 ISER、ICER 和 IP 这三个寄存器,ISER 用来使能中断,ICER 用来失能中断,IP 用来设置中断优先级。
3.初始化外部中断EXTI
a.EXTI初始化结构体
typedef struct
{
uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled.
This parameter can be any combination of @ref EXTI_Lines */
EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines.
This parameter can be a value of @ref EXTIMode_TypeDef */
EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.
This parameter can be a value of @ref EXTIMode_TypeDef */
FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines.
This parameter can be set either to ENABLE or DISABLE */
}EXTI_InitTypeDef;
- EXTI_Line:EXTI 中断/事件线选择,可选 EXTI0 至 EXTI19。
- EXTI_Mode:EXTI 模式选择,可选为产生中断(EXTI_Mode_Interrupt)或者产生事件(EXTI_Mode_Event)。
- EXTI_Trigger:EXTI 边沿触发事件,可选上升沿触发(EXTI_Trigger_Rising)、下降沿触发 ( EXTI_Trigger_Falling) 或者上升沿和下降沿都触发( EXTI_Trigger_Rising_Falling)。
- EXTI_LineCmd:控制是否使能 EXTI 线,可选使能 EXTI 线(ENABLE)或禁用(DISABLE)。
b.采用宏定义的方法定义EXTI的端口
以下为bsp_exti.h文件,定义GPIO端口、端口时钟以及连接到SCL时钟线的GPIO。
#ifndef __BSP_EXTI_H
#define __BSP_EXTI_H
#include "stm32f10x.h"
#define INT_GPIO_PORT GPIOD /* GPIO端口 */
#define INT_GPIO_CLK RCC_APB2Periph_GPIOD /* GPIO端口时钟 */
#define INT_GPIO_PIN GPIO_Pin_2 /* 连接到SCL时钟线的GPIO */
void EXIT_Int_Config(void);
#endif /* __BSP_EXTI_H */
c.初始化EXTI函数
void EXIT_Int_Config(void)
{
//初始化结构体
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
//配置中断优先级
EXTI_NVIC_Config();
// 初始化GPIO
RCC_APB2PeriphClockCmd( INT_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = INT_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(INT_GPIO_PORT, &GPIO_InitStructure);
// 初始化EXTI
RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO, ENABLE);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource2);
EXTI_InitStructure.EXTI_Line = EXTI_Line2;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
d.嵌套向量中断控制器 NVIC 配置
static void EXTI_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
二、LDV5语音模块
1.简介
将语音模块用USB线连接至电脑后,会播报开机语音,模块三个按键从左向右分别是U盘按键、复位按键、触发按键。U盘按键按下后,电脑将读取语音模块中插入的TF卡中的文件,如果我们需要更改语音模块程序,则需要更给该TF卡中的特定文件内容;复位按键按下后,语音模块将进行复位;触发按键需要配合语音模块的模式来使用,可作为触发条件之一。
语音模块预留了8个I/O口,可以控制I/O口的高低电平变化(高电平为3.3V),从而实现进一步操作。同时,在语音模块右下方还有串口通信端口,可以连接单片机的串口进行通信。
注意:RXD、TXD需要交叉连线;与单片机连接时,需要共地。
2.系统内部调用文件介绍(不可删除、改名)
插入语音模块的TF卡中含有以下几个文件为系统内部调用文件,不可删除和改名。
a.主菜单文件——Fyydz.ini
(1)每一行的开头数字,为菜单文件序号。
序号 0 为“口令关键词”,即在口令模式下所喊的名字,这个名字必须要存放在序号 0 处。其他意思和普通关键词一样。
序号1-88为“普通关键词”,其中序号1-32可以控制I/O口高低电平的变化,模块上预留了 PA0-PA7 这 8 个 IO 口,用户只需要简单设置 TF 卡中的菜单文件对应的序号即可对 IO 口进行利用。每个端口具备高电平、低电平、高电平 0.5s 点动、高电平 1s 点动功能。
序号 89 为“退出关键词”,即我们可以通过这句话来让系统退回到主菜单或者退出运行。例如我们在二级菜单,可以加入 89 序号这个名字来让他跳出二级菜单回到主菜单继续待命。或者在口令模式下识别口令后,不行再操作了,就可以用这个命令来停止继续操作。 这个 89 序号的关键词可以自行定义修改,和其他普通关键词一样编写。
序号 90-99 一共 10 个序号,这写序号是进入二级菜单的序号,它的关键词可以自行定义修改,和其他普通关键词一样编写。例如识别到需要 90 这条关键词后,系统会自动进入 T90.txt 的二级菜单文本中,这是只有这个文本的关键词才能识别,原主菜单关键词已经不能识别,系统只在当前 T90.TXT 菜单文本中工作,当然我们可以说出 89 序号命令回到主菜单,或者去其他 91-99 菜单,只要说出对应序号的命令,同时注意 TF 卡中要有对应的文件存在。
(2)每一行中间为串口调试信息。
串口调试信息为15个十六进制的数组成,从左向右读取,若连续出现3个FF,则说明数据终止,则串口数据为三个连续FF前的所有数据,通过模块上的串口通信端口输出。
(3)每一行的最后为触发条件和音频响应
最后的部分为此行命令的触发条件,当唤醒语音模块后,识别到触发条件后,将执行此行命令。触发条件为拼音,如“打开屏幕”则为“da kai ping mu”,后面加上.mp3文件,为触发后的音频响应,注意,此mp3文件需要在TF卡中存在。
b.系统参数配置文件——parameter.ini
1、 波特率
波特率是针对串口通信功能的一个通信速度参数调整,参数值如下:
1------4800bps
2------9600bps
3------19200bps
4------57600bps
5------115200bps
以上不同序号代表不同波特率值,默认为 9600bps。
2、 音量
音量调整为喇叭的音量大小调整参数,具体参数如下:
参数范围:0-15 ;0:最小音量 15:最大音量
3、 麦克风灵敏度
麦克风灵敏度即识别距离、识别率的调整,正常情况下我们不做任何调整,感兴趣可以调整测试,但效果不一定能改善。具体参数如下:
参数范围:1-99
1:最低灵敏度 99:最高灵敏度
说明:灵敏度越高识别距离越远但误识别率越高,反之则反;
4、 识别模式
语音模块具备3种识别模式,分别有口令模式、普通模式、
按键模式,不同模式对应有不同的功能,参数值如下:
参数值:0----口令模式
1----普通模式
2----按键模式(结合触发按键使用)
口令模式:即每次识别时都需要喊出一级口令,如“小石头”喊出一级口令后 10s 左右无发音将自动退出。如有发音可以重新恢复计时并等待,直到让他退出或者自动到时退出。(默认用模式,有效提高抗干扰能力和实用性强)
普通模式:该模式不需要喊一级口令,直接可以喊二级口令操作,没有延时等待和退出功能。(安静的环境中使用,嘈杂容易产生误触发)
按键模式:按键模式和口令模式差不多,只在于按键模块需要按按键,而口令模式是喊一级口令,其他都一样。
5、 延时参数
延时参数即是在口令模式和按键模式中的一个延时等待功能,例如默认设置的参数为 12,那么大概延时等待时间为 10s 左右,同修改这个参数可以改变等待的时间,数值越大,等待越久。这个延时只作为一个延时时间参考,非绝对准确的时间参数。
c.系统提示音频mp3文件
sys_sound.mp3-----系统开机声音(名字不能改,内容可替换)
knock.mp3----------按键模式,按键按下提示声(同上)
exit.mp3-------------退出提示声(同上)
三、语音控制LCD屏点亮
1.连线
依据中断初始化,设置端口D,引脚2为中断触发引脚,连接语音模块PA0。
通过语音触发,使得语音模块PA0端口从低电平转化为高电平,得到上升沿电平,触发单片机中断,进入中断程序(在stm32f10x_it.c文件中),实现RGB灯的点亮或者LCD屏幕的点亮。
2.中断程序(LCD屏)
首先在LCD屏的初始化文件中,找到控制LCD屏背光的GPIO,以及控制LCD屏背光的函数,操作该函数,使得LCD屏背光首先不点亮(即不使能),再中断函数中,如果进入中断,则让LCD屏背光点亮(即使能)。
a.配置LCD背光控制管脚BK
/* 配置LCD背光控制管脚BK*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = ILI9341_BK_PIN;
GPIO_Init ( ILI9341_BK_PORT, & GPIO_InitStructure );
b.ILI9341背光LED控制函数
/**
* @brief ILI9341背光LED控制
* @param enumState :决定是否使能背光LED
* 该参数为以下值之一:
* @arg ENABLE :使能背光LED
* @arg DISABLE :禁用背光LED
* @retval 无
*/
void ILI9341_BackLed_Control ( FunctionalState enumState )
{
if ( enumState )
GPIO_ResetBits ( ILI9341_BK_PORT, ILI9341_BK_PIN );
else
GPIO_SetBits ( ILI9341_BK_PORT, ILI9341_BK_PIN );
}
c.ILI9341初始化函数(背光控制不使能)
/**
* @brief ILI9341初始化函数,如果要用到lcd,一定要调用这个函数
* @param 无
* @retval 无
*/
void ILI9341_Init ( void )
{
ILI9341_GPIO_Config ();
ILI9341_FSMC_Config ();
ILI9341_BackLed_Control ( DISABLE );
ILI9341_Rst ();
ILI9341_REG_Config ();
//设置默认扫描方向,其中 6 模式为大部分液晶例程的默认显示方向
ILI9341_GramScan(LCD_SCAN_MODE);
}
d.EXTI中断函数(使能背光)
void EXTI2_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line2) != RESET)
{
GPIO_ResetBits ( ILI9341_BK_PORT, ILI9341_BK_PIN );
}
EXTI_ClearITPendingBit(EXTI_Line2);
}
总结与改进
本方案实现了采用语音控制LCD屏的点亮,达到了人机交互的效果,整体难度不大。
方案二:可以利用语音模块的串口通信,与stm32进行串口通信,当语音模块送入一个hex数据到单片机,单片机接收串口数据后,做出相应的响应,也可以达到这个效果。
以上是关于基于STM32F1系列和LDV5语音模块的语音控制LCD屏幕的点亮的主要内容,如果未能解决你的问题,请参考以下文章