MCU開發(fā)接入VOI611指南
本文主要描述了MCU接入VOI611方案的開發(fā)流程,適用于嵌入式開發(fā)工程師及個人開發(fā)者快速入門,了解接入VOI611方案的方法。
1. 方案概述
MCU接入VOI611是快速實現(xiàn)產(chǎn)品語音智能化的常用方法,適用于已內(nèi)置MCU主控的產(chǎn)品。
例如空調(diào)、洗衣機等大、小家電產(chǎn)品,自身MCU已具備復(fù)雜的外設(shè)控制和邏輯,接入VOI611串口協(xié)議即可實現(xiàn)語音交互功能,您只需要關(guān)注產(chǎn)品功能和語音交互(對話)的設(shè)計,復(fù)雜的語音算法和模型訓(xùn)練交由探境科技處理。

如上圖所示,藍(lán)色部分的VOI611可作為一個外部輸入輸出設(shè)備,主要具備以下兩個功能:
- 通過 MIC 輸入(語音識別結(jié)果等)
- 通過 SPK 輸出(提示音等)
在本方案中,語音芯片內(nèi)置寄存器表,產(chǎn)品主控MCU通過UART對VOI611的寄存器表進(jìn)行配置,無需修改VOI611片內(nèi)的軟件代碼,從而實現(xiàn)芯片的參數(shù)設(shè)定。
通常,語音芯片VOI611不維護(hù)產(chǎn)品狀態(tài)(例如電機、燈光等電控設(shè)備由產(chǎn)品主控MCU維護(hù),如上圖綠色部分),這種方式使得VOI611更專注的處理語音的識別/播報,無需針對要實現(xiàn)的產(chǎn)品應(yīng)用(例如空調(diào)、洗衣機邏輯功能)進(jìn)行定制化開發(fā),縮短了開發(fā)周期和聯(lián)調(diào)成本。
同時,主控MCU可以自主定制語音交互的方案,能與產(chǎn)品自身功能結(jié)合的更好,標(biāo)準(zhǔn)化接入方式避免來回修改語音芯片固件和協(xié)議,提升庫存通用性,減小生產(chǎn)和庫存管控成本,便于安裝和使用。
VOI611內(nèi)置寄存器表涵蓋了:設(shè)定喚醒時間、設(shè)定喚醒詞、設(shè)定播放音量、播放指定的提示音、讀取當(dāng)前識別結(jié)果、喚醒狀態(tài)等語音交互相關(guān)的配置參數(shù)。產(chǎn)品完整的語音交互方案設(shè)計均可由MCU進(jìn)行設(shè)定,配合示例代碼、寄存器表格、PC端調(diào)試工具,您可以快速出開發(fā)定制化的語音交互需求。
(如若不滿足您的需求,可以將您的需求提交給探境銷售或者技術(shù)支持人員)
2. 開發(fā)流程
常見的開發(fā)流程主要包括:獲取VOI611硬件和固件、調(diào)試工具驗證、MCU軟件開發(fā)、聯(lián)調(diào)對接等步驟。

3. 通訊接口和協(xié)議
3.1 通訊硬件連接
MCU通過下圖的方式和VOI611進(jìn)行連接:

