实现语音识别系统:手把手教你使用STM32C8T6和LD3320(SPI通信版)实现语音识别

这篇具有很好参考价值的文章主要介绍了实现语音识别系统:手把手教你使用STM32C8T6和LD3320(SPI通信版)实现语音识别。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        本文实际是对LD3320(SPI通信版)的个人理解,如果单论代码和开发板的资料而言,其实当你购买LD3320的时候,卖家已然提供了很多资料。我在大学期间曾经多次使用LD3320芯片的开发板用于设计系统,我在我的毕业设计作品中也有添加这个系统功能,用于添加整个系统的趣味性。本文的初衷也是为了总结学习内容,供大家参考学习。如果我的理解有误,也希望读者可以在评论中指出,不胜感激。

附上我的工程代码:工程代码

目录

目录

附上我的工程代码:工程代码

关于LD3320的通俗理解     

那么LD3320串口版和SPI版本的有什么区别呢?

LD3320的实现原理

功能实现(demo)

1、实现功能

2、实物图

3、接线图

4、SPI协议的详细介绍和解读 

1)SPI协议的通信过程如下:

2)SPI协议的数据传输方式分为两种模式:模式0和模式3

3)SPI协议有四根线:SCLK、MOSI、MISO、SS

代码层面解析(需要修改)

1)main.c文件

2)LD3320_main.c文件及其头文件(重点)

(1)LD3320_main.c文件

(2)LDchip.h文件(不做过多解释,详细见注释)

3)关于用电器的IO口配置(led.c)


关于LD3320的通俗理解     

        使用LD3320的好处是它直接免去了你训练模型的过程,换言之,它是将已经训练好的一套语音识别系统集成到LD3320芯片上了,我们只需要会“调用”LD3320芯片即可,就像搭积木一样,它已然是个整体模块,我们甚至不需要提供多余的操作,只需要堆上去,它就已经可以使用。那么如何“调用”它,就是我们需要解决的最大难点。

        目前市面上的LD3320有两种型号:其一是SPI版的,如下图所示,这个是我们今天的主角,我们可以将其视为外围电路的一个模块(就是一块积木),需要外接一个单片机去“调用”这个模块从而实现智能语音识别。

      实现语音识别系统:手把手教你使用STM32C8T6和LD3320(SPI通信版)实现语音识别

 其二是串口版本的,如图所示。

实现语音识别系统:手把手教你使用STM32C8T6和LD3320(SPI通信版)实现语音识别

那么LD3320串口版和SPI版本的有什么区别呢?

LD3320语音识别芯片的SPI版本和串口版本的区别在于它们的通信接口不同。SPI版本是通过SPI接口进行通信,而串口版本是通过串口接口进行通信。

具体而言,SPI版本可以直接和MCU或其他支持SPI通信的设备进行连接,并通过SPI接口传输数据。而串口版本则需要通过串口与MCU进行通信,通常需要在MCU上编写一定的串口通信协议来实现与芯片的数据交换。

另外,由于通信接口不同,SPI版本和串口版本的应用场景也略有不同。SPI版本的芯片适合于对通信速度有要求、需要高速传输数据的场合,而串口版本则适合于一些通信速度要求不高、需要适应不同串口的应用场合。

通俗而言,就是SPI版本的通信速度快,且可以是视为一个正真独立的模块;而串口版的可以视为一个具有信息处理能力的51MCU。


LD3320的实现原理

LD3320语音识别芯片的实现原理主要可以分为以下几个步骤:

1. 音频采集:LD3320内置一个麦克风放大器,它可以对周围的声音进行采集,并将采集到的音频信号送入芯片内部的语音信号处理器。

2. 信号处理:LD3320内置一个语音信号处理器,它可以对音频信号进行预处理、降噪、滤波等处理,以提高识别的准确率。

3. 特征提取:经过信号处理后,LD3320将音频信号转换成数字信号,并提取出其中的语音特征。LD3320采用了一种叫做Mel频率倒谱系数(Mel-frequency cepstral coefficients, MFCC)的特征提取算法。

4. 模型匹配:LD3320内置了一些语音识别的模型,比如说中文数字、英文数字、中文拼音等。LD3320将提取出的语音特征与这些模型进行匹配,以识别出用户说的话。

