#include "config.h"
extern void delay(unsigned long uldata);
uint8 idata ucRegVal;
extern uint8 idata nAsrStatus;
void ProcessInt0(void);
/************************************************************************
功能描述: 復位LD模塊
入口參數: none
返 回 值: none
其他說明: none
**************************************************************************/
void LD_Reset()
{
RSTB=1;
delay(1);
RSTB=0;
delay(1);
RSTB=1;
delay(1);
CSB=0;
delay(1);
CSB=1;
delay(1);
}
/************************************************************************
功能描述: LD模塊命令初始化
入口參數: none
返 回 值: none
其他說明: 該函數為出廠配置,一般不需要修改;
有興趣的客戶可對照開發手冊根據需要自行修改。
**************************************************************************/
void LD_Init_Common()
{
LD_ReadReg(0x06);
LD_WriteReg(0x17, 0x35);
delay(10);
LD_ReadReg(0x06);
LD_WriteReg(0x89, 0x03);
delay(5);
LD_WriteReg(0xCF, 0x43);
delay(5);
LD_WriteReg(0xCB, 0x02);
/*PLL setting*/
LD_WriteReg(0x11, LD_PLL_11);
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);
delay(10);
LD_WriteReg(0xCD, 0x04);
// LD_WriteReg(0x17, 0x4c);
delay(5);
LD_WriteReg(0xB9, 0x00);
LD_WriteReg(0xCF, 0x4F);
LD_WriteReg(0x6F, 0xFF);
}
/************************************************************************
功能描述: LD模塊 ASR功能初始化
入口參數: none
返 回 值: none
其他說明: 該函數為出廠配置,一般不需要修改;
有興趣的客戶可對照開發手冊根據需要自行修改。
**************************************************************************/
void LD_Init_ASR()
{
LD_Init_Common();
LD_WriteReg(0xBD, 0x00);
LD_WriteReg(0x17, 0x48);
delay( 10 );
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);
delay( 1 );
}
/************************************************************************
功能描述: 中斷處理函數
入口參數: none
返 回 值: none
其他說明: 當LD模塊接收到音頻信號時,將進入該函數,
判斷識別是否有結果,如果沒有從新配置寄
存器準備下一次的識別。
**************************************************************************/
void ProcessInt0(void)
{
uint8 nAsrResCount=0;
EX0=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*/
EX0=1;
}
/************************************************************************
功能描述: 運行ASR識別流程
入口參數: none
返 回 值: asrflag:1->啟動成功, 0—>啟動失敗
其他說明: 識別順序如下:
1、RunASR()函數實現了一次完整的ASR語音識別流程
2、LD_AsrStart() 函數實現了ASR初始化
3、LD_AsrAddFixed() 函數實現了添加關鍵詞語到LD3320芯片中
4、LD_AsrRun() 函數啟動了一次ASR語音識別流程
任何一次ASR識別流程,都需要按照這個順序,從初始化開始
**************************************************************************/
uint8 RunASR(void)
{
uint8 i=0;
uint8 asrflag=0;
for (i=0; i<5; i++) // 防止由于硬件原因導致LD3320芯片工作不正常,所以一共嘗試5次啟動ASR識別流程
{
LD_AsrStart();
delay(50);
if (LD_AsrAddFixed()==0)
{
LD_Reset(); // LD3320芯片內部出現不正常,立即重啟LD3320芯片
delay(50); // 并從初始化開始重新ASR識別流程
continue;
}
delay(10);
if (LD_AsrRun() == 0)
{
LD_Reset(); // LD3320芯片內部出現不正常,立即重啟LD3320芯片
delay(50); // 并從初始化開始重新ASR識別流程
continue;
}
asrflag=1;
break; // ASR流程啟動成功,退出當前for循環。開始等待LD3320送出的中斷信號
}
return asrflag;
}
/************************************************************************
功能描述: 檢測LD模塊是否空閑
入口參數: none
返 回 值: flag:1-> 空閑
其他說明: none
**************************************************************************/
uint8 LD_Check_ASRBusyFlag_b2()
{
uint8 j;
uint8 flag = 0;
for (j=0; j<10; j++)
{
if (LD_ReadReg(0xb2) == 0x21)
{
flag = 1;
break;
}
delay(10);
}
return flag;
}
/************************************************************************
功能描述: 啟動ASR
入口參數: none
返 回 值: none
其他說明: none
**************************************************************************/
void LD_AsrStart()
{
LD_Init_ASR();
}
/************************************************************************
功能描述: 運行ASR
入口參數: none
返 回 值: 1:啟動成功
其他說明: none
**************************************************************************/
uint8 LD_AsrRun()
{
EX0=0;
LD_WriteReg(0x35, MIC_VOL);
LD_WriteReg(0x1C, 0x09);
LD_WriteReg(0xBD, 0x20);
LD_WriteReg(0x08, 0x01);
delay( 1 );
LD_WriteReg(0x08, 0x00);
delay( 1 );
if(LD_Check_ASRBusyFlag_b2() == 0)
{
return 0;
}
// LD_WriteReg(0xB6, 0xa); //識別時間 1S
// LD_WriteReg(0xB5, 0x1E); //背景音段時間 300ms
// LD_WriteReg(0xB8, 10); //結束時間
// LD_WriteReg(0x1C, 0x07); //配置雙通道音頻信號做為輸入信號
LD_WriteReg(0x1C, 0x0b); //配置麥克風做為輸入信號
LD_WriteReg(0xB2, 0xff);
delay( 1);
LD_WriteReg(0x37, 0x06);
delay( 1 );
LD_WriteReg(0x37, 0x06);
delay( 5 );
LD_WriteReg(0x29, 0x10);
LD_WriteReg(0xBD, 0x00);
EX0=1;
return 1;
}
/************************************************************************
功能描述: 向LD模塊添加關鍵詞
入口參數: none
返 回 值: flag:1->添加成功
其他說明: 用戶修改.
1、根據如下格式添加拼音關鍵詞,同時注意修改sRecog 和pCode 數組的長度
和對應變了k的循環置。拼音串和識別碼是一一對應的。
2、開發者可以學習"語音識別芯片LD3320高階秘籍.pdf"中
關于垃圾詞語吸收錯誤的用法,來提供識別效果。
3、”xiao jie “ 為口令,故在每次識別時,必須先發一級口令“小捷”
**************************************************************************/
uint8 LD_AsrAddFixed()
{
uint8 k, flag;
uint8 nAsrAddLength;
#define DATE_A 11 /*數組二維數值*/
#define DATE_B 25 /*數組一維數值*/
uint8 code sRecog[DATE_A][DATE_B] = {
"bai jia lao niang men",\
"kai ke ting deng",\
"guan ke ting deng",\
"kai dian shi ji",\
"guan dian shi ji",\
"kai wo shi deng",\
"guan wo shi deng",\
"kai can ting deng",\
"guan can ting deng",\
"kai chu fang deng",\
"guan chu fang deng"
}; /*添加關鍵詞,用戶修改*/
uint8 code pCode[DATE_A] = {
CODE_CMD,\
CODE_KKTD,\
CODE_GKTD,\
CODE_KDSJ,\
CODE_GDSJ,\
CODE_KWSD,\
CODE_GWSD,\
CODE_KCTD,\
CODE_GCTD,\
CODE_KCFD,\
CODE_GCFD,
}; /*添加識別碼,用戶修改*/
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);
delay(1);
LD_WriteReg(0x08, 0x00);
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;
}
/************************************************************************
功能描述: 獲取識別結果
入口參數: none
返 回 值: LD_ReadReg(0xc5 ); 讀取內部寄存器返回識別碼。
其他說明: none
**************************************************************************/
uint8 LD_GetResult()
{
return LD_ReadReg(0xc5 );
}
|