- UART格式:波特率 9600,8位數(shù)據(jù)位,無校驗位,1位停止位。
- INT(可選):語音芯片識別結(jié)果輸出信號,當(dāng)
REG 0x0B
設(shè)置為 0 時使用該引腳,否則不使用該引腳。INT信號的空閑狀態(tài)為高電平,低電平表示REG 0x0A
中當(dāng)前有非零識別結(jié)果尚未讀取,讀取后恢復(fù)高電平(當(dāng)前無識別結(jié)果)。 - RST(可選):語音芯片復(fù)位引腳,低電平有效(推薦低脈沖寬度 > 1ms),外部需上拉處理。
VOI611 芯片所有 IO 邏輯電平為 0v / 3.3v。 如果您的 MCU IO 口邏輯電平為其他值,直接與芯片引腳相連時請務(wù)必加入電平轉(zhuǎn)換電路。模組 A/B 板載了電平轉(zhuǎn)換,4pin 串口可以支持 5V 邏輯電平。
3.2 串口數(shù)據(jù)幀格式
數(shù)據(jù)幀采用固定長度,固定標(biāo)記位,小端方式發(fā)送(若有多字節(jié)數(shù)據(jù),低字節(jié)在前),具體格式如下。
STX
表示數(shù)據(jù)幀的起始標(biāo)志,固定為0xFEA5
。LEN
表示有效載荷數(shù)據(jù)PAYLOAD
的字節(jié)長度,固定為0x0002
。SEQ
表示數(shù)據(jù)幀序列號,范圍 0 ~ 65535,每發(fā)送完一個消息自增 1。
(調(diào)試測試階段語音芯片不檢查
SEQ
,但考慮到協(xié)議標(biāo)準(zhǔn)、問題診斷、后續(xù)升級和協(xié)議擴展等方面,建議自增處理。)
SYS
為發(fā)起方,表示發(fā)送的方向。MSG
表示消息類型編號,具體含義見下文。PAYLOAD
表示本條數(shù)據(jù)幀所裝載的消息,固定為 2 個字節(jié),具體含義見下文。SUM
為校驗和,將前面 D0 ~ D9 所有字節(jié)相加取低8位。
注意:連續(xù)寫入/讀取數(shù)據(jù)幀時,MCU發(fā)送給語音芯片數(shù)據(jù)幀之間的間隔需 100ms 以上。
3.2.1 寫入寄存器
只需要一個步驟就可以寫入寄存器值到語音芯片,主控 MCU 指定 REG 和 VAL 參數(shù)后,按照如下格式發(fā)送串口幀即可。
如需校驗寫入結(jié)果是否成功,可以按下面步驟讀取寄存器值進(jìn)行檢查。語音芯片上電后載入默認(rèn)的寄存器值,重啟后需要重新配置,掉電不保存(除特殊說明外)。
3.2.2 讀取寄存器
讀取語音芯片當(dāng)前寄存器的值,需要兩個步驟。首先主控 MCU 將要讀取的 REG 發(fā)送給語音芯片,按如下格式發(fā)出。
語音芯片收到上方消息后,會在 100ms 內(nèi)通過串口消息回復(fù)該 REG 當(dāng)前的 VAL,解析格式如下,此時完成讀取操作。
若超時 150ms 未有回復(fù),視為異常情況,可嘗試重新發(fā)送讀取請求,或另作分析。