5. 输出结果:一旦LD3320识别出了用户的话,它会将识别结果输出到外部的MCU或DSP芯片中,以供后续的应用程序使用。

总的来说,LD3320的实现智能语音识别的原理就是通过内置的麦克风放大器进行音频采集,经过信号处理和特征提取后,将提取出的语音特征与内置的模型进行匹配,从而实现对用户语音指令的识别和理解。LD3320语音识别芯片通过识别语音信号中的特定频率和时域特征来实现语音识别。它使用的是端点检测技术,即在语音信号的开始和结束处检测到信号的存在,并将其传递给后续处理模块进行识别。LD3320芯片可以进行多语言识别,包括中文、英文、日文、韩文等。不过需要注意的是,其语音识别的准确率可能会受到环境噪声等因素的影响。


功能实现(demo)

1、实现功能

语音控制开关卧室、客厅灯;开关风扇等功能

2、实物图

实现语音识别系统:手把手教你使用STM32C8T6和LD3320(SPI通信版)实现语音识别

3、接线图

 实现语音识别系统:手把手教你使用STM32C8T6和LD3320(SPI通信版)实现语音识别

4、SPI协议的详细介绍和解读 

SPI(Serial Peripheral Interface)是一种同步的串行通信协议,用于在微控制器或其他数字集成电路(IC)之间传输数据。它是一种全双工、点对点的通信协议,使用四根线进行通信:主机发送数据时,从机收到并返回响应数据。

SPI通信协议使用一个主机和一个或多个从机之间进行数据传输,其中一个设备是主机,其他设备是从机。主机负责协调整个通信过程,从机只有在被主机选择时才会响应。通常情况下,SPI总线上只会有一个主机,但可以同时连接多个从机,每个从机都有一个独立的从机选择信号线。

1)SPI协议的通信过程如下:

1. 主机将从机选择信号线拉低,选中要进行通信的从机。

2. 主机向从机发送一个时钟信号,时钟信号将数据的传输分为若干个时钟周期。

3. 主机通过一个数据线将数据发送给从机,并通过另一个数据线接收从机返回的数据。

4. 在时钟的最后一个周期,主机将从机选择信号线拉高,表示通信结束。

2)SPI协议的数据传输方式分为两种模式:模式0和模式3

模式0的时钟极性(CPOL)和相位(CPHA)都为0,意味着时钟线在空闲状态下为低电平,数据在上升沿进行采样。模式3的时钟极性(CPOL)和相位(CPHA)都为1,意味着时钟线在空闲状态下为高电平,数据在下降沿进行采样。

3)SPI协议有四根线:SCLK、MOSI、MISO、SS

其中,SCLK是时钟线,由主设备控制,用于同步数据传输;MOSI是主设备输出、从设备输入的数据线;MISO是从设备输出、主设备输入的数据线;SS是片选信号线,用于选择与主设备通信的从设备。通信过程中,主设备通过SCLK线向从设备发送时钟信号,同时将数据通过MOSI线发送给从设备,从设备则通过MISO线返回响应的数据。SS线控制从设备的选中与释放,可以支持多从设备的通信。

SPI协议的优点是高速、简单、成本低廉,通信线路简单,但需要额外的从机选择信号线。SPI协议被广泛应用于各种数字集成电路之间的通信,如闪存、EEPROM、数字信号处理器等。总而言之,SPI协议的传输速率快,适合于数据量小、实时性高的应用场合。


代码层面解析(需要修改)

 综上所述,我们不难看出。我们只需要学会“调用”LD3320就行,因为它就是一块“积木”,我们只需要学会使用就行,至于语音识别的难题,芯片已经帮你解决了。在“调用”芯片时需要使用到SPI协议,我们使用STM32C8T6作为控制芯片

1)main.c文件

我们这里只需要注意LD3320_main()函数,至于while中的两个函数,你不要被它唬到了,它其实就是通过定时器和中断来实现开关(客厅和卧室)灯。难点实际在LD3320_main()

