雷龍LSYT201B語音模塊配合STM32使用視頻示例:https://www.bilibili.com/video/BV1SZ421M7oE?t=2.9
前言
基于YT2228芯片開發(fā)的一款面向智能家居控制的離線語音控制模組,離線語音模塊,集成藍(lán)牙功能,可適配各種不同的應(yīng)用場景,方便使用,減少開發(fā)周期。模塊通過麥克風(fēng)對語音進(jìn)行采集,然后由語音芯片進(jìn)行識別處理,識別成功的結(jié)果可通過語音進(jìn)行播報和通過串口下發(fā)指令給整機控制板。
一、LSYT201B
一、產(chǎn)品簡介
YT2228 是根據(jù)智能語音交互市場需求及思必馳算法的發(fā)展方向定義開發(fā)的 “芯片+算法”人工智能人機語音交互解決方案,具有高性能、低功耗等特點。
該芯片通過軟硬融合的方法,具備快速賦予各類設(shè)備語音交互的能力,極大的提高了用戶體驗和產(chǎn)品靈活性。該芯片支持家居5m交互,本地最多可識別150詞,具備多輪交互能力。
二、產(chǎn)品特征
2.1 處理器
? 32位處理器,支持FPU(Hardware Float Point Unit)
? 運行頻率:240MHz
? 內(nèi)置 2MB FLASH
? 64中斷向量
? 4級別中斷優(yōu)先級
2.2 外設(shè)
? USB1.1
? 4個多功能16位定時器,支持捕獲和PWM模式
? 3個16位PWM發(fā)生器,可用于驅(qū)動電機
? 2個SPI
? 所有GPIO支持外部中斷
2.3 音頻
? 兩通道 16 位 DAC,SNR> = 95dB
? 單通道 16 位 ADC,SNR> = 90dB
? 采樣率支持 8KHz / 11.025KHz / 16KHz / 22.05KHz / 24KHz
/32KHz / 44.1KHz / 48KHz
2.4 藍(lán)牙
? 符合藍(lán)牙 V5.1 + BR + EDR + BLE 規(guī)范
? 滿足 Class1 class2 和 class3 傳輸功耗需求
? 支持 GFSK 和 π/ 4 DQPSK 所有包裝類型
? 最大+ 6dbm 發(fā)射功率
? 接收器最小靈敏度
2.5 電源
? VDDIO可輸出50mA@2.2-3.6V
? 模組功耗:50mA
2.6 封裝
? VSSOP28(0.635)/QSOP28
2.7 溫度
? 工作溫度:-40℃ to +85℃
? 存儲溫度:-65℃ to +150℃
2.8 應(yīng)用領(lǐng)域
? 智能家電(生活電器、廚房家電等)
? 智能衛(wèi)浴、智能照明、智能家居
? 智能玩具
? 空調(diào)伴侶
二、使用步驟
現(xiàn)在也已經(jīng)大致了解了這個模塊的功能,那么能不能結(jié)合單片機來使用呢。
1.UART 控制協(xié)議
先來看一下他的通信協(xié)議
采用標(biāo)準(zhǔn) UART 異步串口接口, 3.3V TTL 電平。通訊格式
波特率9600、數(shù)據(jù)位8 位、停止位1 位、奇偶校驗位無、流控?zé)o。
有了這些東西去對他進(jìn)行開發(fā)還不是輕輕松松,關(guān)鍵效果怎么樣呢(太強了,從視頻里就能看出)
2.代碼
廢話不多說直接貼代碼。由于STM32接收的是ASII碼,我們先將他轉(zhuǎn)十六進(jìn)制字符串,然后用strcmp來對字符串作比較。
代碼如下:
#include "sys.h"
#include "usart.h"
#include "led.h"
#include "string.h"
//
//如果使用ucos,則包括下面的頭文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h" //ucos 使用
#endif
#if 1
#pragma import(__use_no_semihosting)
//標(biāo)準(zhǔn)庫需要的支持函數(shù)
struct __FILE
{
int handle;
};
FILE __stdout;
//定義_sys_exit()以避免使用半主機模式
_sys_exit(int x)
{
x = x;
}
//重定義fputc函數(shù)
int fputc(int ch, FILE *f)
{
while((USART2->SR&0X40)==0);//循環(huán)發(fā)送,直到發(fā)送完畢
USART2->DR = (u8) ch;
return ch;
}
#endif
/*使用microLib的方法*/
/*
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (uint8_t) ch);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}
return ch;
}
int GetKey (void) {
while (!(USART1->SR & USART_FLAG_RXNE));
return ((int)(USART1->DR & 0x1FF));
}
*/
#if EN_USART1_RX //如果使能了接收
//串口1中斷服務(wù)程序
//注意,讀取USARTx->SR能避免莫名其妙的錯誤
u8 USART_RX_BUF[USART_REC_LEN]; //接收緩沖,最大USART_REC_LEN個字節(jié).
//接收狀態(tài)
//bit15, 接收完成標(biāo)志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字節(jié)數(shù)目
u16 USART_RX_STA=0; //接收狀態(tài)標(biāo)記
u8 USART2_RX_BUF[USART_REC_LEN]; //接收緩沖,最大USART_REC_LEN個字節(jié).
//接收狀態(tài)
//bit15, 接收完成標(biāo)志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字節(jié)數(shù)目
u16 USART2_RX_STA=0; //接收狀態(tài)標(biāo)記
void uart_init(u32 bound){
//GPIO端口設(shè)置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA時鐘
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復(fù)用推挽輸出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//搶占優(yōu)先級3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子優(yōu)先級3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根據(jù)指定的參數(shù)初始化VIC寄存器
//USART 初始化設(shè)置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數(shù)據(jù)格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數(shù)據(jù)流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發(fā)模式
USART_Init(USART1, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開啟串口接受中斷
USART_Cmd(USART1, ENABLE); //使能串口1
}
void uart2_init(u32 bound){
//GPIO端口設(shè)置
//GPIO端口設(shè)置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA時鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE); //使能USART2
//USART2_TX GPIOA.2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.2
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復(fù)用推挽輸出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.2
//USART1_RX GPIOA.3初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.3
//Usart2 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//搶占優(yōu)先級3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子優(yōu)先級3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根據(jù)指定的參數(shù)初始化VIC寄存器
//USART 初始化設(shè)置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數(shù)據(jù)格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數(shù)據(jù)流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發(fā)模式
USART_Init(USART2, &USART_InitStructure); //初始化串口2
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//開啟串口接受和發(fā)送中斷
USART_Cmd(USART2, ENABLE);
}
void USART2_IRQHandler(void) //??2??????
{
u8 Res,t;
/
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中斷(接收到的數(shù)據(jù)必須是0x0d 0x0a結(jié)尾)
{
Res =USART_ReceiveData(USART2); //讀取接收到的數(shù)據(jù)
if((USART2_RX_STA&0x8000)==0)//接收未完成
{
if(USART2_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART2_RX_STA=0;//接收錯誤,重新開始
else USART2_RX_STA|=0x8000; //接收完成了
}
else //還沒收到0X0D
{
if(Res==0x0d)USART2_RX_STA|=0x4000;
else
{
USART2_RX_BUF[USART2_RX_STA&0X3FFF]=Res ;
USART2_RX_STA++;
if(USART2_RX_STA>(USART2_REC_LEN-1))USART2_RX_STA=0;//接收數(shù)據(jù)錯誤,重新開始接收
}
}
}
}
}
void USART1_IRQHandler(void) //串口1中斷服務(wù)程序
{
u8 Res;
char result[100];
char hex_string[30];
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS為真,則需要支持OS.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中斷(接收到的數(shù)據(jù)必須是0x0d 0x0a結(jié)尾)
{
Res =USART_ReceiveData(USART1); //讀取接收到的數(shù)據(jù)
sprintf(hex_string,"%02X", Res);
//printf("%srn",hex_string);
sscanf(hex_string + 5, "%s", hex_string);
if(!strcmp(hex_string,"03"))
{
GPIO_ResetBits(GPIOB,GPIO_Pin_5);
GPIO_ResetBits(GPIOE,GPIO_Pin_5);
}
if(!strcmp(hex_string,"04"))
{
GPIO_SetBits(GPIOB,GPIO_Pin_5);
GPIO_SetBits(GPIOE,GPIO_Pin_5);
}
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收錯誤,重新開始
else USART_RX_STA|=0x8000; //接收完成了
}
else //還沒收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收數(shù)據(jù)錯誤,重新開始接收
}
}
}
}
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS為真,則需要支持OS.
OSIntExit();
#endif
}
#endif
總結(jié)
兄弟們,太強了,25塊錢能夠抗噪聲的語音識別播報一體模塊,還要什么自行車。就是喚醒詞不能自己定制,需要聯(lián)系技術(shù)人員幫你定制。(可以遠(yuǎn)程)
————————————————
雷龍發(fā)展公司致力于為客戶提供一站式的離線語音解決方案。我們的服務(wù)涵蓋了多個領(lǐng)域,包括家電、醫(yī)療器械、安防報警、汽車電子、多媒體、通信、電話錄音、工業(yè)自動化控制、玩具及互動消費類產(chǎn)品等。通過我們的專業(yè)知識和經(jīng)驗,我們能夠滿足各類產(chǎn)品的語音交互需求,讓用戶享受更加智能、便捷的使用體驗。
審核編輯 黃宇
-
STM32
+關(guān)注
關(guān)注
2264文章
10854瀏覽量
354286 -
智能家居
+關(guān)注
關(guān)注
1926文章
9471瀏覽量
183864 -
人機語音
+關(guān)注
關(guān)注
0文章
3瀏覽量
7134
發(fā)布評論請先 登錄
相關(guān)推薦
評論