目录
本节主要贴上以前写的语音识别外设LD3320,希望对大家有用,本人已经测试过有用
如何使用,将下面这段函数添加到功能函数中
LD3320.h
LD3320.c
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_LSD: //命令“流水灯”
{
printf(" 流水灯 指令识别成功\r\n");
//SYN6288_Speech(DEBUG_USARTx,"现在展示流水灯"); /*播放声音,播放声音时候LED会灭掉,就是BY接口用来检测是否繁忙的*/
Delay_ms(200);
break;
}
case CODE_SS: //命令“闪烁”
{
printf(" 名字 指令识别成功\r\n");
// SYN6288_Speech(DEBUG_USARTx,"现在展示闪烁"); /*播放声音,播放声音时候LED会灭掉,就是BY接口用来检测是否繁忙的*/
Delay_ms(200);
break;
}
case LDE_1:
{
printf(" 红灯打开\r\n");
//SYN6288_Speech(DEBUG_USARTx,"按键触发"); /*播放声音,播放声音时候LED会灭掉,就是BY接口用来检测是否繁忙的*/
Delay_ms(200);
break;
}
case LDE_2:
{
printf(" 绿灯打开\r\n");
//SYN6288_Speech(DEBUG_USARTx,"全灭 指令识别成功"); /*播放声音,播放声音时候LED会灭掉,就是BY接口用来检测是否繁忙的*/
Delay_ms(200);
break;
}
case LDE_3:
{
printf(" 蓝灯打开\r\n");
// SYN6288_Speech(DEBUG_USARTx,"状态 指令识别成功"); /*播放声音,播放声音时候LED会灭掉,就是BY接口用来检测是否繁忙的*/
Delay_ms(200);
break;
}
case LDE_1_1:
{
printf(" 红灯关闭\r\n");
//SYN6288_Speech(DEBUG_USARTx,"按键触发"); /*播放声音,播放声音时候LED会灭掉,就是BY接口用来检测是否繁忙的*/
Delay_ms(200);
break;
}
case LDE_2_1:
{
printf(" 绿灯关闭\r\n");
//SYN6288_Speech(DEBUG_USARTx,"全灭 指令识别成功"); /*播放声音,播放声音时候LED会灭掉,就是BY接口用来检测是否繁忙的*/
Delay_ms(200);
break;
}
case LDE_3_1:
{
printf(" 蓝灯关闭\r\n");
// SYN6288_Speech(DEBUG_USARTx,"状态 指令识别成功"); /*播放声音,播放声音时候LED会灭掉,就是BY接口用来检测是否繁忙的*/
Delay_ms(200);
break;
}
case LDE_All_OFF: //命令“状态”
{
printf(" 全灯关闭打开\r\n");
// SYN6288_Speech(DEBUG_USARTx,"状态 指令识别成功"); /*播放声音,播放声音时候LED会灭掉,就是BY接口用来检测是否繁忙的*/
Delay_ms(200);
break;
}
case chen:
{
// SYN6288_Speech(DEBUG_USARTx,"状态 指令识别成功"); /*播放声音,播放声音时候LED会灭掉,就是BY接口用来检测是否繁忙的*/
Delay_ms(200);
break;
}
case chen_1:
{
// SYN6288_Speech(DEBUG_USARTx,"状态 指令识别成功"); /*播放声音,播放声音时候LED会灭掉,就是BY接口用来检测是否繁忙的*/
Delay_ms(200);
break;
}
case voice_J_0:
{
printf(" 音量提高\r\n");
//SYN6288_Speech(DEBUG_USARTx,"全灭 指令识别成功"); /*播放声音,播放声音时候LED会灭掉,就是BY接口用来检测是否繁忙的*/
Delay_ms(200);
break;
}
case voice_J_1:
{
printf(" 音量降低\r\n");
// SYN6288_Speech(DEBUG_USARTx,"状态 指令识别成功"); /*播放声音,播放声音时候LED会灭掉,就是BY接口用来检测是否繁忙的*/
Delay_ms(200);
break;
}
default:break;
}
nAsrStatus = LD_ASR_NONE;
break;
case LD_ASR_FOUNDZERO:
default:
nAsrStatus = LD_ASR_NONE;
break;
}//switch
#ifndef _LD3320_H__
#define _LD3320_H__
#include "stm32f10x_exti.h"
#include "stm32f10x_spi.h"
///以下三个状态定义用来记录程序是在运行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_t)((CLK_IN/2.0)-1)
#define LD_PLL_MP3_19 0x0f
#define LD_PLL_MP3_1B 0x18
#define LD_PLL_MP3_1D (uint8_t)(((90.0*((LD_PLL_11)+1))/(CLK_IN))-1)
#define LD_PLL_ASR_19 (uint8_t)(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
///识别码(客户修改处)
#define CODE_LSD 1 //唤醒
#define CODE_SS 2 //名字
#define LDE_1 3 //打开红
#define LDE_2 4 //打开绿
#define LDE_3 5 //打开蓝
#define LDE_All_OFF 6 //状态
#define voice_J_0 7 //提高音量
#define LDE_1_1 51 //打开红
#define LDE_2_1 52 //打开绿
#define LDE_3_1 53 //打开蓝
#define voice_J_1 57 //降低音量
#define chen 90 //娱乐
#define chen_1 91 //娱乐
///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)
///LD3320引脚相关定义
#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
///相关初始化
void LD3320_main(void);
void LD3320_init(void);
static void LD3320_GPIO_Cfg(void);
static void LD3320_EXTI_Cfg(void);
static void LD3320_SPI_cfg(void);
///中间层
static void LD3320_delay(unsigned long uldata);
uint8_t RunASR(void);
void LD_reset(void);
void LD_AsrStart(void);
uint8_t LD_Check_ASRBusyFlag_b2(void);
///寄存器操作
uint8_t spi_send_byte(uint8_t byte);
void LD_WriteReg(uint8_t data1,uint8_t data2);
uint8_t LD_ReadReg(uint8_t reg_add);
uint8_t LD_AsrAddFixed(void);
uint8_t LD_GetResult(void);
uint8_t LD_AsrRun(void);
void ProcessInt(void);
void LD_Init_Common(void);
void LD_Init_ASR(void);
#endif
#include "LD3320.h"
#include "string.h"
#include "bsp_SysTick.h"
#include
#include "bsp_usart1.h"
#include "SYN6288.h"
#include "bsp_led.h"
/************************************************************************************
// nAsrStatus 用来在main主程序中表示程序运行的状态,不是LD3320芯片内部的状态寄存器
// LD_ASR_NONE: 表示没有在作ASR识别
// LD_ASR_RUNING: 表示LD3320正在作ASR识别中
// LD_ASR_FOUNDOK: 表示一次识别流程结束后,有一个识别结果
// LD_ASR_FOUNDZERO: 表示一次识别流程结束后,没有识别结果
// LD_ASR_ERROR: 表示一次识别流程中LD3320芯片内部出现不正确的状态
首先:
LD3320
SPI总线
RST—PB15,
CS--PA4,
IRQ—PB12,
WR—PB13,
MISO—PA6,
MOSI—PA7,
SCK—PA5
*********************************************************************************/
extern uint8_t nAsrStatus;
uint8_t nLD_Mode = LD_MODE_IDLE;//用来记录当前是在进行ASR识别还是在播放MP3
uint8_t ucRegVal;
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);
}
///中间层
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(LD3320IRQEXITLINE)!= RESET )
{
ProcessInt();
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;j0 && 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
}
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);
}
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 );
}
///相关初始化
void LD3320_init(void)
{
LD3320_GPIO_Cfg();
LD3320_EXTI_Cfg();
LD3320_SPI_cfg();
LD_reset();
}
static uint8_t LD_AsrAddFixed(void)
{
uint8_t k, flag;
uint8_t nAsrAddLength;
#define DATE_A 20 //数组二维数值
#define DATE_B 50 //数组一维数值
//添加关键词,用户修改
uint8_t sRecog[DATE_A][DATE_B] = {
"xiao die xiao die",\
"ni jiao shen me",\
"ni shi shei",\
"da kai hong deng",\
"da kai lv deng",\
"da kai lan deng",\
"guan bi hong deng",\
"guan bi lv deng",\
"guan bi lan deng",\
"chen meng die shi shei",\
"chen xiang xin shi shei",\
"yin liang ti gao",\
"yin liang jiang da",\
"guan bi suo you deng" \
};
uint8_t pCode[DATE_A] = {
CODE_LSD, \
CODE_SS, \
CODE_SS, \
LDE_1, \
LDE_2, \
LDE_3, \
LDE_1_1, \
LDE_2_1, \
LDE_3_1, \
chen, \
chen_1, \
voice_J_0, \
voice_J_1, \
LDE_All_OFF \
}; //添加识别码,用户修改
flag = 1;
for (k=0; k