int main()
{  	
	
	Systick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	USART1_Init(115200);
	//TIM3_Int_Init(5000-1,72-1);
	TIM4_Int_Init(999,72-1);

	LED_Init();

	//TIM_Cmd(TIM3,ENABLE);
	TIM_Cmd(TIM4,ENABLE);
    printf("初始化完成\r\n");
    LD3320_main();		//LD3320 主函数函数
	while(1)
	{
		TimerTreat();
		ledshow();
       
	}
}

2)LD3320_main.c文件及其头文件(重点)

(1)LD3320_main.c文件

这里主要修改:static void Board_text(uint8 Code_Val)函数,具体操作结合头文件分析即可。注意,头文件也需要修改。这个非常的简单,只需要有基本的C代码阅读能力即可修改,不做过多解释啦


#include "LDchip.h"
#include "Reg_RW.h"
#include "system.h"
#include "SysTick.h"
#include "usart.h"
#include <stdio.h>
#include "led.h"
/*************端口信息********************
 * 接线说明
 LD3320接口 	  STM32接口
 * RST              PB6
 * CS   	        PB8
 * WR/SPIS          PB9
 * P2/SDCK          PB13
 * P1/SDO           PB14
 * P0/SDI           PB15
 * IRQ              PA3
 * A0		        PB7
 * RD               PA0

*****************************************/



/************************************************************************************
//	nAsrStatus 用来在main主程序中表示程序运行的状态,不是LD3320芯片内部的状态寄存器
//	LD_ASR_NONE:		表示没有在作ASR识别
//	LD_ASR_RUNING:		表示LD3320正在作ASR识别中
//	LD_ASR_FOUNDOK:		表示一次识别流程结束后,有一个识别结果
//	LD_ASR_FOUNDZERO:	表示一次识别流程结束后,没有识别结果
//	LD_ASR_ERROR:		表示一次识别流程中LD3320芯片内部出现不正确的状态
*********************************************************************************/

uint8 nAsrStatus=0;	
void LD3320_Init(void);
uint8 RunASR(void);
void ProcessInt0(void);
void LD3320_EXTI_Cfg(void);
void LD3320_Spi_cfg(void);
void LD3320_GPIO_Cfg(void);
void LED_gpio_cfg(void);
static void Board_text(uint8 Code_Val);
extern void PrintComBit(USART_TypeDef* USARTx, uint8_t Data);
/***********************************************************
* 名    称: LD3320_main(void)
* 功    能: 主函数LD3320程序入口
* 入口参数:  
* 出口参数:
* 说    明:
* 调用方法: 
**********************************************************/ 
void  LD3320_main(void)
{
	uint8 nAsrRes=0;
	LD3320_Init();	  

	while(1)
	{
    	switch(nAsrStatus)
		{
			case LD_ASR_RUNING:
			case LD_ASR_ERROR:		
							  break;
			case LD_ASR_NONE:
								nAsrStatus=LD_ASR_RUNING;
								if (RunASR()==0)	//	启动一次ASR识别流程:ASR初始化,ASR添加关键词语,启动ASR运算
								{		
									nAsrStatus = LD_ASR_ERROR;
								}
								break;

			case LD_ASR_FOUNDOK:
								 nAsrRes = LD_GetResult( );	//识别成功自动 获取识别码,识别码在LDChip.h文件中,自行定义的数据										 									
								 PrintComBit(USART1,nAsrRes ); //串口输出识别码								
								 //Board_text(nAsrRes );//开发板测试演示部分---对识别码的进行判断做出动作 (用户亦可以添加自己的功能,例如控制IO口输出,串口数据输出等)		
								 nAsrStatus = LD_ASR_NONE;
								break;
			
			case LD_ASR_FOUNDZERO:
			default: nAsrStatus = LD_ASR_NONE;
					 break;
			}//switch	
        //开发板测试
		Board_text(nAsrRes );
	}// while
}


