使用LD3320模块,实现用户说一句话,比如说一句"小车左转",小车就会进行左转,到后面会加SD卡模块,实现语音交互等功能.

LD3320是非特定人(不用针对指定人)语音识别芯片,即语音声控芯片。最多可以识别50条预先内置的指令。

工作模式:

LD3320(LDV7)语音模块可以工作在以下三种模式:
普通模式:直接说话,模块直接识别;
按键模式:按键触发开始ASR进程;
口令模式:需要一级唤醒词(口令);


推荐使用口令模式,这样避免嘈杂环境下误动作。

小车与STMF103接线图:


                    A轮  \\   ------   //  B轮 TIM2
                             \\   ------  //
                                  ------
                               //  ------ \\
                    D轮  //   ------   \\  C轮 TIM3
                

           控制ABCD四个轮子的PWM
            PC6--A轮 //左前 ---- 电机驱动1-ENA
            PC7--B轮 //右前 ---- 电机驱动1-ENB
            PC8--C轮 //右后 ---- 电机驱动2-ENA
            PC9--D轮 //左后 ---- 电机驱动2-ENB
        
            A轮:PC1 PC0 控制前后运动   PC1----IN2,PC0----IN1
            B轮:PC3 PC2 控制前后运动     PC3----IN4,PC2----IN3            
            C轮:PC10,PC11控制前后运动 PC10 --- IN1,PC11---IN2
            D轮:PC12,PD2控制前后运动  PC12 --- IN3,PD2 ---IN4

LD332模块与单片机接线图:

LD3320 5v-----单片机的电源5v,GND----GND;

LD3320 RST----PB15

LD3320  CS---PB13

LD3320 IRQ---PB12

LD3320 CS---PA4

LD3320  SCK---PA5

LD3320  MISO----PA6

LD3320   MOSI---PA7

主要代码如下:

测试的时候可以串口助手进行调试.

LD3320_config.h

#ifndef _LD3320_CONFIG_H__
#define _LD3320_CONFIG_H__

///识别码
#define CODE_XCQJ	1	 //小车前进
#define CODE_XCHT	2	 //小车后退
#define CODE_XCYZ	3	 //小车右转
#define CODE_XCZZ 4	 //小车左转
#define CODE_XCTZ	5  //小车停止

///小车引脚相关定义
#define M1_PIN							GPIO_Pin_0
#define M1_GPIO_PORT				GPIOC
#define M1_GPIO_CLK					RCC_APB2Periph_GPIOC

#define M2_PIN							GPIO_Pin_1
#define M2_GPIO_PORT				GPIOC
#define M2_GPIO_CLK					RCC_APB2Periph_GPIOC

#define M3_PIN							GPIO_Pin_2
#define M3_GPIO_PORT				GPIOC
#define M3_GPIO_CLK					RCC_APB2Periph_GPIOC

#define M4_PIN							GPIO_Pin_2
#define M4_GPIO_PORT				GPIOC
#define M4_GPIO_CLK					RCC_APB2Periph_GPIOC

#define M5_PIN							GPIO_Pin_10
#define M5_GPIO_PORT				GPIOC
#define M5_GPIO_CLK					RCC_APB2Periph_GPIOC

#define M6_PIN							GPIO_Pin_11
#define M6_GPIO_PORT				GPIOC
#define M6_GPIO_CLK					RCC_APB2Periph_GPIOC

#define M7_PIN							GPIO_Pin_12
#define M7_GPIO_PORT				GPIOC
#define M7_GPIO_CLK					RCC_APB2Periph_GPIOC

#define M8_PIN							GPIO_Pin_2
#define M8_GPIO_PORT				GPIOD
#define M8_GPIO_CLK					RCC_APB2Periph_GPIOD

#define E1_PIN							GPIO_Pin_6
#define E1_GPIO_PORT				GPIOC
#define E1_GPIO_CLK					RCC_APB2Periph_GPIOC

#define E2_PIN							GPIO_Pin_7
#define E2_GPIO_PORT				GPIOC
#define E2_GPIO_CLK					RCC_APB2Periph_GPIOC

#define E3_PIN							GPIO_Pin_8
#define E3_GPIO_PORT				GPIOC
#define E3_GPIO_CLK					RCC_APB2Periph_GPIOC

