以下作品由安信可社區用戶
lazy制作
簡介
DY-SV17F 一款智能語音模塊,集成 IO 分段觸發,UART 串口控制,ONE_line 單總線串口控制,標準 MP3 等 7 種工作模式;板載 5W D 類功放,可直接驅動 4Ω,3~5W 喇叭;支持 MP3,WAV 解碼格式,板載 32Mbit(4MByte)flash 存儲音頻文件,可通過 USB 數據線連接電腦更新音頻文件。
1、支持 MP3、WAV 解碼格式。
2、支持采樣率
(KHz):8/11.025/12/16/22.05/24/32/44.1/48。
3、24 位 DAC 輸出,動態范圍支持 90dB,信噪比支持 85dB。
4、板載 32Mbit(4MByte)flash 存儲,可通過 USB 數據線連接電腦更新音頻文件。。
5、自帶 5W D 類功放,可直接驅動 4Ω,3~5W 喇叭。
6、UART 串口控制語音播報功能,可控制播放,暫停,選曲,音量加減等功能,最大選曲 65535 首曲目,波特率 9600 bps。
7、支持 IO 觸發播放功能,8 個 IO 口單獨觸發 8 首曲目或 8 個 IO 口組合觸發 255 首曲目。
8、支持 One_line 單總線串口控制,可控制播放,暫停,選曲,音量加減等功能。
9、支持 3 個配置 IO 進行多達 7 種工作模式選擇。
模塊接口及功能定義
引腳定義
IO 輸入輸出特性
這個模塊支持的工作模式比較多,最好上手的還是 UART 串口模式通信了。
DY-SV17F 路徑格式說明
DY-SV17F 模塊支持中英文路徑指定播放和插播功能,路徑使用需要按以下格式
1、指定文件夾路徑
/XXX*/*MP3
2、指定根目錄文件名播放
/YYY*MP3
3、指定文件夾下文件名播放
/XXX*/YYY*MP3,
說明:
1、路徑 以”/”開頭
2、XXX 代表文件夾的名稱,YYY 代表文件名,可以中文或英文,或中英文組合,XXX 的
長度小于 8,YYY 的長度小于 8,文件夾名稱沒有限制,所有字母全部要求大寫,不管文件
夾或文件名是否為大寫,取前面幾個能區分的字母或漢字,長度不能超過 8 個字節。比如有
兩個文件夾為 002ABC 和 002DFG,為了能區分要取 002A 和 002D。
3、一個漢字占用兩個字節,一個字母為一個字節。
4、播放文件夾中的文件:/DY*/00001*MP3
5、播放文件夾中的文件:/DY*/00255*MP3
6、播放文件夾中的文件:/DY*/65535*MP3
7、播放根目錄中的文件:/00001*MP3
8、播放根目錄中的文件:/00255*MP3
9、播放根目錄中的文件:/65535*MP3
10、使用專有串口調試助手進行路徑播放測試如下圖
本篇文主要講解的就是 UART 串口模式。
硬件配置說明
通信格式
采用全雙工串口通信;
波特率為 9600,數據位:8 ,停止位 1 位,檢驗位 N。
起始碼-指令類型-數據長度(n)-數據 1-數據 n-和檢驗(SM)
指令碼 :固定為 AA。
指令類型 : 用來區分指令類型。
數據長度:指令中的數據的字節數。
數據 :指令中的相關數據,當數據長度為 1 時,表示只有 CMD,沒有數據位。
檢驗 :為之前所有字節之和的低 8 位,即起始碼到數據相加后取低 8 位。
數據格式:發送的數據或命令,高 8 位數據在前,低 8 位在后。
通信協議
以下是本芯片返回和能識別的數據定義。
1. 播放狀態定義 :系統上電處于停止狀態。
00(停止) 01(播放) 02(暫停)
2. 盤符定義: 切換盤符后處于停止狀態。
USB:00 SD:01 FLASH:02 NO_DEVICE:FF
3. 音量:音量總共為 31 級,0-30 級,上電默認為 20 級。
4. 播放模式定義:上電默認為單曲停止。
全盤循環(00):按順序播放全盤曲目,播放完后循環播放。
單曲循環(01):一直循環播放當前曲目。
單曲停止(02):播放完當前曲目一次停止。
全盤隨機(03):隨機播放盤符內曲目。
目錄循環(04):按順序播放當前文件夾內曲目,播放完后循環播放,目錄不包含子目錄。
目錄隨機(05): 在當前目錄內隨機播放,目錄不包含子目錄。
目錄順序播放(06):按順序播放當前文件夾內曲目,播放完后停止,目錄不包含子目錄。
順序播放(07):按順序播放全盤曲目,播放完后停止。
5.EQ 定義:上電默認 EQ 為 NORMAL(00)。
NORMAL(00) POP(01) ROCK(02) JAZZ(03) CLASSIC(04)
6. 組合播放定義:組合播放是按文件名來組合,文件要求存儲在“XY”文件夾下,可以把要組合的文件名稱更改為兩個字節的名稱,一般建議用數字表示。如: 01.mp3,02.mp3,也可以用兩個字母或一個漢字命名。
sv17f_uart.h
/**
* @file uart.h
* @author your name ([email]you@domain.com[/email])
* @brief
* @version 0.1
* @date 2023-07-24
*
* @copyright Copyright (c) 2023
*
*/
#ifndef _sv17f_UART_H_
#define _sv17f_UART_H_
/*
指令碼:固定AA
指令類型:用來區分指令類型
數據長度:指令中的數據字節數
數據:指令中的相關數據,當數據長度為1時,表示只有CMD,沒有數據位
和校驗:為之前所有字節之和的低8位,即起始碼到數據相加后取低8位。
數據格式:發送的數據或指令高8位數據在前,低8位在后。
*/
//通信協議
//1、播放狀態定義:系統上電處于停止狀態
#define STATUS_STOP 0x00 //停止
#define STATUS_PLAY 0x01 //播放
#define STATUS_PAUSE 0x02 //暫停
//2、盤符定義:切換盤符后處于停止狀態
#define PAN_USB 0x00 //USB
#define PAN_SD 0x01 //SD
#define PAN_FLASH 0x02 //FLASH
#define PAN_NO_DEVICE 0xFF //NO_DEVICE
//3、音量:音量總共31級,0-31級,上電默認為20級
#define VOLUME_LEVEL_0 0
#define VOLUME_LEVEL_1 1
#define VOLUME_LEVEL_2 2
#define VOLUME_LEVEL_3 3
#define VOLUME_LEVEL_4 4
#define VOLUME_LEVEL_5 5
#define VOLUME_LEVEL_6 6
#define VOLUME_LEVEL_7 7
#define VOLUME_LEVEL_8 8
#define VOLUME_LEVEL_9 9
#define VOLUME_LEVEL_10 10
#define VOLUME_LEVEL_11 11
#define VOLUME_LEVEL_12 12
#define VOLUME_LEVEL_13 13
#define VOLUME_LEVEL_14 14
#define VOLUME_LEVEL_15 15
#define VOLUME_LEVEL_16 16
#define VOLUME_LEVEL_17 17
#define VOLUME_LEVEL_18 18
#define VOLUME_LEVEL_19 19
#define VOLUME_LEVEL_20 20
#define VOLUME_LEVEL_21 21
#define VOLUME_LEVEL_22 22
#define VOLUME_LEVEL_23 23
#define VOLUME_LEVEL_24 24
#define VOLUME_LEVEL_25 25
#define VOLUME_LEVEL_26 26
#define VOLUME_LEVEL_27 27
#define VOLUME_LEVEL_28 28
#define VOLUME_LEVEL_29 29
#define VOLUME_LEVEL_30 30
// 4、播放模式定義:商店默認為單曲停止
#define LOOP_MODE_ALL 0x00 //全盤循環:按順序播放全盤曲目,播放完后循環播放
#define LOOP_MODE_SINGLE 0x01 //單曲循環:一直循環播放當前曲目
#define LOOP_MODE_SINGLE_STOP 0x02 //單曲停止:播放完當前曲目一次停止
#define LOOP_MODE_ALL_RANDOM 0x03 //全盤隨機:隨機播放盤符內曲目
#define LOOP_MODE_DIR 0x04 //目錄循環:按順序播放當前文件夾內曲目,播放完后循環播放,目錄不包含子目錄
#define LOOP_MODE_DIR_RANDOM 0x05 //目錄隨機:在當前目錄內隨機播放,目錄不包含子目錄
#define LOOP_MODE_DIR_SEQUENCE 0x06 //目錄順序播放:按順序播放當前文件夾內曲目,播放完后停止,目錄不包含子目錄
#define LOOP_MODE_ALL_SEQUENCE_STOP 0x07 //順序播放按順序播放全盤曲目,播放完后停止
// 5、EQ定義:上電默認EQ為NORMAL(00)
#define EQ_NOMARL 0x00 // NOMARL
#define EQ_POP 0x01 // POP
#define EQ_ROCK 0x02 // ROCK
#define EQ_JAZZ 0x03 // JAZZ
#define EQ_CLASSIC 0x04 // CLASSIC
/*
6、組合播放定義:組合播放是按文件名來組合,文件要求存儲在“XY”文件夾下,可以巴瑤族喝的文件名稱更改為兩個字節的名稱,一般建議用數字表示。如:01.MP3,02.mp3,也可以用兩個字母或漢字命名
*/
/**
* @brief
* @param volume 音量
* @param loop_mode 循環模式
* @param eq 音樂風格
* @param pan 盤符指定路徑
*/
struct sv17f_config_s {
uint32_t volume;
uint8_t loop_mode;
uint8_t eq;
uint8_t pan;
};
void sv17f_uart_task(void* arg);
void sv17f_init(const struct sv17f_config_s *config);
/*計算校驗碼*/
uint8_t check_sum(uint8_t *ck_buf, uint8_t size);
//音量設置 0xAA, 0x13, 0x01, 音量, SM
int sv17f_set_vol(uint8_t vol);
//設置循環模式 0xAA, 0x18, 0x01, 循環模式, SM
int sv17f_set_loop(uint8_t loop);
//設置循環次數 0xAA, 0x19, 0x02, 次數高, 次數低, SM
int sv17f_set_count(uint8_t count);
//EQ設置 0xAA, 0x1A, 0x01, EQ, SM
int sv17f_set_eq(uint8_t eq);
//指定曲目 0xAA, 0x07, 0x02, 曲目高, 曲目低, SM
int sv17f_set_sound(uint8_t sound);
//指定盤符指定路徑 0xAA, 0x08, 長度, 盤符, 路徑, SM
int sv17f_set_pan(uint8_t pan);
//切換到指定盤符徑 0xAA, 0x0B, 0x01, 盤符, SM
int sv17f_set_sel_pan(uint8_t pan);
//指定曲目播放 0xAA, 0x16, 0x03, 盤符, 曲目高, 曲目低, SM
int sv17f_set_sel_sound_paly(uint8_t pan, uint16_t sound);
//指定路徑播放 0xAA, 0x17, 長度, 盤符, 路徑, SM
int sv17f_set_sel_dir_paly(uint8_t pan, uint8_t dir);
//選曲不播放 0xAA, 0x1F, 0x02, 曲目高, 曲目低, SM
int sv17f_check_sel_sound(uint16_t sound);
// 查詢播放狀態
uint8_t sv17f_play_status(uint16_t timeout);
// 查詢當前在線盤符
uint8_t sv17f_online_pan(uint16_t timeout);
// 查詢當前播放盤符
uint8_t sv17f_use_pan(uint16_t timeout);
// 查詢總曲目
uint8_t sv17f_sum_sound(uint16_t timeout);
// 查詢當前曲目
uint8_t sv17f_cur_sound(uint16_t timeout);
// 查詢文件夾目錄曲目
uint16_t sv17f_dir_sound(uint16_t timeout);
// 查詢文件夾目錄總曲目
uint16_t sv17f_sum_dir_sound(uint16_t timeout);
// 播放
int sv17f_play();
// 暫停
int sv17f_pasue();
// 停止
int sv17f_stop();
// 上一曲
int sv17f_sound_up();
// 下一曲
int sv17f_sound_down();
// 音量加
int sv17f_vol_up();
// 音量減
int sv17f_vol_down();
// 上一文件目錄
int sv17f_dir_up();
// 下一文件目錄
int sv17f_dir_down();
// 結束播放
int sv17f_release();
#endif
sv17f_uart.c
/**
* @file uart.c
* @author your name ([email]you@domain.com[/email])
* @brief
* @version 0.1
* @date 2023-07-24
*
* @copyright Copyright (c) 2023
*
*/
#include
#include
#include
#include
#include
#include
#include
#include "bflb_uart.h"
#include "bflb_gpio.h"
#include "sv17f_uart.h"
#include "log.h"
/*控制指令*/
/* 播放*/
uint8_t CMD_PLAY[4] = { 0xAA, 0x02, 0x00, 0xAC };
/* 暫停*/
uint8_t CMD_PAUSE[4] = { 0xAA, 0x03, 0x00, 0xAD };
/* 停止*/
uint8_t CMD_STOP[4] = { 0xAA, 0x04, 0x00, 0xAE };
/* 上一曲*/
uint8_t CMD_SOUND_UP[4] = { 0xAA, 0x05, 0x00, 0xAF };
/* 下一曲*/
uint8_t CMD_SOUND_DOWN[4] = { 0xAA, 0x06, 0x00, 0xB0 };
/* 音量加*/
uint8_t CMD_VOL_UP[4] = { 0xAA, 0x14, 0x00, 0xBE };
/* 音量減*/
uint8_t CMD_VOL_DOWN[4] = { 0xAA, 0x15, 0x00, 0xBF };
/* 上一文件目錄*/
uint8_t CMD_DIR_UP[4] = { 0xAA, 0x0E, 0x00, 0xB8 };
/* 下一文件目錄*/
uint8_t CMD_DIR_DOWN[4] = { 0xAA, 0x0F, 0x00, 0xB9 };
/* 結束播放*/
uint8_t CMD_RELEASE[4] = { 0xAA, 0x10, 0x00, 0xBA };
/*查詢指令*/
/*查詢播放狀態 返回:AA 01 01 播放狀態 SM*/
uint8_t CMD_QUERY_STATUS[4] = { 0xAA, 0x01, 0x00, 0xAB };
/*查詢當前在線盤符 返回:AA 09 01 盤符 SM*/
uint8_t CMD_QUERY_PAN[4] = { 0xAA, 0x09, 0x00, 0xB3 };
/*查詢當前播放盤符 返回:AA 0A 01 盤符 SM*/
uint8_t CMD_QUERY_PLAY_PAN[4] = { 0xAA, 0x0A, 0x00, 0xB4 };
/*查詢總曲目 返回:AA 0C 02 總曲目高 總曲目低 SM*/
uint8_t CMD_QUERY_SUM_SOUND[4] = { 0xAA, 0x0C, 0x00, 0xB6 };
/*查詢當前曲目 返回:AA 0D 02 曲目高 曲目低 SM*/
uint8_t CMD_QUERY_CUR_SOUND[4] = { 0xAA, 0x0D, 0x00, 0xB7 };
/*查詢文件夾目錄曲目 返回:AA 11 02 曲目高 曲目低 SM*/
uint8_t CMD_QUERY_DIR_SOUND[4] = { 0xAA, 0x11, 0x00, 0xBB };
/*查詢文件夾目錄總曲目 返回:AA 12 02 曲目高 曲目低 SM*/
uint8_t CMD_QUERY_SUM_DIR_SOUND[4] = { 0xAA, 0x12, 0x00, 0xBC };
/*設置指令 */
/*音量設置 0xAA, 0x13, 0x01, 音量, SM*/
uint8_t VOL_SET[5] = { 0xAA, 0x13, 0x01, 0x00, 0x00 };
/*設置循環模式 0xAA, 0x18, 0x01, 循環模式, SM*/
uint8_t LOOP_SET[5] = { 0xAA, 0x18, 0x01, 0x00, 0x00 };
/*設置循環次數 0xAA, 0x19, 0x02, 次數高, 次數低, SM*/
uint8_t LOOP_COUNT_SET[6] = { 0xAA, 0x19, 0x02, 0x00, 0x00, 0x00 };
/*EQ設置 0xAA, 0x1A, 0x01, EQ, SM*/
uint8_t EQ_SET[5] = { 0xAA, 0x1A, 0x01, 0x00, 0x00 };
/*指定曲目 0xAA, 0x07, 0x02, 曲目高, 曲目低, SM*/
uint8_t SEL_SOUND_SET[6] = { 0xAA, 0x07, 0x02, 0x00, 0x00, 0x00 };
/*指定盤符指定路徑 0xAA, 0x08, 長度, 盤符, 路徑, SM*/
uint8_t PAN_SET[6] = { 0xAA, 0x08, 0x00, 0x00, 0x00, 0x00 };
/*切換到指定盤符徑 0xAA, 0x0B, 0x01, 盤符, SM*/
uint8_t SEL_PAN_SET[5] = { 0xAA, 0x0B, 0x01, 0x00, 0x00 };
/*指定曲目播放 0xAA, 0x16, 0x03, 盤符, 曲目高, 曲目低, SM*/
uint8_t SEL_PAN_SOUND_SET[7] = { 0xAA, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00 };
/*指定路徑播放 0xAA, 0x17, 長度, 盤符, 路徑, SM*/
uint8_t SEL_DIR_SOUND_SET[6] = { 0xAA, 0x17, 0x00, 0x00, 0x00, 0x00 };
/*選曲不播放 0xAA, 0x1F, 0x02, 曲目高, 曲目低, SM*/
uint8_t CHECK_SOUND_SET[6] = { 0xAA, 0x1F, 0x02, 0x00, 0x00, 0x00 };
static void sv17f_uart_init(void);
static struct bflb_device_s *sound_uart;
static char uart_buff[8] = { 0 };
xQueueHandle sound_queue;
extern xQueueHandle rf_queue;
void sv17f_CMD_LOG(uint8_t *cmd_buf, uint8_t size)
{
printf("sv17f_CMD_LOG: ");
for (int i = 0; i < size; i++) {
printf("0x%02X ", cmd_buf[i]);
}
printf("rn");
}
/*計算校驗碼*/
uint8_t check_sum(uint8_t *ck_buf, uint8_t size)
{
uint8_t checkSum = 0x00;
for (int i = 0; i < size; i++) {
checkSum += ck_buf[i];
}
return checkSum;
}
/*音量設置 0xAA, 0x13, 0x01, 音量, SM*/
int sv17f_set_vol(uint8_t vol)
{
if (vol > 0x30) {
vol = 0x30;
} else if (vol < 0x00) {
vol = 0x00;
}
VOL_SET[3] = vol;
VOL_SET[4] = check_sum(VOL_SET, 5);
sv17f_CMD_LOG(VOL_SET, 5);
int ret;
ret = bflb_uart_put(sound_uart, VOL_SET, sizeof(VOL_SET));
return ret;
}
/*設置循環模式 0xAA, 0x18, 0x01, 循環模式, SM*/
int sv17f_set_loop(uint8_t loop)
{
LOOP_SET[3] = loop;
LOOP_SET[4] = check_sum(LOOP_SET, 5);
int ret;
sv17f_CMD_LOG(LOOP_SET, 5);
ret = bflb_uart_put(sound_uart, LOOP_SET, sizeof(LOOP_SET));
return ret;
}
/*設置循環次數 0xAA, 0x19, 0x02, 次數高, 次數低, SM*/
int sv17f_set_count(uint8_t count)
{
LOOP_COUNT_SET[3] = (count >> 8) & 0xFF;
LOOP_COUNT_SET[4] = count & 0xFF;
LOOP_COUNT_SET[5] = check_sum(LOOP_COUNT_SET, 6);
int ret;
ret = bflb_uart_put(sound_uart, LOOP_COUNT_SET, sizeof(LOOP_COUNT_SET));
return ret;
}
/*EQ設置 0xAA, 0x1A, 0x01, EQ, SM*/
int sv17f_set_eq(uint8_t eq)
{
int ret;
EQ_SET[3] = eq;
EQ_SET[4] = check_sum(EQ_SET, 5);
sv17f_CMD_LOG(EQ_SET, 5);
ret = bflb_uart_put(sound_uart, EQ_SET, sizeof(EQ_SET));
return ret;
}
/*指定曲目(會播放)*/
int sv17f_set_sound(uint8_t sound)
{
int ret;
SEL_SOUND_SET[3] = sound >> 8 & 0xFF;
SEL_SOUND_SET[4] = sound & 0xFF;
SEL_SOUND_SET[5] = check_sum(SEL_SOUND_SET, 6);
ret = bflb_uart_put(sound_uart, SEL_SOUND_SET, sizeof(SEL_SOUND_SET));
return ret;
}
/*指定盤符指定路徑 0xAA, 0x08, 長度, 盤符, 路徑, SM*/
int sv17f_set_pan(uint8_t pan)
{
int ret;
PAN_SET[3] = (pan >> 8) & 0xFF;
PAN_SET[4] = pan & 0xFF;
PAN_SET[5] = check_sum(PAN_SET, 6);
sv17f_CMD_LOG(PAN_SET, 6);
ret = bflb_uart_put(sound_uart, PAN_SET, sizeof(PAN_SET));
return ret;
}
/*切換到指定盤符徑 0xAA, 0x0B, 0x01, 盤符, SM*/
int sv17f_set_sel_pan(uint8_t pan)
{
int ret;
SEL_PAN_SET[3] = pan;
SEL_PAN_SET[4] = check_sum(SEL_PAN_SET, 5);
sv17f_CMD_LOG(SEL_PAN_SET, 5);
ret = bflb_uart_put(sound_uart, SEL_PAN_SET, sizeof(SEL_PAN_SET));
return ret;
}
/*指定曲目播放 0xAA, 0x16, 0x03, 盤符, 曲目高, 曲目低, SM*/
int sv17f_set_sel_sound_paly(uint8_t pan, uint16_t sound)
{
int ret;
SEL_PAN_SOUND_SET[3] = pan;
SEL_PAN_SOUND_SET[4] = sound >> 8 & 0xFF;
SEL_PAN_SOUND_SET[5] = sound & 0xFF;
SEL_PAN_SOUND_SET[6] = check_sum(SEL_PAN_SOUND_SET, 7);
sv17f_CMD_LOG(SEL_PAN_SOUND_SET, 7);
ret = bflb_uart_put(sound_uart, SEL_PAN_SOUND_SET, sizeof(SEL_PAN_SOUND_SET));
return ret;
}
/*指定路徑播放 0xAA, 0x17, 長度, 盤符, 路徑, SM*/
int sv17f_set_sel_dir_paly(uint8_t pan, uint8_t dir)
{
int ret;
// SEL_DIR_SOUND_SET[2] = 盤符長度+路徑長度=1+路徑長度;
SEL_DIR_SOUND_SET[3] = pan;
SEL_DIR_SOUND_SET[4] = dir;
SEL_DIR_SOUND_SET[5] = check_sum(SEL_DIR_SOUND_SET, 7);
ret = bflb_uart_put(sound_uart, SEL_DIR_SOUND_SET, sizeof(SEL_DIR_SOUND_SET));
return ret;
}
/*選曲不播放 1-65535*/
int sv17f_check_sel_sound(uint16_t sound)
{
int ret;
CHECK_SOUND_SET[3] = sound >> 8 & 0xFF;
CHECK_SOUND_SET[4] = sound & 0xFF;
CHECK_SOUND_SET[5] = check_sum(CHECK_SOUND_SET, 6);
ret = bflb_uart_put(sound_uart, CHECK_SOUND_SET, sizeof(CHECK_SOUND_SET));
return ret;
}
/* 查詢播放狀態*/
uint8_t sv17f_play_status(uint16_t timeout)
{
int ret = bflb_uart_put(sound_uart, CMD_QUERY_STATUS, 4);
while (!bflb_uart_rxavailable(sound_uart) && (--timeout)) {
bflb_mtimer_delay_ms(1);
}
int i;
uint8_t rx_buf[5] = { 0 };
printf("sv17f_play_status: ");
while (bflb_uart_rxavailable(sound_uart)) {
uint8_t tmp = bflb_uart_getchar(sound_uart);
printf("0x%02x ", tmp);
if (tmp == 0xAA) {
rx_buf[0] = tmp;
for (i = 1; i < 5; i++) {
rx_buf[i] = bflb_uart_getchar(sound_uart);
}
} else {
printf("0x%02x ", tmp);
memset(rx_buf, 0, 5);
}
}
printf("rn ");
sv17f_CMD_LOG(rx_buf, 5);
return rx_buf[3];
}
/* 查詢當前在線盤符*/
uint8_t sv17f_online_pan(uint16_t timeout)
{
int ret;
ret = bflb_uart_put(sound_uart, CMD_QUERY_PAN, sizeof(CMD_QUERY_PAN));
while (!bflb_uart_rxavailable(sound_uart) && (--timeout)) {
bflb_mtimer_delay_ms(1);
}
int i;
uint8_t rx_buf[5] = { 0 };
while (bflb_uart_rxavailable(sound_uart)) {
uint8_t tmp = bflb_uart_getchar(sound_uart);
if (tmp == 0xAA) {
rx_buf[0] = tmp;
for (i = 1; i < 5; i++) {
rx_buf[i] = bflb_uart_getchar(sound_uart);
}
} else {
memset(rx_buf, 0, 5);
}
}
sv17f_CMD_LOG(rx_buf, 5);
return rx_buf[3];
}
/* 查詢當前播放盤符*/
uint8_t sv17f_use_pan(uint16_t timeout)
{
int ret;
ret = bflb_uart_put(sound_uart, CMD_QUERY_PLAY_PAN, sizeof(CMD_QUERY_PLAY_PAN));
while (!bflb_uart_rxavailable(sound_uart) && (--timeout)) {
bflb_mtimer_delay_ms(1);
};
int i;
uint8_t rx_buf[5] = { 0 };
while (bflb_uart_rxavailable(sound_uart)) {
uint8_t tmp = bflb_uart_getchar(sound_uart);
if (tmp == 0xAA) {
rx_buf[0] = tmp;
for (i = 1; i < 5; i++) {
rx_buf[i] = bflb_uart_getchar(sound_uart);
}
} else {
memset(rx_buf, 0, 5);
}
}
sv17f_CMD_LOG(rx_buf, 5);
return rx_buf[3];
}
/* 查詢總曲目*/
uint8_t sv17f_sum_sound(uint16_t timeout)
{
int ret;
ret = bflb_uart_put(sound_uart, CMD_QUERY_SUM_SOUND, sizeof(CMD_QUERY_SUM_SOUND));
while (!bflb_uart_rxavailable(sound_uart) && (--timeout)) {
bflb_mtimer_delay_ms(1);
}
int i;
uint8_t rx_buf[6] = { 0 };
while (bflb_uart_rxavailable(sound_uart)) {
uint8_t tmp = bflb_uart_getchar(sound_uart);
if (tmp == 0xAA) {
rx_buf[0] = tmp;
for (i = 1; i < 6; i++) {
rx_buf[i] = bflb_uart_getchar(sound_uart);
}
} else {
memset(rx_buf, 0, 6);
}
}
sv17f_CMD_LOG(rx_buf, 6);
return rx_buf[3] << 8 + rx_buf[4];
}
/* 查詢當前曲目*/
uint8_t sv17f_cur_sound(uint16_t timeout)
{
int ret;
ret = bflb_uart_put(sound_uart, CMD_QUERY_CUR_SOUND, sizeof(CMD_QUERY_CUR_SOUND));
while (!bflb_uart_rxavailable(sound_uart) && (--timeout)) {
bflb_mtimer_delay_ms(1);
}
int i;
uint8_t rx_buf[6] = { 0 };
while (bflb_uart_rxavailable(sound_uart)) {
uint8_t tmp = bflb_uart_getchar(sound_uart);
if (tmp == 0xAA) {
rx_buf[0] = tmp;
for (i = 1; i < 6; i++) {
rx_buf[i] = bflb_uart_getchar(sound_uart);
}
} else {
memset(rx_buf, 0, 6);
}
}
sv17f_CMD_LOG(rx_buf, 6);
return rx_buf[3] << 8 + rx_buf[4];
}
/* 查詢文件夾目錄曲目*/
uint16_t sv17f_dir_sound(uint16_t timeout)
{
int ret;
ret = bflb_uart_put(sound_uart, CMD_QUERY_DIR_SOUND, sizeof(CMD_QUERY_DIR_SOUND));
while (!bflb_uart_rxavailable(sound_uart) && (--timeout)) {
bflb_mtimer_delay_ms(1);
}
int i;
uint8_t rx_buf[6] = { 0 };
while (bflb_uart_rxavailable(sound_uart)) {
uint8_t tmp = bflb_uart_getchar(sound_uart);
if (tmp == 0xAA) {
rx_buf[0] = tmp;
for (i = 1; i < 6; i++) {
rx_buf[i] = bflb_uart_getchar(sound_uart);
}
} else {
memset(rx_buf, 0, 6);
}
}
sv17f_CMD_LOG(rx_buf, 6);
uint16_t result = rx_buf[3] << 8;
return result + rx_buf[4];
}
/* 查詢文件夾目錄總曲目*/
uint16_t sv17f_sum_dir_sound(uint16_t timeout)
{
int ret;
ret = bflb_uart_put(sound_uart, CMD_QUERY_SUM_DIR_SOUND, sizeof(CMD_QUERY_SUM_DIR_SOUND));
while (!bflb_uart_rxavailable(sound_uart) && (--timeout)) {
bflb_mtimer_delay_ms(1);
}
int i;
uint8_t rx_buf[6] = { 0 };
while (bflb_uart_rxavailable(sound_uart)) {
uint8_t tmp = bflb_uart_getchar(sound_uart);
if (tmp == 0xAA) {
rx_buf[0] = tmp;
for (i = 1; i < 6; i++) {
rx_buf[i] = bflb_uart_getchar(sound_uart);
}
} else {
memset(rx_buf, 0, 6);
}
}
sv17f_CMD_LOG(rx_buf, 6);
uint16_t result = rx_buf[3] << 8;
return result + rx_buf[4];
}
/* 播放*/
int sv17f_play()
{
int ret;
ret = bflb_uart_put(sound_uart, CMD_PLAY, sizeof(CMD_PLAY));
return ret;
}
/* 暫停*/
int sv17f_pasue()
{
int ret;
ret = bflb_uart_put(sound_uart, CMD_PAUSE, sizeof(CMD_PAUSE));
return ret;
}
/* 停止*/
int sv17f_stop()
{
int ret;
ret = bflb_uart_put(sound_uart, CMD_STOP, sizeof(CMD_STOP));
return ret;
}
/* 上一曲*/
int sv17f_sound_up()
{
int ret;
ret = bflb_uart_put(sound_uart, CMD_SOUND_UP, sizeof(CMD_SOUND_UP));
return ret;
}
/* 下一曲*/
int sv17f_sound_down()
{
int ret;
ret = bflb_uart_put(sound_uart, CMD_SOUND_DOWN, sizeof(CMD_SOUND_DOWN));
return ret;
}
/* 音量加*/
int sv17f_vol_up()
{
int ret;
ret = bflb_uart_put(sound_uart, CMD_VOL_UP, sizeof(CMD_VOL_UP));
return ret;
}
/* 音量減*/
int sv17f_vol_down()
{
int ret;
ret = bflb_uart_put(sound_uart, CMD_VOL_DOWN, sizeof(CMD_VOL_DOWN));
return ret;
}
/* 上一文件目錄*/
int sv17f_dir_up()
{
int ret;
ret = bflb_uart_put(sound_uart, CMD_DIR_UP, sizeof(CMD_DIR_UP));
return ret;
}
/* 下一文件目錄*/
int sv17f_dir_down()
{
int ret;
ret = bflb_uart_put(sound_uart, CMD_DIR_DOWN, sizeof(CMD_DIR_DOWN));
return ret;
}
/* 結束播放*/
int sv17f_release()
{
int ret;
ret = bflb_uart_put(sound_uart, CMD_RELEASE, sizeof(CMD_RELEASE));
return ret;
}
void sv17f_init(const struct sv17f_config_s *config)
{
sv17f_set_vol(config->volume);
sv17f_set_loop(config->loop_mode);
sv17f_set_eq(config->eq);
}
void sv17f_uart_task(void *arg)
{
char *buf = NULL;
sound_queue = xQueueCreate(1, 8);
struct sv17f_config_s sv17f_cfg = {
.volume = VOLUME_LEVEL_30,
.loop_mode = LOOP_MODE_SINGLE_STOP,
.eq = EQ_NOMARL,
.pan = PAN_SD
};
sv17f_uart_init();
sv17f_init(&sv17f_cfg);
while (1) {
buf = pvPortMalloc(8);
memset(buf, 0, 8);
xQueueReceive(sound_queue, buf, portMAX_DELAY);
sv17f_set_sound(1);
// sv17f_set_pan(config->pan);
LOG_E("播放狀態:0x%02x rn", sv17f_play_status(2000));
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
/**
* @brief
*
*/
static void sv17f_uart_init()
{
struct bflb_device_s *gpio;
struct bflb_uart_config_s sound_cfg = {
.baudrate = 9600,
.data_bits = UART_DATA_BITS_8,
.stop_bits = UART_STOP_BITS_1,
.parity = UART_PARITY_NONE,
.flow_ctrl = 0,
.tx_fifo_threshold = 4,
.rx_fifo_threshold = 4,
};
gpio = bflb_device_get_by_name("gpio");
sound_uart = bflb_device_get_by_name("uart1");
bflb_gpio_uart_init(gpio, GPIO_PIN_25, GPIO_UART_FUNC_UART1_TX);
bflb_gpio_uart_init(gpio, GPIO_PIN_26, GPIO_UART_FUNC_UART1_RX);
bflb_uart_init(sound_uart, &sound_cfg);
}
【外設移植】Ai-M6x + SI4432 無線模塊
https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=45477&fromuid=16612
上篇帖子的代碼分成了發送端和接收端為了增加了設備 id 防止被其他設備觸發
接收端
發送端
【外設移植】Ai-M6x + DY-SV17F 語音播放模塊】 視頻演示:
https://www.bilibili.com/video/BV1H5mhYDEZi/?share_source=copy_web&vd_source=addf5eba933a94affcf41637a0ea1365
感覺用來找電動車、自行車、小汽車比較不錯,畢竟空曠場景超遠距離傳輸數據呢。
說干就干呢,下篇加外殼DIY 一個妥妥的找車神器,就是聲音能不能傳千米呢?試試再說
審核編輯 黃宇
-
wifi模塊
+關注
關注
60文章
380瀏覽量
73495 -
安信可
+關注
關注
0文章
152瀏覽量
3984
發布評論請先 登錄
相關推薦
評論