static void Board_text(uint8 Code_Val)
{																					 
	switch(Code_Val)  //对结果执行相关操作
	{
		case CODE_DD:	//命令“打开客厅灯”
		LED_KT=1;
        printf("打开客厅灯\r\n");
		break;
		
        case CODE_GD:		//命令“关闭客厅灯”
	    LED_KT=0;
        printf("关闭客厅灯\r\n");
        break;
        
        case CODE_QDD:		//命令“打开卧室灯”
	    //打开卧室灯
        LED_WS = 1;
        printf("打开卧室灯\r\n");
        break;
        
        case CODE_DG:		//命令“关闭卧室灯”
	    //关闭卧室灯
        LED_WS = 0;
        printf("关闭卧室灯\r\n");
		break;
        
        case CODE_LSD:		//命令“全部打开”
	    //全部打开
        LED_KT=1;
        LED_WS = 1;
        printf("全部打开\r\n");
		break;
        
        case CODE_SSD:		//命令“全部关闭”
	    //全部关闭
        LED_KT=0;  
        LED_WS = 0;
        printf("全部关闭\r\n");
        break;
        
        case CODE_DDR:		//命令“打开风扇”
	    //打开风扇
        printf("打开风扇\r\n");
        JDY_FS = 0;
		break;
        
        case CODE_RDD:		//命令“关闭风扇”
	    //关闭风扇
        JDY_FS = 1;
        printf("关闭风扇\r\n");
		break;
		default:break;
	}	
}
/***********************************************************
* 名    称:LD3320_Init(void)
* 功    能:模块驱动端口初始配置
* 入口参数:  
* 出口参数:
* 说    明:
* 调用方法: 
**********************************************************/ 
void LD3320_Init(void)
{
	LD3320_GPIO_Cfg();	
	LD3320_EXTI_Cfg();
	LD3320_Spi_cfg();	 
	LD_reset();
	
}
/***********************************************************
* 名    称:	RunASR(void)
* 功    能:	运行ASR
* 入口参数:  
* 出口参数:
* 说    明:
* 调用方法: 
**********************************************************/ 
uint8 RunASR(void)
{
	uint8 i=0;
	uint8 asrflag=0;
	for (i=0; i<5; i++)			//	防止由于硬件原因导致LD3320芯片工作不正常,所以一共尝试5次启动ASR识别流程
	{
		LD_AsrStart();			//初始化ASR
		LD3320_delay(100);
		if (LD_AsrAddFixed()==0)	//添加关键词语到LD3320芯片中
		{
			LD_reset();			//	LD3320芯片内部出现不正常,立即重启LD3320芯片
			LD3320_delay(50);			//	并从初始化开始重新ASR识别流程
			continue;
		}

		LD3320_delay(10);

		if (LD_AsrRun() == 0)
		{
			LD_reset();			//	LD3320芯片内部出现不正常,立即重启LD3320芯片
			LD3320_delay(50);			//	并从初始化开始重新ASR识别流程
			continue;
		}

		asrflag=1;
		break;					//	ASR流程启动成功,退出当前for循环。开始等待LD3320送出的中断信号
	}

	return asrflag;
}

/***********************************************************
* 名    称: void Delay_( int i)
* 功    能: 短延时
* 入口参数:  
* 出口参数:
* 说    明:
* 调用方法: 
**********************************************************/ 
void Delay_( int i)
 {     
    while( i--)
       {	

        }
 }	
/***********************************************************
* 名    称:	LD3320_delay(unsigned long uldata)
* 功    能:	长延时函数
* 入口参数:  
* 出口参数:
* 说    明:
* 调用方法: 
**********************************************************/ 
 void  LD3320_delay(unsigned long uldata)
{
	unsigned int j  =  0;
	unsigned int g  =  0;
	for (j=0;j<5;j++)
	{
		for (g=0;g<uldata;g++)
		{
			Delay_(120);
		}
	}
}