#define E4_PIN							GPIO_Pin_9
#define E4_GPIO_PORT				GPIOC
#define E4_GPIO_CLK					RCC_APB2Periph_GPIOC


#define M1_ON()								GPIO_SetBits(GPIOC,GPIO_Pin_0)
#define M2_ON()								GPIO_SetBits(GPIOC,GPIO_Pin_1)
#define M3_ON()								GPIO_SetBits(GPIOC,GPIO_Pin_2)
#define M4_ON()								GPIO_SetBits(GPIOC,GPIO_Pin_2)
#define M5_ON()								GPIO_SetBits(GPIOC,GPIO_Pin_10)
#define M6_ON()								GPIO_SetBits(GPIOC,GPIO_Pin_11)
#define M7_ON()								GPIO_SetBits(GPIOC,GPIO_Pin_12)
#define M8_ON()								GPIO_SetBits(GPIOD,GPIO_Pin_2)



#define M1_OFF()							GPIO_ResetBits(GPIOC,GPIO_Pin_0)
#define M2_OFF()							GPIO_ResetBits(GPIOC,GPIO_Pin_1)
#define M3_OFF()							GPIO_ResetBits(GPIOC,GPIO_Pin_2)
#define M4_OFF()							GPIO_ResetBits(GPIOC,GPIO_Pin_3)
#define M5_OFF()							GPIO_ResetBits(GPIOC,GPIO_Pin_10)
#define M6_OFF()							GPIO_ResetBits(GPIOC,GPIO_Pin_11)
#define M7_OFF()							GPIO_ResetBits(GPIOC,GPIO_Pin_12)
#define M8_OFF()							GPIO_ResetBits(GPIOD,GPIO_Pin_2)

#define E1_ON()								GPIO_SetBits(GPIOC,GPIO_Pin_6)
#define E2_ON()								GPIO_SetBits(GPIOC,GPIO_Pin_7)
#define E3_ON()								GPIO_SetBits(GPIOC,GPIO_Pin_8)
#define E4_ON()								GPIO_SetBits(GPIOC,GPIO_Pin_9)




#define E1_OFF()							GPIO_ResetBits(GPIOC,GPIO_Pin_6)
#define E2_OFF()							GPIO_ResetBits(GPIOC,GPIO_Pin_7)
#define E3_OFF()							GPIO_ResetBits(GPIOC,GPIO_Pin_8)
#define E4_OFF()							GPIO_ResetBits(GPIOC,GPIO_Pin_9)
///LD3320引脚相关定义
#define LD3320RST_PIN					GPIO_Pin_15		
#define LD3320RST_GPIO_PORT		GPIOB
#define LD3320RST_GPIO_CLK		RCC_APB2Periph_GPIOB
#define LD_RST_H() 						GPIO_SetBits(GPIOB, GPIO_Pin_15)
#define LD_RST_L() 						GPIO_ResetBits(GPIOB, GPIO_Pin_15)

#define LD3320CS_PIN					GPIO_Pin_4		
#define LD3320CS_GPIO_PORT		GPIOA
#define LD3320CS_GPIO_CLK			RCC_APB2Periph_GPIOA
#define LD_CS_H()							GPIO_SetBits(GPIOA, GPIO_Pin_4)
#define LD_CS_L()							GPIO_ResetBits(GPIOA, GPIO_Pin_4)

#define LD3320IRQ_GPIO_CLK		RCC_APB2Periph_GPIOB
#define LD3320IRQ_PIN					GPIO_Pin_12
#define LD3320IRQ_GPIO_PORT		GPIOB
#define LD3320IRQEXIT_PORTSOURCE		GPIO_PortSourceGPIOB
#define LD3320IRQPINSOURCE		GPIO_PinSource12
#define LD3320IRQEXITLINE			EXTI_Line12
#define LD3320IRQN						EXTI15_10_IRQn

#define LD3320WR_PIN					GPIO_Pin_13
#define LD3320WR_GPIO_PORT		GPIOB
#define LD3320WR_GPIO_CLK			RCC_APB2Periph_GPIOB
#define LD_SPIS_H()  					GPIO_SetBits(GPIOB, GPIO_Pin_13)
#define LD_SPIS_L()  					GPIO_ResetBits(GPIOB, GPIO_Pin_13)

