智能语音播放模块 | STM32F103C8T6 | HAL库 | IO触发模式
DY-SV17F 语音播放模块的工作原理、核心功能及引脚定义
DY-SV17F 是一款高集成度的智能语音模块,集成 IO分段触发、UART串口控制、ONE_line单总线串口控制、标准MP3等7种工作模式;板载 5W D类功放,可直接驱动4Ω、3~5W喇叭;支持 MP3、WAV 解码格式,板载 32Mbit(4MByte)Flash存储,可通过USB数据线连接电脑更新音频文件。
该模块通过3个配置引脚(CON1/CON2/CON3)的拨码开关组合选择工作模式。本项目采用 IO触发模式(CON3 CON2 CON1 = 0 0 0,即I/O组合模式0),通过控制模块的 IO1、IO2、IO3 引脚电平来选择播放不同曲目。IO触发模式下低电平有效,8个IO口(IO0~IO7)组合可触发255首曲目,独立触发可控制8首曲目。
在IO组合模式下,IO0~IO7构成8位二进制选择器,所有IO为高电平时待机,某IO为低电平时播放对应编号曲目。曲目按文件名命名,必须使用5位数字格式(如 00001.mp3、00002.mp3)。本项目仅使用 IO1/IO2/IO3 三个引脚,分别触发 00001.mp3、00002.mp3、00003.mp3 三首曲目。
内置24位DAC,动态范围90dB,信噪比85dB,支持 MP3/WAV 格式,采样率 8~48KHz。
8个IO口(IO0~IO7)低电平触发,组合模式可播放255首曲目,独立模式可播放8首曲目,仅需GPIO即可控制。
板载32Mbit(4MByte)Flash存储,可通过USB数据线连接电脑直接更新音频文件,同时支持TF卡扩展。
板载5W D类功放,可直接驱动4Ω、3~5W喇叭,无需外接功放电路,简化系统设计。
| 引脚号 | 引脚名称 | 功能描述 | STM32连接 |
|---|---|---|---|
| 1 | TXD/IO0 | IO触发模式输入IO0 / UART模式TX | — |
| 2 | RXD/IO1 | IO触发模式输入IO1 / UART模式RX | PA5 |
| 3 | IO2 | IO触发模式输入IO2 | PA6 |
| 4 | IO3 | IO触发模式输入IO3 | PA7 |
| 5 | IO4/ONE_LINE | IO触发模式IO4 / One_Line数据接收 | — |
| 6 | IO5 | IO触发模式输入IO5 | — |
| 7 | IO6 | IO触发模式输入IO6 | — |
| 8 | IO7 | IO触发模式输入IO7 | — |
| 9 | GND | 参考地端 | GND |
| 10 | CON1 | 模式配置引脚1 | 拨码开关 |
| 11 | CON2 | 模式配置引脚2 | 拨码开关 |
| 12 | CON3/BUSY | 上电30mS内配置引脚3 / 30mS后BUSY信号输出 | — |
| 13 | V5 | 5V电源正极输入 | 5V |
| 14 | V33 | 3.3V电源输出(最大80mA) | — |
| 15 | DACR | 右声道音频输出 | — |
| 16 | DACL | 左声道音频输出 | — |
| 17 | SPK- | 5W功放输出负,接喇叭负极 | 接喇叭- |
| 18 | SPK+ | 5W功放输出正,接喇叭正极 | 接喇叭+ |
| IO7 | IO6 | IO5 | IO4 | IO3 | IO2 | IO1 | IO0 | 播放曲目 |
|---|---|---|---|---|---|---|---|---|
| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 停止 / 待机 |
| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 00001.mp3 |
| 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 00002.mp3 |
| 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 00003.mp3 |
| 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 00004.mp3 |
| … | … | … | … | … | … | … | … | … |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 00255.mp3 |
上表为模块IO组合模式通用映射规则。本项目使用 IO1/IO2/IO3 三路控制,音频文件命名为 00001.mp3、00002.mp3、00003.mp3,分别对应 IO1/IO2/IO3 低电平触发。IO0 及 IO4~IO7 未连接,保持高电平。
| IO1 (PA5) | IO2 (PA6) | IO3 (PA7) | 动作 |
|---|---|---|---|
| 1 | 1 | 1 | 停止 / 待机 |
| 0 | 1 | 1 | 播放 00001.mp3 |
| 1 | 0 | 1 | 播放 00002.mp3 |
| 1 | 1 | 0 | 播放 00003.mp3 |
DY-SV17F 音乐模块实物外观与尺寸图
DY-SV17F 模块原理图设计与PCB封装展示
基于 STM32 HAL 库的 DY-SV17F 音乐模块控制程序分析
在 main.h 中定义了 IO1/IO2/IO3 控制引脚和 K1/K2/K3 按键引脚的硬件映射。在 main.c 中通过宏封装了 GPIO 读写操作,使代码更简洁。
/* IO控制引脚 — 连接DY-SV17F模块的IO1/IO2/IO3 */ #define IO1_Pin GPIO_PIN_5 #define IO1_GPIO_Port GPIOA #define IO2_Pin GPIO_PIN_6 #define IO2_GPIO_Port GPIOA #define IO3_Pin GPIO_PIN_7 #define IO3_GPIO_Port GPIOA /* 按键引脚 — K1/K2/K3 独立按键 */ #define K1_Pin GPIO_PIN_11 #define K1_GPIO_Port GPIOA #define K2_Pin GPIO_PIN_12 #define K2_GPIO_Port GPIOA #define K3_Pin GPIO_PIN_15 #define K3_GPIO_Port GPIOA
/* 按键读取宏 — 返回引脚电平(0=按下, 1=松开) */ #define K1 HAL_GPIO_ReadPin(K1_GPIO_Port, K1_Pin) #define K2 HAL_GPIO_ReadPin(K2_GPIO_Port, K2_Pin) #define K3 HAL_GPIO_ReadPin(K3_GPIO_Port, K3_Pin) /* IO输出宏 — 设置IO引脚电平(0=低, 1=高) */ #define IO1(a) HAL_GPIO_WritePin(IO1_GPIO_Port, IO1_Pin, (GPIO_PinState)a) #define IO2(a) HAL_GPIO_WritePin(IO2_GPIO_Port, IO2_Pin, (GPIO_PinState)a) #define IO3(a) HAL_GPIO_WritePin(IO3_GPIO_Port, IO3_Pin, (GPIO_PinState)a)
在 gpio.c 中完成所有GPIO引脚的初始化配置。IO1/IO2/IO3 配置为推挽输出模式,初始电平为高(对应模块待机状态);K1/K2/K3 配置为上拉输入模式,按键按下时引脚被拉低为0。
void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO端口时钟使能 */ __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /* IO1/IO2/IO3 初始输出高电平(模块待机) */ HAL_GPIO_WritePin(GPIOA, IO1_Pin|IO2_Pin|IO3_Pin, GPIO_PIN_SET); /* IO1/IO2/IO3: 推挽输出, 上拉, 低速 */ GPIO_InitStruct.Pin = IO1_Pin|IO2_Pin|IO3_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* K1/K2/K3: 上拉输入 */ GPIO_InitStruct.Pin = K1_Pin|K2_Pin|K3_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); }
OLED 使用软件模拟 I2C 通信,SCL 接 PB15,SDA 接 PB14。OLED 模块用于实时显示 IO1/IO2/IO3 三个控制引脚的电平状态值。
#define SCL_Port GPIOB #define SCL_Pin GPIO_PIN_15 /* OLED时钟线 → PB15 */ #define SDA_Port GPIOB #define SDA_Pin GPIO_PIN_14 /* OLED数据线 → PB14 */
主循环 while(1) 中持续检测 K1/K2/K3 三个按键。采用软件消抖(10ms延时)和松手检测(while(Kn==0) 等待按键释放)确保每次按键只触发一次动作。
每个按键被按下后,对应 IO 引脚执行翻转操作(Toggle),同时将另外两个 IO 引脚置高。这样确保同一时刻只有一个 IO 为低电平,即只播放一首曲目。再次按下同一按键则翻转回高电平,模块停止播放。
while (1) { // ---- 按键K1检测:控制IO1 ---- if(K1 == 0) { HAL_Delay(10); // 消抖延时10ms if(K1 == 0) { while(K1 == 0); // 等待按键松开 HAL_GPIO_TogglePin(IO1_GPIO_Port, IO1_Pin); // 翻转IO1 IO2(1); // IO2置高 IO3(1); // IO3置高 } } // ---- 按键K2检测:控制IO2 ---- if(K2 == 0) { HAL_Delay(10); if(K2 == 0) { while(K2 == 0); HAL_GPIO_TogglePin(IO2_GPIO_Port, IO2_Pin); // 翻转IO2 IO1(1); // IO1置高 IO3(1); // IO3置高 } } // ---- 按键K3检测:控制IO3 ---- if(K3 == 0) { HAL_Delay(10); if(K3 == 0) { while(K3 == 0); HAL_GPIO_TogglePin(IO3_GPIO_Port, IO3_Pin); // 翻转IO3 IO1(1); // IO1置高 IO2(1); // IO2置高 } }
使用 HAL_GetTick() 获取系统滴答定时器计数值,每 50ms 刷新一次 OLED 显示内容。显示内容包括 IO1、IO2、IO3 三个引脚的当前电平状态(0 或 1),通过 OLED_CenterPrintf 居中显示标题,OLED_ShowNum 分别在三个位置显示数值。
// ---- OLED屏幕显示(50ms更新一次) ---- if(HAL_GetTick() - Time_Now >= 50) { OLED_Clear(); // 清屏 OLED_CenterPrintf(12, "IO1 IO2 IO3"); // 标题行 OLED_ShowNum(12, 36, HAL_GPIO_ReadPin(IO1_GPIO_Port, IO1_Pin), 1, OLED_8X16); OLED_ShowNum(60, 36, HAL_GPIO_ReadPin(IO2_GPIO_Port, IO2_Pin), 1, OLED_8X16); OLED_ShowNum(108, 36, HAL_GPIO_ReadPin(IO3_GPIO_Port, IO3_Pin), 1, OLED_8X16); OLED_Update(); // 更新显示 Time_Now = HAL_GetTick(); // 更新时间戳 }
| 按键操作 | IO1 | IO2 | IO3 | 模块动作 | OLED显示 |
|---|---|---|---|---|---|
| 初始状态 | 1 | 1 | 1 | 待机/停止 | 1 1 1 |
| 按K1(第一次) | 0 | 1 | 1 | 播放 00001.mp3 | 0 1 1 |
| 按K1(第二次) | 1 | 1 | 1 | 停止播放 | 1 1 1 |
| 按K2(第一次) | 1 | 0 | 1 | 播放 00002.mp3 | 1 0 1 |
| 按K2(第二次) | 1 | 1 | 1 | 停止播放 | 1 1 1 |
| 按K3(第一次) | 1 | 1 | 0 | 播放 00003.mp3 | 1 1 0 |
| 按K3(第二次) | 1 | 1 | 1 | 停止播放 | 1 1 1 |
STM32 主程序执行流程,包含初始化、按键检测、IO控制与OLED显示
流程说明:程序上电后依次完成 HAL_Init、时钟配置、GPIO 初始化和 OLED 初始化,随后进入 while(1) 主循环。循环体内依次检测 K1、K2、K3 按键状态,检测到按键按下时执行消抖、等待松手、翻转对应 IO 引脚并复位其余 IO。随后判断距上次刷新是否满 50ms,满则执行 OLED 清屏并显示 IO1/IO2/IO3 状态值。虚线框为 while(1) 循环体范围,循环回退线(黄色)表示每次执行完毕后回到循环起始处继续检测。
模拟 DY-SV17F 模块的按键控制与播放状态,OLED 实时显示 IO 电平
IO1/IO2/IO3 引脚指示灯:绿色圆圈表示高电平(1),红色圆圈表示低电平(0)。同一时刻仅允许一个 IO 为低电平。
扬声器与音符动画:当某曲目正在播放时,扬声器旁出现声波动画和漂浮音符,表示音频正在输出。
OLED 显示屏:模拟 0.96 寸 OLED 屏幕,绿色字体显示 IO1/IO2/IO3 的实时电平值,每 50ms 刷新一次。
按键操作:点击 K1/K2/K3 模拟物理按键按下。首次按下对应曲目开始播放,再次按下则停止。切换曲目时自动停止当前曲目。