/***********************************************************
* 名    称:LD3320_GPIO_Cfg(void)
* 功    能:初始化需要用到的IO口
* 入口参数:  
* 出口参数:
* 说    明:
* 调用方法: 
**********************************************************/ 
void LD3320_GPIO_Cfg(void)
{	
	    GPIO_InitTypeDef GPIO_InitStructure;
		// 配置PA8 输出	 8M 波形	
		//定义RST/A0/CS/WR端口
	 {
	 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB ,ENABLE);
		//LD_CS	/RSET
		GPIO_InitStructure.GPIO_Pin =GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
		GPIO_Init(GPIOB,&GPIO_InitStructure);
		GPIO_SetBits(GPIOB,GPIO_Pin_7);	/*A0默认拉高*/
	 }
}
/***********************************************************
* 名    称:LD3320_Spi_cfg(void)
* 功    能:配置SPI功能和端口初始化
* 入口参数:  
* 出口参数:
* 说    明:
* 调用方法: 
**********************************************************/ 
void LD3320_Spi_cfg(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
  	SPI_InitTypeDef  SPI_InitStructure;

	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能 
	RCC_APB1PeriphClockCmd(	RCC_APB1Periph_SPI2,  ENABLE );//SPI2时钟使能 	
 
	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //PB13/14/15复用推挽输出 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	LD_CS_H();
	
 	GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);  //PB13/14/15上拉

	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;		//设置SPI工作模式:设置为主SPI
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;		//设置SPI的数据大小:SPI发送接收8位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;		//选择了串行时钟的稳态:时钟悬空高
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;	//数据捕获于第二个时钟沿
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;		//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;		//定义波特率预分频的值:波特率预分频值为16
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
	SPI_InitStructure.SPI_CRCPolynomial = 7;	//CRC值计算的多项式
	SPI_Init(SPI2, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
 
	SPI_Cmd(SPI2, ENABLE); //使能SPI外设
}
/***********************************************************
* 名    称: LD3320_EXTI_Cfg(void) 
* 功    能: 外部中断功能配置和相关端口配置
* 入口参数:  
* 出口参数:
* 说    明:
* 调用方法: 
**********************************************************/ 
void LD3320_EXTI_Cfg(void)
{
  EXTI_InitTypeDef EXTI_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  //定义IRQ中断引脚配置
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  GPIO_InitStructure.GPIO_Pin =GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
	//外部中断线配置
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);
  EXTI_InitStructure.EXTI_Line = EXTI_Line3;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger =EXTI_Trigger_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
  EXTI_GenerateSWInterrupt(EXTI_Line3);
		
	GPIO_SetBits(GPIOA,GPIO_Pin_3);	 //默认拉高中断引脚

	EXTI_ClearFlag(EXTI_Line3);
	EXTI_ClearITPendingBit(EXTI_Line3);
	//中断嵌套配置
  NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}


/***********************************************************
* 名    称:  EXTI1_IRQHandler(void)
* 功    能: 外部中断函数
* 入口参数:  
* 出口参数:
* 说    明:
* 调用方法: 
**********************************************************/ 
void EXTI3_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line3)!= RESET ) 
	{
 		ProcessInt0();
		EXTI_ClearFlag(EXTI_Line3);
		EXTI_ClearITPendingBit(EXTI_Line3);
	}
}

(2)LDchip.h文件(不做过多解释,详细见注释)

#ifndef LD_CHIP_H
#define LD_CHIP_H

#define uint8 unsigned char
#define uint16 unsigned int
#define uint32 unsigned long

//	以下三个状态定义用来记录程序是在运行ASR识别还是在运行MP3播放
#define LD_MODE_IDLE		0x00
#define LD_MODE_ASR_RUN		0x08
#define LD_MODE_MP3		 	0x40


//	以下五个状态定义用来记录程序是在运行ASR识别过程中的哪个状态
#define LD_ASR_NONE				0x00	//	表示没有在作ASR识别
#define LD_ASR_RUNING			0x01	//	表示LD3320正在作ASR识别中
#define LD_ASR_FOUNDOK			0x10	//	表示一次识别流程结束后,有一个识别结果
#define LD_ASR_FOUNDZERO 		0x11	//	表示一次识别流程结束后,没有识别结果
#define LD_ASR_ERROR	 		0x31	//	表示一次识别流程中LD3320芯片内部出现不正确的状态


#define CLK_IN   	22	/* user need modify this value according to clock in */
#define LD_PLL_11			(uint8)((CLK_IN/2.0)-1)
#define LD_PLL_MP3_19		0x0f
#define LD_PLL_MP3_1B		0x18
#define LD_PLL_MP3_1D   	(uint8)(((90.0*((LD_PLL_11)+1))/(CLK_IN))-1)