#define	LD3320SPI							SPI1
#define LD3320SPI_CLK					RCC_APB2Periph_SPI1						

#define LD3320SPIMISO_PIN					GPIO_Pin_6
#define LD3320SPIMISO_GPIO_PORT		GPIOA
#define LD3320SPIMISO_GPIO_CLK		RCC_APB2Periph_GPIOA

#define LD3320SPIMOSI_PIN					GPIO_Pin_7
#define LD3320SPIMOSI_GPIO_PORT		GPIOA
#define LD3320SPIMOSI_GPIO_CLK		RCC_APB2Periph_GPIOA

#define LD3320SPISCK_PIN					GPIO_Pin_5
#define LD3320SPISCK_GPIO_PORT		GPIOA
#define LD3320SPISCK_GPIO_CLK			RCC_APB2Periph_GPIOA

#endif

LD3320.h

#ifndef __LD3320_H
#define	__LD3320_H

#include "stm32f10x.h"
#include <stdio.h>
#include "usart_config.h"
#include "LD3320_config.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   					24/* 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

#define MIC_VOL 0x43


void  LD3320_main(void);
static uint8 LD_AsrAddFixed(void);
static void Board_text(uint8 Code_Val);
static void Delayms(uint16 i);

//小车的方向
static void car_go(void);
static void car_back(void);
static void car_right(void);
static void car_left(void);
static void car_stop(void);

///相关初始化
static void LD3320_init(void);
static void LD3320_GPIO_Cfg(void);
static void LD3320_EXTI_Cfg(void);
static void LD3320_SPI_cfg(void);
static void car_Init(void);

///中间层
static void LD3320_delay(unsigned long uldata);
static uint8 RunASR(void);
static void LD_reset(void);
static void LD_AsrStart(void);
static uint8 LD_Check_ASRBusyFlag_b2(void);

///寄存器操作
static uint8 spi_send_byte(uint8 byte);
static void LD_WriteReg(uint8 data1,uint8 data2);
static uint8 LD_ReadReg(uint8 reg_add);
static uint8 LD_GetResult(void);
static uint8 LD_AsrRun(void);
static void ProcessInt(void);
static void LD_Init_Common(void);
static void LD_Init_ASR(void);

#endif /*__LD3320_H */

LD3320.C

#include "LD3320.h"


uint8 nAsrStatus = 0;	
uint8 nLD_Mode = LD_MODE_IDLE;//用来记录当前是在进行ASR识别还是在播放MP3
uint8 ucRegVal;

///用户修改
void LD3320_main(void)
{
	uint8 nAsrRes=0;
	LD3320_init();	  
 	printf("1、小车前进\r\n"); 
	printf("2、小车后退\r\n"); 				
	printf("3、小车右转\r\n"); 		
	printf("4、小车左转\r\n"); 			
	printf("5、小车停止\r\n"); 		
	nAsrStatus = LD_ASR_NONE;//初始状态:没有在作ASR

	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( );//一次ASR识别流程结束,去取ASR识别结果										 
					 printf("\r\n识别码:%d", nAsrRes);			 		
								
					 switch(nAsrRes)		   			//对结果执行相关操作,客户修改
						{
							case CODE_XCQJ:					//命令“小车前进”
								printf(" 小车前进 指令识别成功\r\n"); 
							
															 break;
							case CODE_XCHT:	 					//命令“小车后退”
								printf(" 小车后退 指令识别成功\r\n"); 
															 break;
							case CODE_XCYZ:					//命令“小车右转”
								printf(" 小车右转 指令识别成功\r\n"); 
															break;
							case CODE_XCZZ:						//命令“小车左转”
								printf(" 小车左转 指令识别成功\r\n");
															break;
							case CODE_XCTZ:						//命令“小车停止”
								printf(" 小车停止 指令识别成功\r\n");
							
							default:break;
						}	
					nAsrStatus = LD_ASR_NONE;
					break;
			case LD_ASR_FOUNDZERO:
			default:
					nAsrStatus = LD_ASR_NONE;
					break;
			}//switch
		//开发板测试
		Board_text(nAsrRes );
	}// while
}