讀取過程可以參考上圖。
3.2.3 語音芯片上電通知
語音芯片上電初始化成功后,延遲1秒,發(fā)出以下串口指令。
MCU收到本條串口指令后,可以進(jìn)行寄存器的讀寫操作。
3.2.4 主動上報識別結(jié)果
當(dāng) REG 0x0B 設(shè)置為 1 時,語音芯片識別成功后會直接發(fā)出串口消息,識別結(jié)果不會存入 REG 0x0A。
這種方法適用于 MCU 不需要頻繁讀取語音芯片的場合,MCU 等待接收識別結(jié)果即可。
INDEX:命令詞索引值,在《方案規(guī)格書》的命令詞表中查詢。
關(guān)于“主動上報 / 不主動上報”、“主動播報 / 被動播報”、“喚醒邏輯”的關(guān)系在 8. 相關(guān)解釋 中描述。
產(chǎn)品的《方案規(guī)格書》中有對于本數(shù)據(jù)幀有專門說明的,則以《方案規(guī)格書》中內(nèi)容為準(zhǔn)。
4. 寄存器
4.1 寄存器描述
4.1.1 [REG 0x00] CHIP_TYPE_L
CHIP_TYPE_低8位,為芯片類型,是一個固定返回值,可用于檢查語音芯片是否上電初始化成功。
- 默認(rèn)值: 0x63
- 允許讀寫: R
4.1.2 [REG 0x01] CHIP_TYPE_H
CHIP_TYPE_高8位,為芯片類型,是一個固定返回值,可用于檢查語音芯片是否上電初始化成功。
- 默認(rèn)值: 0x02
- 允許讀寫: R
4.1.3 [REG 0x04] 復(fù)位寄存器表
RESET,用于復(fù)位寄存器表,寫入 0x01 使寄存器表中所有值恢復(fù)出廠默認(rèn)設(shè)置,寫入其他值無效。
- 合法值: 0x01
- 允許讀寫: W
4.1.4 [REG 0x05] 麥克風(fēng)增益
MIC_GAIN,用于設(shè)定麥克風(fēng)增益,保留,不要修改。
4.1.5 [REG 0x06] 音量調(diào)節(jié)
VOLUME_LEVEL,用于設(shè)置芯片DAC輸出信號的音量等級,這是一個全局參數(shù),數(shù)值越大聲音越大。(寫入后立刻生效)
- 默認(rèn)值: 0x19
- 合法值(DEC): 0 表示靜音;
- 合法值(DEC): 1 ~ 31 數(shù)值越大聲音越大;
- 允許讀寫: R/W
請注意:電路板上可能搭載了后端的 PA 功放(例如模組B/M7),這部分元器件的放大系數(shù)不在本寄存器控制范圍之內(nèi),通常是硬件參數(shù)決定。本寄存器僅影響語音芯片的DAC輸出。
4.1.6 [REG 0x07] 播放提示音
立即播放索引號提示音,該寄存器值代表《方案規(guī)格書》提示音播報表中索引號,寫入后立即停止正在播放的內(nèi)容,并開始播放新索引號的提示音。開始播放后將索引號裝載到 REG 0x08
。
- 合法值(DEC): 0 ~ 255 提示音索引號;
- 允許讀寫: W
MCU 可以在寫入這個寄存器后,讀取 REG 0x08
來確認(rèn)語音芯片是否開始播放對應(yīng)的提示音。
每次寫入操作語音芯片只會播放 1 次,未包含在《方案規(guī)格書》提示音播報表的索引號將會忽略。
4.1.7 [REG 0x08] 當(dāng)前提示音
當(dāng)前正在進(jìn)行播放的提示音索引號,該寄存器值代表《方案規(guī)格書》提示音播報表中索引號。
- 合法值(DEC): 0 表示當(dāng)前沒有正在播放的內(nèi)容(芯片 SPK 引腳無聲音輸出);
- 合法值(DEC): 1 ~ 255 當(dāng)前正在播放的提示音文件索引號;
- 允許讀寫: R
4.1.8 [REG 0x09] 語音識別開關(guān)
該寄存器用于控制開始/停止語音識別,寫入后立刻生效。(這是整個語音識別系統(tǒng)開/關(guān),不是控制喚醒狀態(tài)開/關(guān))
- 默認(rèn)值: 0x01
- 合法值: 0x01 表示語音芯片處于打開識別狀態(tài),識別成功后會產(chǎn)生識別結(jié)果;
- 合法值: 0x00 表示語音芯片處于關(guān)閉識別狀態(tài),停止上報任何識別結(jié)果;
- 允許讀寫: R/W
4.1.9 [REG 0x0A] 當(dāng)前識別結(jié)果
該寄存器僅當(dāng) [REG 0x0B] 設(shè)置為 0x00 時可用,其表示當(dāng)前的識別結(jié)果。
當(dāng)語音芯片識別到《方案規(guī)格書》命令詞列表中的某個詞后,會將該詞的索引號寫入到本寄存器,并等待 MCU 讀取。
- 合法值(DEC): 0 表示當(dāng)前無識別結(jié)果;
- 合法值(DEC): 1-255 當(dāng)前識別結(jié)果的詞索引號(不支持非喚醒狀態(tài)下識別非喚醒詞);
- 允許讀寫: R
當(dāng)本寄存器值為非 0 時,語音芯片的 INT 引腳將輸出低電平。進(jìn)行讀取操作完成后,本寄存器值自動復(fù)位為 0,且語音芯片的 INT 引腳輸出低電平。
當(dāng)有新的識別結(jié)果產(chǎn)生時,會覆蓋之前未讀取的內(nèi)容。
4.1.10 [REG 0x0B] 主動上報開關(guān)
該寄存器用于設(shè)置當(dāng)語音芯片識別到《方案規(guī)格書》命令詞列表中的某個詞后,如何將識別結(jié)果從語音芯片傳遞給主控 MCU。VOI611提供兩種方式:主動上報、不主動上報(由MCU發(fā)起讀?。?。寫入后立刻生效,并在下一個識別結(jié)果產(chǎn)生時得以體現(xiàn)。
- 默認(rèn)值: 0x01
- 合法值: 0x01 主動上報,語音芯片識別完成后會直接發(fā)出串口消息,識別結(jié)果不會存入 REG 0x0A;(主動上報格式,參考 2.2.4 主動上報識別結(jié)果。不支持非喚醒狀態(tài)下識別非喚醒詞);
- 合法值: 0x00 表示不主動上報,識別結(jié)果存入 REG 0x0A,用戶必須從中讀取識別結(jié)果;
- 允許讀寫: R/W
關(guān)于“主動上報 / 不主動上報”、“主動播報 / 被動播報”、“喚醒邏輯”的關(guān)系在 8. 相關(guān)解釋 中描述。
4.1.11 [REG 0x10] 默認(rèn)喚醒時間_低8位
該寄存器用于存儲默認(rèn)的喚醒時間設(shè)定低 8 位。與 REG 0x11 構(gòu)成默認(rèn)喚醒時間(2 字節(jié)),范圍 0x0000 ~ 0xffff 秒。
當(dāng)“喚醒-事件”發(fā)生后,語音芯片裝載默認(rèn)喚醒時間到 REG 0x12:0x13。
- 默認(rèn)值(DEC): 20
- 合法值(DEC): 0 ~ 255 默認(rèn)的喚醒時間,單位為秒;
- 允許讀寫: R/W
4.1.12 [REG 0x11] 默認(rèn)喚醒時間_高8位
該寄存器用于存儲默認(rèn)的喚醒時間設(shè)定高 8 位。與 REG 0x10 構(gòu)成默認(rèn)喚醒時間(2 字節(jié)),范圍 0x0000 ~ 0xffff 秒。
當(dāng)“喚醒-事件”發(fā)生后,語音芯片裝載默認(rèn)喚醒時間到 REG 0x12:0x13。
- 默認(rèn)值(DEC): 0
- 合法值(DEC): 0 ~ 255 默認(rèn)的喚醒時間,單位為 256 秒;
- 允許讀寫: R/W
4.1.13 [REG 0x12] 當(dāng)前剩余喚醒時間_低8位
該寄存器用于存儲當(dāng)前剩余的喚醒時間值低 8 位。與 REG 0x13 構(gòu)成當(dāng)前剩余喚醒時間(2 字節(jié)),范圍 0x0000 ~ 0xffff 秒。
當(dāng)前剩余喚醒時間相當(dāng)于一個倒計時器,會隨時間遞減,直至為 0 時退出喚醒(REG 0x14 被清零)。
- 默認(rèn)值(DEC): 0
- 合法值(DEC): 0 ~ 255 剩余喚醒時間,單位為秒;
- 允許讀寫: R
4.1.14 [REG 0x13] 當(dāng)前剩余喚醒時間_高8位
該寄存器用于存儲當(dāng)前剩余的喚醒時間值高 8 位。與 REG 0x12 構(gòu)成當(dāng)前剩余喚醒時間(2 字節(jié)),范圍 0x0000 ~ 0xffff 秒。
當(dāng)前剩余喚醒時間相當(dāng)于一個倒計時器,會隨時間遞減,直至為 0 時退出喚醒(REG 0x14 被清零)。
- 默認(rèn)值(DEC): 0
- 合法值(DEC): 0 ~ 255 剩余喚醒時間,單位為 256 秒;
- 允許讀寫: R
4.1.15 [REG 0x14] 喚醒狀態(tài)
該寄存器用于表示當(dāng)前語音芯片的喚醒狀態(tài),寫入 0x00 至本寄存器,將立刻退出喚醒,并把 REG 0x12:0x13 清零;寫入 0x01 至本寄存器,將立刻觸發(fā)“喚醒-事件”(不論當(dāng)前是處于非喚醒狀態(tài) or 喚醒狀態(tài)),載入 REG 0x10:0x11 至 REG 0x12:0x13 并啟動剩余喚醒時間的倒計時;
- 默認(rèn)值: 0x00
- 合法值: 0x00,表示當(dāng)前處于非喚醒狀態(tài);
- 合法值: 0x01,表示當(dāng)前處于喚醒狀態(tài);
- 允許讀寫: R/W
(寫入后立刻生效。)
關(guān)于“喚醒邏輯”的說明在 8. 相關(guān)解釋 中描述。
4.1.16 [REG 0x15] 喚醒保持使能
該寄存器用于設(shè)定語音芯片是否通過喚醒倒計時來退出喚醒,如果打開該功能,語音芯片將長期保持喚醒狀態(tài)。(寫入后立刻生效,若當(dāng)前處于非喚醒狀態(tài),則下一次進(jìn)入喚醒時生效)
- 默認(rèn)值: 0x00
- 合法值: 0x00,語音芯片通過 REG 0x12:0x13 超時來決定是否退出喚醒狀態(tài);
- 合法值: 0x01,語音芯片一旦進(jìn)入喚醒將不會不超時,不會主動退出喚醒狀態(tài)(僅接收主控 MCU 指令退出喚醒);
- 允許讀寫: R/W
若當(dāng)前語音芯片已處于喚醒狀態(tài)(REG 0x14 為 0x01),且本寄存器值為 0x01,此時寫入 0x00 至本寄存器,會立即退出喚醒(REG 0x14 被清零)。
4.1.17 [REG 0x16] 允許通過喚醒詞進(jìn)入喚醒狀態(tài)
該寄存器用于設(shè)定語音芯片是否通喚醒詞來進(jìn)入喚醒狀態(tài),如果關(guān)閉該功能,語音芯片將無法在識別到喚醒詞后直接產(chǎn)生“喚醒-事件”(進(jìn)入喚醒狀態(tài)),只能通過外部 MCU 的指令進(jìn)入喚醒。(寫入后立刻生效。下一次識別到喚醒詞后得以體現(xiàn))
- 默認(rèn)值: 0x01
- 合法值: 0x00,出現(xiàn)識別結(jié)果為喚醒詞,語音芯片不會直接產(chǎn)生“喚醒-事件”(不會直接進(jìn)入喚醒狀態(tài))。此模式下僅接收外部觸發(fā)的“喚醒-事件”,用戶可寫入 REG 0x14 進(jìn)入喚醒。(也就是說“喚醒-事件”完全由主控 MCU 控制);
- 合法值: 0x01,出現(xiàn)識別結(jié)果為喚醒詞,語音芯片將直接產(chǎn)生“喚醒-事件”(也可由主控 MCU 控制,兩種方法共存);
- 允許讀寫: R/W
4.1.18 [REG 0x17] 允許通過非喚醒詞延長喚醒時間
語音芯片處于喚醒狀態(tài)時,識別到命令詞后,對于延長喚醒時間處理有常見的 3 種方式:
- 【單輪對話】識別到命令詞,將當(dāng)前剩余喚醒時間清零,立即退出喚醒。
- 【多輪對話-延長】識別到命令詞,延長當(dāng)前剩余喚醒時間(通常是重置喚醒倒計時)。
- 【多輪對話-不延長】識別到命令詞,不對喚醒時間進(jìn)行操作。
本寄存器用于設(shè)定【多輪對話】方式下,識別到命令詞后是否【延長】當(dāng)前剩余喚醒時間(重置喚醒倒計時)。
- 默認(rèn)值: 0x01
- 合法值: 0x00,出現(xiàn)識別結(jié)果為非喚醒詞,語音芯片不會調(diào)整剩余喚醒時間,REG 0x12:0x13 維持原規(guī)則動作;
- 合法值: 0x01,出現(xiàn)識別結(jié)果為非喚醒詞,語音芯片將會將剩余喚醒時間 REG 0x12:0x13 延長至默認(rèn)喚醒時間 REG 0x10:0x11(即重新喚醒計時);
- 允許讀寫: R/W
4.1.19 [REG 0x20] 當(dāng)前應(yīng)用場景-索引號
該寄存器用于設(shè)置語音芯片的應(yīng)用場景,寫入正確的索引號將立即生效。若場景索引號不存在或無效,將寫入失敗且不會變更本寄存器的值。(寫入后保存到 Flash,掉電不丟失)
用戶可以在執(zhí)行寫入后,讀取本寄存器的值進(jìn)行檢驗。
- 默認(rèn)值: 詳見《方案規(guī)格書》應(yīng)用場景表
- 合法值: 0x00,生產(chǎn)測試使用,保留;
- 合法值: 應(yīng)用場景索引號,用于標(biāo)記《應(yīng)用場景表》中指定的場景,詳見《方案規(guī)格書》應(yīng)用場景表;
- 允許讀寫: R/W
4.1.20 [REG 0x21] 喚醒詞1-索引號
通常《方案規(guī)格書》命令詞列表列出了模型(weight_iet_upgrade.bin)中所有可以被識別的孤立詞,這部分詞可根據(jù)語音交互邏輯分為兩類:
- 【喚醒詞】在非喚醒狀態(tài)和喚醒狀態(tài)下均可識別,識別后進(jìn)入喚醒狀態(tài)。
- 【命令詞】僅在喚醒狀態(tài)下識別,在非喚醒狀態(tài)下不會被識別。
該寄存器用于標(biāo)記《方案規(guī)格書》命令詞列表中【喚醒詞 1】的索引號。當(dāng)該寄存器值為非零時,語音芯片識別到《方案規(guī)格書》命令詞列表中的某個詞后,將該詞索引號與本寄存器值進(jìn)行比較,若相同則視為識別到【喚醒詞 1】;若與 REG 0x21:0x23 均不相同,則視為【命令詞】。
推薦在語音芯片上電后,初始配置階段,將需要啟用的【喚醒詞】索引號填入 REG 0x21:0x23。
- 默認(rèn)值(DEC): 2
- 合法值(DEC): 0,表示空,沒有第 1 個喚醒詞;
- 合法值(DEC): 1 ~ 255,《方案規(guī)格書》命令詞列表中的索引號;
- 允許讀寫: R/W
4.1.21 [REG 0x22] 喚醒詞2-索引號
該寄存器用于標(biāo)記《方案規(guī)格書》命令詞列表中【喚醒詞 2】的索引號。當(dāng)該寄存器值為非零時,語音芯片識別到《方案規(guī)格書》命令詞列表中的某個詞后,將該詞索引號與本寄存器值進(jìn)行比較,若相同則視為識別到【喚醒詞 2】;若與 REG 0x21:0x23 均不相同,則視為【命令詞】。
推薦在語音芯片上電后,初始配置階段,將需要啟用的【喚醒詞】索引號填入 REG 0x21:0x23。
- 默認(rèn)值(DEC): 0
- 合法值(DEC): 0,表示空,沒有第 2 個喚醒詞;
- 合法值(DEC): 1 ~ 255,《方案規(guī)格書》命令詞列表中的索引號;
- 允許讀寫: R/W
4.1.22 [REG 0x23] 喚醒詞3-索引號
該寄存器用于標(biāo)記《方案規(guī)格書》命令詞列表中【喚醒詞 3】的索引號。當(dāng)該寄存器值為非零時,語音芯片識別到《方案規(guī)格書》命令詞列表中的某個詞后,將該詞索引號與本寄存器值進(jìn)行比較,若相同則視為識別到【喚醒詞 3】;若與 REG 0x21:0x23 均不相同,則視為【命令詞】。
推薦在語音芯片上電后,初始配置階段,將需要啟用的【喚醒詞】索引號填入 REG 0x21:0x23。
- 默認(rèn)值(DEC): 0
- 合法值(DEC): 0,表示空,沒有第 3 個喚醒詞;
- 合法值(DEC): 1 ~ 255,《方案規(guī)格書》命令詞列表中的索引號;
- 允許讀寫: R/W
5. 寄存器調(diào)試工具(上位機)
開發(fā)者可以直接在圖形界面,控制VOI611芯片。

點擊這里下載:reg_tool_ver2.1_20210408.exe
使用方法:
- 將語音模塊通過串口連接到 pc,檢查 com 端口號。
- 啟動 voi611_reg_tool 軟件,選擇端口號,波特率設(shè)置為 9600(默認(rèn)),點擊“打開串口”。
- 點擊界面右側(cè)“讀取全部”按鈕,觀察讀出寄存器值。
- 點擊界面下方的播放提示音按鈕“1”,觀察語音模塊是否正常播報。
常見錯誤:
- 工具無法啟動:建議在 Windows 10 64bit 系統(tǒng)上運行。
- 無法打開端口:調(diào)試工具無法訪問串口設(shè)備,可能是 com 端口號設(shè)置錯誤,或者有其他程序占用了該端口。
- 讀取 / 寫入失敗:可能是串口的 tx / rx 連接錯誤,或芯片固件不支持寄存器協(xié)議,或電源異常。
6. 典型應(yīng)用流程
6.1 識別-播報(INT信號、不主動上報)
具體過程如下圖所示:

本流程需要使用 INT 引腳,可以不使用 MCU 串口中斷功能。主控 MCU 周期性查詢 INT 引腳電平信號,當(dāng)有識別結(jié)果產(chǎn)生時,MCU 發(fā)起查詢 REG 指令獲取當(dāng)前識別結(jié)果,并按產(chǎn)品功能邏輯將要播放的提示音寫入到 VOI611 中,依次完成識別-播報的語音交互。
6.2 識別-播報(無INT信號、輪詢心跳)
本流程省略了對 INT 引腳的判斷,主控 MCU 周期性讀取 REG 0x0A 的值,非零代表識別結(jié)果 ID,為零則表示無識別結(jié)果,兩種回復(fù)都被認(rèn)為讀取操作成功(其他回復(fù)或無回復(fù)被視為異常)。
具體過程如下圖所示:

心跳包是指將自己的狀態(tài)通知對方,表示自己處于正常工作狀態(tài)。考慮到產(chǎn)片端主控 MCU 對心跳周期和狀態(tài)數(shù)據(jù)類目的多樣性,語音芯片的心跳包實現(xiàn)方式為:主控 MCU 對語音芯片的讀操作,若讀取成功,則說明語音芯片當(dāng)前系統(tǒng)處于正常運行狀態(tài)。
對于讀取語音芯片操作的多次失?。ūM管概率很低,但不排除一些外部原因),主控 MCU 可以通過 RST 引腳傳遞復(fù)位信號,控制語音芯片重啟。
7. 示例程序
7.1 十分鐘快速上手
如下是讀寫操作簡單示例。
static uint16_t seq = 0;
uint8_t voi611_reg_write(uint8_t reg, uint8_t val, uint8_t msg)
{
// 1. 準(zhǔn)備發(fā)送的數(shù)據(jù)幀
uint8_t buf[11] = {0}
buf[0] = 0xA5; // STX
buf[1] = 0xFE; // STX
buf[2] = 0x02; // LEN
buf[3] = 0x00; // LEN
buf[4] = (uint8_t)(0x00ff & seq); // SEQ
buf[5] = (uint8_t)(0x00ff & (seq >> 8)); // SEQ
buf[6] = 0x01; // SYS
buf[7] = msg; // MSG
buf[8] = reg; // REG
buf[9] = val; // VAL
uint8_t i, sum = 0;
for(i = 0; i < 10; i++)
{
sum += buf[i];
}
buf[10] = sum; // SUM
seq++; // SEQ 自增
// 2. 以下為 MCU 串口發(fā)送 api
uint8_t ret = uart_write(buf, 11);
return ret;
}
uint8_t voi611_reg_read(uint8_t reg, uint8_t *val)
{
// 1. 先發(fā)送讀取 REG 指令
voi611_reg_write(reg, 0x00, 0xF1);
// 2. 以下為等待 VOI611 回復(fù)(阻塞式),或開發(fā)者自行實現(xiàn)接收,通過 3. 進(jìn)行解析
uint8_t ret, val;
uint8_t buf[11];
uint32_t timeout_ms = 150;
ret = uart_read_with_timeout(buf, 11, timeout_ms);
// 2.1 讀取 11 個字節(jié)超時,失敗退出
if (ret == 0x00)
{
return 0x00;
}
// 3. 讀取成功,校驗和解析
if(buf[0] == 0xA5 && buf[1] == 0xFE && // STX
buf[2] == 0x02 && buf[3] == 0x00 && // LEN
buf[6] == 0x00 && buf[7] == 0xFF && // SYS, MSG
buf[8] == reg) // REG
{
// 3.1 檢查校驗和
uint8_t i, sum = 0;
for(i = 0; i < 10; i++)
{
sum += buf[i];
}
if (buf[10] == sum)
{
// 校驗和正確,返回結(jié)果
*val = buf[9]; // VAL
return 0x01;
}
// 校驗和錯誤
}
// 非法幀
return 0x00;
}
典型應(yīng)用代碼(最小化)如下。
uint8_t voi611_init_reg()
{
uint8_t ret, val;
// 1. 先檢查連接是否正常
ret = voi611_reg_read(0x00, &val);
if (ret != 0x00 && val == 0x63)
{
; // 讀取型號 OK
}
else
{
return 0x00; // 讀取型號失敗,可能是硬件連接錯誤或者型號不對
}
ret = voi611_reg_read(0x01, &val);
if (ret != 0x00 && val == 0x02)
{
; // 讀取型號 OK
}
else
{
return 0x00; // 讀取型號失敗,可能是硬件連接錯誤或者型號不對
}
// 2. 寫入需要配置的寄存器和值
voi611_reg_write(0x04, 0x01, 0xF0); // 復(fù)位寄存器表
voi611_reg_write(0x0B, 0x00, 0xF0); // 設(shè)置為識別結(jié)果不主動上報,MCU 自行查詢
voi611_reg_write(0x20, 0x05, 0xF0); // 設(shè)置選擇應(yīng)用場景索引號
voi611_reg_write(0x07, 0x01, 0xF0); // 播放上電歡迎語的提示音
// 3. 讀取并校驗寫入成功
// ……
return 0x01;
}
void main()
{
uint8_t ret, val;
// 1. 初始化VOI611的寄存器
voi611_init_reg();
// 2. 主循環(huán)
while(1)
{
// 每隔 200ms,讀取識別結(jié)果,0表示當(dāng)前無識別結(jié)果
ret = voi611_reg_read(0x0A, &val);
if (ret == 0x00 || val == 0x00)
{
// 超時或者無識別結(jié)果,本次查詢無語音動作
// continue;
}
else
{
switch(val)
{
case (1):
// 打開燈光
app_light_on();
// 播放提示音:開燈
voi611_reg_write(0x07, 0x03, 0xF0);
break;
case (2):
// 關(guān)閉燈光
app_light_off();
// 播放提示音:關(guān)燈
voi611_reg_write(0x07, 0x04, 0xF0);
break;
case (3):
case (4):
// 屏蔽這些命令詞3和4,不響應(yīng)識別結(jié)果
break;
default:
// 屏蔽其他的識別結(jié)果
break;
}
}
// 其他程序
// ...
}
}
8. 相關(guān)解釋
關(guān)于“主動上報 / 不主動上報”、“主動播報 / 被動播報”、“喚醒邏輯”的關(guān)系:
“主動上報 / 不主動上報”與“喚醒邏輯”并無關(guān)聯(lián),這兩種方式僅區(qū)別于如何將識別結(jié)果從語音芯片傳遞給主控 MCU。
“主動上報 / 不主動上報”的設(shè)定與“主動播報 / 被動播報”并無關(guān)聯(lián),播報方式僅代表語音芯片完成識別后是直接播放提示音(主動),還是由MCU控制播放提示音(被動),通常在應(yīng)用場景號中進(jìn)行選擇。(一般來說,不主動上報識別結(jié)果時,識別-播報的交互邏輯也是交由MCU處理,此時語音模塊應(yīng)選擇為被動播報)
關(guān)于“喚醒邏輯”的說明:
通常情況下語音芯片應(yīng)用的喚醒邏輯有兩種狀態(tài):
- 非喚醒狀態(tài)(僅監(jiān)聽喚醒詞)
- 喚醒狀態(tài)(監(jiān)聽喚醒詞、命令詞)
其中,從非喚醒狀態(tài)進(jìn)入喚醒狀態(tài),稱之為“喚醒-事件”,“喚醒-事件”只能通過 2 種方式產(chǎn)生:任何情況下 MCU 寫入 1 至 REG 0x14;或者語音芯片識別到在 REG 0x21:0x23 標(biāo)記為喚醒詞的命令詞 ID,且 REG 0x16 設(shè)置為 1。
喚醒邏輯的設(shè)定,是為了減少誤操作的發(fā)生。例如語音智能燈產(chǎn)品,默認(rèn)(非喚醒狀態(tài))僅監(jiān)聽喚醒詞“你好小白”,進(jìn)入喚醒狀態(tài)后可以識別其他命令詞“打開燈光、調(diào)亮一點”等等。
如果在非喚醒狀態(tài)下識別《命令詞列表》中所有的詞匯并執(zhí)行動作,那么會使誤操作的概率上升,造成用戶困擾(現(xiàn)階段語音識別無法杜絕誤識別,但可以通過此方法減小概率)。
通常,除在 REG 0x21:0x23 中被標(biāo)記為喚醒詞的命令詞以外,剩余《命令詞列表》的詞均為非喚醒詞。