#define LD_PLL_ASR_19 		(uint8)(CLK_IN*32.0/(LD_PLL_11+1) - 0.51)
#define LD_PLL_ASR_1B 		0x48
#define LD_PLL_ASR_1D 		0x1f

// LD chip fixed values.
#define        RESUM_OF_MUSIC               0x01
#define        CAUSE_MP3_SONG_END           0x20

#define        MASK_INT_SYNC				0x10
#define        MASK_INT_FIFO				0x04
#define    	   MASK_AFIFO_INT				0x01
#define        MASK_FIFO_STATUS_AFULL		0x08



void LD_reset(void);
uint8 RunASR(void);

void LD_Init_Common(void);

void LD_Init_ASR(void);

void LD_ReloadMp3Data(void);
void LD_ReloadMp3Data_2(void);

uint8 LD_ProcessAsr(uint32 RecogAddr);
void LD_AsrStart(void);
uint8 LD_AsrRun(void);
uint8 LD_AsrAddFixed(void);
uint8 LD_GetResult(void);

void LD_ReadMemoryBlock(uint8 dev, uint8 * ptr, uint32 addr, uint8 count);
void LD_WriteMemoryBlock(uint8 dev, uint8 * ptr, uint32 addr, uint8 count);

extern uint8  nLD_Mode;


	//以下为识别码的宏定义无特别意义,0-ff可自行修改值,不分顺序不要重复。
#define CODE_DD       0X01	  /*打开客厅灯*/
#define CODE_GD	  	  0X02	  /*关闭客厅灯*/
#define CODE_QDD 	  0X03    /*打开卧室灯*/
#define CODE_DG		  0X04	  /*关闭卧室灯*/
#define CODE_LSD	  0X05	  /*全部打开*/
#define CODE_SSD	  0X06	  /*全部关闭*/
#define CODE_DDR	  0X07	  /*打开继电器*/
#define CODE_RDD	  0X08	  /*继电器点动*/

//#define CODE_PLAY	  0X09	  /*播放歌曲*/
//#define CODE_NAME	  0X0A    /*你叫什么名字*/
//#define CODE_DO		  0X0B    /*你会做什么*/


void  LD3320_delay(unsigned long uldata);

#define MIC_VOL 0x43    //麦克风灵敏度条件,值越大越灵敏也容易误识别

#endif

3)关于用电器的IO口配置(led.c)

这里的代码的是对用电器引脚口的一个配置

#include "led.h"
#include "timer.h"
 void LED_Init()
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	    
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_0|GPIO_Pin_1;			   
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 	 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	 //IO口速度为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure);
    
    LED_KT = 0;
    LED_WS = 0;//灯光初始为关闭状态
    JDY_FS = 1;
}


void ledshow(void)
{
	if(g_stTimerTickFlag.bTimer500ms == 1)
	{
		LED_KT = !LED_KT;
        LED_WS = !LED_WS;
	}
}

        代码是不是也非常简单,它就是一个搭积木的过程。总而言之很有趣的一个小系统,用于智能家居等一些场景也是十分不错的。但是目前而言,LD3320语音识别的板子对杂音的过滤十分有限,大概只能做到1m-1.5m的有效识别吧,具体的没测过。感兴趣的同学可以试试哈哈哈哈哈哈哈

哦,对了,需要说明一下,本代码只供学习哦,这代码本身也是我通过商家代码改的。如果想跟我一样,给自己的毕设或者系统添加一点小功能和一些趣味性,代码自取哈!文章来源地址https://www.toymoban.com/news/detail-457164.html