static uint8 LD_AsrAddFixed(void)
{
	uint8 k, flag;
	uint8 nAsrAddLength;
	#define DATE_A 5    //数组二维数值
	#define DATE_B 20		//数组一维数值
	//添加关键词
	uint8  sRecog[DATE_A][DATE_B] = {
	 			"xiao che qian jian",\
				"xiao che hou tui",\
				"xiao che you zhuan",\
				"xiao che zuo zhuan",\
				"xiao che ting zhi"\
		
																	};	
	uint8  pCode[DATE_A] = {
	 															CODE_XCQJ,	\
																CODE_XCHT,	\
																CODE_XCYZ,\
																CODE_XCZZ,	\
																CODE_XCTZ		\
															};	//添加识别码
	flag = 1;
	for (k=0; k<DATE_A; k++)
	{			
		if(LD_Check_ASRBusyFlag_b2() == 0)
		{
			flag = 0;
			break;
		}

		LD_WriteReg(0xc1, pCode[k] );
		LD_WriteReg(0xc3, 0);
		LD_WriteReg(0x08, 0x04);
		LD3320_delay(1);
		LD_WriteReg(0x08, 0x00);
		LD3320_delay(1);

		for (nAsrAddLength=0; nAsrAddLength<DATE_B; nAsrAddLength++)
		{
			if (sRecog[k][nAsrAddLength] == 0)
				break;
			LD_WriteReg(0x5, sRecog[k][nAsrAddLength]);
		}
		LD_WriteReg(0xb9, nAsrAddLength);
		LD_WriteReg(0xb2, 0xff);
		LD_WriteReg(0x37, 0x04);
	}	 
	return flag;
}

static void Board_text(uint8 Code_Val)
{																					 
	switch(Code_Val)  //对结果执行相关操作
	{
		case CODE_XCQJ:  //命令“小车前进”
			car_go();
		break;
		case CODE_XCHT:	  //命令“小车后退”
			car_back();
		break;
		case CODE_XCYZ:	//命令“小车右转”
			car_right();
		break;
		case CODE_XCZZ:		//命令“小车左转”
		car_left();
		break;
		case CODE_XCTZ:		//命令“小车停止”
			car_stop();
		break;
		default:break;
	}	
}

static void Delayms(uint16 i)
{
	unsigned char a,b;
	for(;i>0;i--)
	        for(b=4;b>0;b--)
	            for(a=113;a>0;a--);	
}


static void car_go(void)
{

	M1_OFF();M3_OFF();M6_OFF();M7_OFF();
	M2_ON();M4_ON();M5_ON();M8_ON();
	
	E1_ON();E2_ON();E3_ON();E4_ON();	
}

static void car_back(void)
{

	M2_OFF();M4_OFF();M5_OFF();M8_OFF();
	M1_ON();M3_ON();M6_ON();M7_ON();
	
	E1_ON();E2_ON();E3_ON();E4_ON();	
}

static void car_right(void)
{
M3_OFF();M7_OFF();
M4_ON();M8_ON();
E2_ON();E4_ON();
}

static void car_left(void)
{
	M1_OFF();M6_OFF();
	M2_ON();M5_ON();;
	
	E1_ON();E3_ON();
}



static void car_stop(void)
{
E1_OFF();E2_OFF();E3_OFF();E4_OFF();

}




///相关初始化
static void LD3320_init(void)
{
	LD3320_GPIO_Cfg();	
	LD3320_EXTI_Cfg();
	LD3320_SPI_cfg();
	car_Init();
	LD_reset();
}

static void LD3320_GPIO_Cfg(void)
{	
		GPIO_InitTypeDef GPIO_InitStructure;
		RCC_APB2PeriphClockCmd(LD3320RST_GPIO_CLK | LD3320CS_GPIO_CLK,ENABLE);
		//LD_CS	/RSET
		GPIO_InitStructure.GPIO_Pin =LD3320CS_PIN;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
		GPIO_Init(LD3320CS_GPIO_PORT,&GPIO_InitStructure);
		GPIO_InitStructure.GPIO_Pin =LD3320RST_PIN;
		GPIO_Init(LD3320RST_GPIO_PORT,&GPIO_InitStructure);
}