到了这里,关于实现语音识别系统:手把手教你使用STM32C8T6和LD3320(SPI通信版)实现语音识别的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 手把手教你基于【SpringBoot+MyBatis】实现员工管理系统‍【附完整源码】

    Hello,你好呀,我是 灰小猿 ,一个超会写 BUG 的程序猿🙊! 近期在学习springboot框架相关的内容,相比于SSM, SpringBoot最大的特点就是集成了Spring和SpringMVC,让之前繁琐的配置工作变得更加简洁, 同时对于业务逻辑层的处理也更加的友好, 所以今天就使用 SpringBoot整合MyBati

    2023年04月08日
    浏览(44)
  • 手把手教你实现一个JavaWeb项目:创建一个自己的网页博客系统(前端+后端)(一)

    一篇博客带你实现一个真正的项目!  先来看看它是什么样式的: 目录: 1、大体步骤🦖:         1、创建Maven项目🦕         2、引入依赖🦕         3、创建必要的目录🦕         4、编写代码🦕         5、打包部署(基于SmartTomcat)🦕         

    2024年02月06日
    浏览(55)
  • 手把手教你在Linux/Windows系统使用Nginx部署多个前端项目【详细操作】

            需求:项目上线需要将前端的前台和后台部署在服务器上提供用户进行使用,部署在不同的服务器直接在服务器安装nginx即可。但是在内网安装还是有点麻烦,因为需要联网,如果是内网可以参考Linux安装Nginx并部署前端项目【内/外网-保姆级教程】_MXin5的博客-CSDN博

    2024年02月14日
    浏览(58)
  • 【运维】手把手教你在Linux/Windows系统使用Nginx部署多个前端项目【详细操作】

            需求:项目上线需要将前端的前台和后台部署在服务器上提供用户进行使用,部署在不同的服务器直接在服务器安装nginx即可。但是在内网安装还是有点麻烦,因为需要联网,如果是内网可以参考Linux安装Nginx并部署前端项目【内/外网-保姆级教程】_MXin5的博客-CSDN博

    2024年02月08日
    浏览(58)
  • 手把手教你使用Python实现推箱子小游戏(附完整源码)

    我们这个项目是一个基于Python实现的推箱子小游戏,名叫Sokoban: 这个游戏的目的是让玩家,也就是大写的 P ,推着箱子 # ,填充用小写的 o 标记的地面上的洞 该版本的Sokoban的规则如下: 游戏在矩形的二维网格上举行,其 原点(0,0) 位于左上方 网格上的每个单元格可以随时包

    2024年02月03日
    浏览(50)
  • 快速上手WebGL,代码+图解手把手教你使用WebGL一步步实现热力图

    大家好,我是南木元元,热衷分享有趣实用的文章。 项目中需要绘制热力图,热力图其实就是数值大小用颜色来进行区分,每个点的数值需根据颜色映射表(调色板)映射为指定颜色。需要3个数值字段,可绘制在平行坐标系中(2个数值字段分别确定x、y轴,1个数值字段确定

    2024年01月18日
    浏览(54)
  • 【YOLOv8】实战一:手把手教你使用YOLOv8实现实时目标检测

    ‍‍🏡博客主页: virobotics的CSDN博客:LabVIEW深度学习、人工智能博主 🎄所属专栏:『LabVIEW深度学习实战』 🍻上期文章: LabVIEW+OpenCV快速搭建人脸识别系统(附源码)) 📰如觉得博主文章写的不错或对你有所帮助的话,还望大家多多支持呀! 欢迎大家✌关注、👍点赞、✌收

    2024年02月02日
    浏览(47)
  • 手把手教你用UNet做医学图像分割系统

    兄弟们好呀,这里是肆十二,这转眼间寒假就要过完了,相信大家的毕设也要准备动手了吧,作为一名大作业区的UP主,也该蹭波热度了,之前关于图像分类和目标检测我们都出了相应的教程,所以这期内容我们搞波新的,我们用Unet来做医学图像分割。我们将会以皮肤病的数

    2024年02月03日
    浏览(74)
  • 手把手教你实现SpringBoot的监控!

    任何一个服务如果没有监控,那就是两眼一抹黑,无法知道当前服务的运行情况,也就无法对可能出现的异常状况进行很好的处理,所以对任意一个服务来说,监控都是必不可少的。 就目前而言,大部分微服务应用都是基于 SpringBoot 来构建,所以了解 SpringBoot 的监控特性是非

    2024年02月11日
    浏览(49)
  • 手把手教你如何使用Docker

    我们在公司开发中,会有开发环境,测试环境,上线环境, 比如我们开发人员开发好了一个项目,在开发环境中运行正常,但测试人员拉到测试环境就跑不起来【jdk版本等】,或者上线的时候运行不起来,这时候就要为每个机器配置一个环境,那运维人员不得累死?【哈哈,

    2024年02月10日
    浏览(68)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包