static void LD3320_EXTI_Cfg(void)
{
  EXTI_InitTypeDef EXTI_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	

	RCC_APB2PeriphClockCmd(LD3320IRQ_GPIO_CLK, ENABLE);
  GPIO_InitStructure.GPIO_Pin =LD3320IRQ_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(LD3320IRQ_GPIO_PORT, &GPIO_InitStructure);
	//外部中断线配置
  GPIO_EXTILineConfig(LD3320IRQEXIT_PORTSOURCE, LD3320IRQPINSOURCE);
  EXTI_InitStructure.EXTI_Line = LD3320IRQEXITLINE;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger =EXTI_Trigger_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
	//中断嵌套配置
  NVIC_InitStructure.NVIC_IRQChannel = LD3320IRQN;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

static void LD3320_SPI_cfg(void)
{
	SPI_InitTypeDef  SPI_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
  //spi端口配置
	RCC_APB2PeriphClockCmd(LD3320SPI_CLK,ENABLE);		
  RCC_APB2PeriphClockCmd(LD3320WR_GPIO_CLK | LD3320SPIMISO_GPIO_CLK | LD3320SPIMOSI_GPIO_CLK | LD3320SPISCK_GPIO_CLK,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = LD3320SPIMISO_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(LD3320SPIMISO_GPIO_PORT,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = LD3320SPIMOSI_PIN;
	GPIO_Init(LD3320SPIMOSI_GPIO_PORT,&GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = LD3320SPISCK_PIN;
	GPIO_Init(LD3320SPISCK_GPIO_PORT,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = LD3320WR_PIN;				
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(LD3320WR_GPIO_PORT, &GPIO_InitStructure);
	
	LD_CS_H();
	
	SPI_Cmd(LD3320SPI, DISABLE);

	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;   	//全双工
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;						   						//主模式
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;					   					//8位
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;						   							//时钟极性 空闲状态时,SCK保持低电平
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;						   						//时钟相位 数据采样从第一个时钟边沿开始
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;							   							//软件产生NSS
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;   //波特率控制 SYSCLK/128
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;				   					//数据高位在前
	SPI_InitStructure.SPI_CRCPolynomial = 7;							   							//CRC多项式寄存器初始值为7
	SPI_Init(LD3320SPI, &SPI_InitStructure);

	SPI_Cmd(LD3320SPI, ENABLE);
}

static void car_Init(void)
{	
		GPIO_InitTypeDef GPIO_InitStructure;
	
		RCC_APB2PeriphClockCmd(M1_GPIO_CLK | M2_GPIO_CLK | M3_GPIO_CLK | M4_GPIO_CLK|M5_GPIO_CLK | M6_GPIO_CLK | M7_GPIO_CLK | M8_GPIO_CLK| E1_GPIO_CLK| E2_GPIO_CLK| E3_GPIO_CLK| E4_GPIO_CLK,ENABLE);
	
		GPIO_InitStructure.GPIO_Pin = M1_PIN;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
		GPIO_Init(M1_GPIO_PORT, &GPIO_InitStructure);
		GPIO_InitStructure.GPIO_Pin = M2_PIN;
		GPIO_Init(M2_GPIO_PORT, &GPIO_InitStructure);
		GPIO_InitStructure.GPIO_Pin = M3_PIN;
		GPIO_Init(M3_GPIO_PORT, &GPIO_InitStructure);
		GPIO_InitStructure.GPIO_Pin = M4_PIN;
		GPIO_Init(M4_GPIO_PORT, &GPIO_InitStructure);	
	  GPIO_InitStructure.GPIO_Pin = M5_PIN;
		GPIO_Init(M5_GPIO_PORT, &GPIO_InitStructure);
		GPIO_InitStructure.GPIO_Pin = M6_PIN;
		GPIO_Init(M6_GPIO_PORT, &GPIO_InitStructure);
		GPIO_InitStructure.GPIO_Pin = M7_PIN;
		GPIO_Init(M7_GPIO_PORT, &GPIO_InitStructure);
		GPIO_InitStructure.GPIO_Pin = M8_PIN;
		GPIO_Init(M8_GPIO_PORT, &GPIO_InitStructure);
	
	
	
	  GPIO_InitStructure.GPIO_Pin = E1_PIN;
		GPIO_Init(E1_GPIO_PORT, &GPIO_InitStructure);
	   GPIO_InitStructure.GPIO_Pin = E2_PIN;
		GPIO_Init(E2_GPIO_PORT, &GPIO_InitStructure);
		GPIO_InitStructure.GPIO_Pin = E3_PIN;
		GPIO_Init(E3_GPIO_PORT, &GPIO_InitStructure);
	   GPIO_InitStructure.GPIO_Pin = E4_PIN;
		GPIO_Init(E4_GPIO_PORT, &GPIO_InitStructure);
	

}
///相关初始化 end 

///中间层
void EXTI15_10_IRQHandler(void)
{
	if(EXTI_GetITStatus(LD3320IRQEXITLINE)!= RESET ) 
	{
		ProcessInt(); 
 		printf("进入中断12\r\n");	
		EXTI_ClearFlag(LD3320IRQEXITLINE);
		EXTI_ClearITPendingBit(LD3320IRQEXITLINE);//清除LINE上的中断标志位  
	} 
}

static void LD3320_delay(unsigned long uldata)
{
	unsigned int i  =  0;
	unsigned int j  =  0;
	unsigned int k  =  0;
	for (i=0;i<5;i++)
	{
		for (j=0;j<uldata;j++)
		{
			k = 200;
			while(k--);
		}
	}
}

static 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;
}

static void LD_reset(void)
{
	uint8 i;
	LD_RST_H();
	LD3320_delay(100);
	LD_RST_L();
	LD3320_delay(100);
	LD_RST_H();
	LD3320_delay(100);
	LD_CS_L();
	LD3320_delay(100);
	LD_CS_H();		
	LD3320_delay(100);
	
	i=LD_ReadReg(0x6);
	LD_WriteReg(0x35, 0x33);
	LD_WriteReg(0x1b, 0x55);
	LD_WriteReg(0xb3, 0xaa);
	i=LD_ReadReg(0x35);
	i=LD_ReadReg(0x1b);
	i=LD_ReadReg(0xb3);
	i=i;
	LD_RST_H();
	LD3320_delay(100);
	LD_RST_L();
	LD3320_delay(100);
	LD_RST_H();
	LD3320_delay(100);
	LD_CS_L();
	LD3320_delay(100);
	LD_CS_H();		
	i=LD_ReadReg(0x6);
	LD3320_delay(100);
	i=LD_ReadReg(0x35);
	i=LD_ReadReg(0x1b);
	i=LD_ReadReg(0xb3);
	i=i;
}

static void LD_AsrStart(void)
{
	LD_Init_ASR();
}

uint8 LD_Check_ASRBusyFlag_b2(void)
{
	uint8 j;
	uint8 flag = 0;
	for (j=0; j<10; j++)
	{
		if (LD_ReadReg(0xb2) == 0x21)
		{
			flag = 1;
			break;
		}
		LD3320_delay(10);		
	}
	return flag;
}
///中间层end


///寄存器操作
static uint8 spi_send_byte(uint8 byte)
{
	while (SPI_I2S_GetFlagStatus(LD3320SPI, SPI_I2S_FLAG_TXE) == RESET);
	SPI_I2S_SendData(LD3320SPI,byte);
	while (SPI_I2S_GetFlagStatus(LD3320SPI,SPI_I2S_FLAG_RXNE) == RESET);
	return SPI_I2S_ReceiveData(LD3320SPI);
}

static void LD_WriteReg(uint8 data1,uint8 data2)
{
	LD_CS_L();
	LD_SPIS_L();
	spi_send_byte(0x04);
	spi_send_byte(data1);
	spi_send_byte(data2);
	LD_CS_H();
}

static uint8 LD_ReadReg(uint8 reg_add)
{
	uint8 i;
	LD_CS_L();
	LD_SPIS_L();
	spi_send_byte(0x05);
	spi_send_byte(reg_add);
	i=spi_send_byte(0x00);
	LD_CS_H();
	return(i);
}

static uint8 LD_GetResult(void)
{
	return LD_ReadReg(0xc5);
}

static uint8 LD_AsrRun(void)
{
	LD_WriteReg(0x35, MIC_VOL);
	LD_WriteReg(0x1C, 0x09);
	LD_WriteReg(0xBD, 0x20);
	LD_WriteReg(0x08, 0x01);
	LD3320_delay( 5 );
	LD_WriteReg(0x08, 0x00);
	LD3320_delay( 5);

	if(LD_Check_ASRBusyFlag_b2() == 0)
	{
		return 0;
	}

	LD_WriteReg(0xB2, 0xff);	
	LD_WriteReg(0x37, 0x06);
	LD_WriteReg(0x37, 0x06);
	LD3320_delay(5);
	LD_WriteReg(0x1C, 0x0b);
	LD_WriteReg(0x29, 0x10);
	LD_WriteReg(0xBD, 0x00);   
	return 1;
}

static void ProcessInt(void)
{
	uint8 nAsrResCount=0;

	ucRegVal = LD_ReadReg(0x2B);

// 语音识别产生的中断
//(有声音输入,不论识别成功或失败都有中断)
	LD_WriteReg(0x29,0) ;
	LD_WriteReg(0x02,0) ;

	if((ucRegVal & 0x10) && LD_ReadReg(0xb2)==0x21 && LD_ReadReg(0xbf)==0x35)		
	{	 
			nAsrResCount = LD_ReadReg(0xba);

			if(nAsrResCount>0 && nAsrResCount<=4) 
			{
				nAsrStatus=LD_ASR_FOUNDOK; 				
			}
			else
			{
				nAsrStatus=LD_ASR_FOUNDZERO;
			}	
	}
	else
	{
		nAsrStatus=LD_ASR_FOUNDZERO;//执行没有识别
	}

	LD_WriteReg(0x2b,0);
	LD_WriteReg(0x1C,0);//写0:ADC不可用
	LD_WriteReg(0x29,0);
	LD_WriteReg(0x02,0);
	LD_WriteReg(0x2B,0);
	LD_WriteReg(0xBA,0);	
	LD_WriteReg(0xBC,0);	
	LD_WriteReg(0x08,1);//清除FIFO_DATA
	LD_WriteReg(0x08,0);//清除FIFO_DATA后 再次写0
}

static void LD_Init_Common(void)
{
	LD_ReadReg(0x06);  
	LD_WriteReg(0x17, 0x35); 
	LD3320_delay(5);
	LD_ReadReg(0x06);  

	LD_WriteReg(0x89, 0x03);  
	LD3320_delay(5);
	LD_WriteReg(0xCF, 0x43);   
	LD3320_delay(5);
	LD_WriteReg(0xCB, 0x02);
	
	/*PLL setting*/
	LD_WriteReg(0x11, LD_PLL_11);       
	if (nLD_Mode == LD_MODE_MP3)
	{
		LD_WriteReg(0x1E, 0x00); 
		LD_WriteReg(0x19, LD_PLL_MP3_19);   
		LD_WriteReg(0x1B, LD_PLL_MP3_1B);   
		LD_WriteReg(0x1D, LD_PLL_MP3_1D);
	}
	else
	{
		LD_WriteReg(0x1E,0x00);
		LD_WriteReg(0x19, LD_PLL_ASR_19); 
		LD_WriteReg(0x1B, LD_PLL_ASR_1B);		
	  LD_WriteReg(0x1D, LD_PLL_ASR_1D);
	}
	LD3320_delay(5);
	
	LD_WriteReg(0xCD, 0x04);
	LD_WriteReg(0x17, 0x4c); 
	LD3320_delay(1);
	LD_WriteReg(0xB9, 0x00);
	LD_WriteReg(0xCF, 0x4F); 
	LD_WriteReg(0x6F, 0xFF); 
}

static void LD_Init_ASR(void)
{
	nLD_Mode=LD_MODE_ASR_RUN;
	LD_Init_Common();

	LD_WriteReg(0xBD, 0x00);
	LD_WriteReg(0x17, 0x48);	
	LD3320_delay(5);
	LD_WriteReg(0x3C, 0x80);    
	LD_WriteReg(0x3E, 0x07);
	LD_WriteReg(0x38, 0xff);    
	LD_WriteReg(0x3A, 0x07);
	LD_WriteReg(0x40, 0);          
	LD_WriteReg(0x42, 8);
	LD_WriteReg(0x44, 0);    
	LD_WriteReg(0x46, 8); 
	LD3320_delay( 1 );
}
///寄存器操作 end
/*********************************************END OF FILE**********************/

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