简介:STM32F103C8T6驱动BY9301语音播报模块源码介绍。
开发平台:KEIL ARM
MCU型号:STM32F103C8T6
传感器型号:BY9301
特别提示:驱动内可能使用了某些其他组件,比如delay等,在文末外设模板下载地址内有。
1积分源码下载地址在文末!!!
接口图:
使用举例:
#include <stdio.h>
#include "BY9301.h"
int main()
{
BY9301Class.init(9600); // 初始化
BY9301Class.setVolume(30); // 音量30
BY9301Class.sayFileID(1); // 播放序号为1的mp3文件
while(1) {}
}
驱动源码:
BY9301.c
/*
BY9301语音播报模块
*/
#include "main.h"
void BY9301_USART_Init(uint32_t baudRate);
static void BY9301_SendString(uint8_t *str);
static void BY9301_Say(uint8_t NOx);
static void BY9301_setVolume(uint8_t volume);
static void BY9301_playPause(uint8_t playPause);
static uint8_t BY9301_Busy(void);
BY9301ClassStruct BY9301Class = {
.init = BY9301_USART_Init,
.sayFileID = BY9301_Say,
.isBusy = BY9301_Busy,
.setVolume = BY9301_setVolume,
.playPause = BY9301_playPause
};
// VOICE USART define
#if 1
#define BY9301_USARTx_PORT USART1
#define BY9301_USARTx_CLK RCC_APB2Periph_USART1
#define BY9301_USARTx_APBxClkCmd RCC_APB2PeriphClockCmd
#define BY9301_USARTx_PORT_CLK (RCC_APB2Periph_GPIOA)
#define BY9301_USARTx_PORT_APBxClkCmd RCC_APB2PeriphClockCmd
#define BY9301_USARTx_TX_PORT GPIOA
#define BY9301_USARTx_TX_PIN GPIO_Pin_9
#define BY9301_USARTx_RX_PORT GPIOA
#define BY9301_USARTx_RX_PIN GPIO_Pin_10
#define BY9301_USARTx_IRQ USART1_IRQn
#define BY9301_USARTx_IRQHandler USART1_IRQHandler
#else
#define BY9301_USARTx_PORT USART2
#define BY9301_USARTx_CLK RCC_APB1Periph_USART2
#define BY9301_USARTx_APBxClkCmd RCC_APB1PeriphClockCmd
#define BY9301_USARTx_PORT_CLK (RCC_APB2Periph_GPIOA)
#define BY9301_USARTx_PORT_APBxClkCmd RCC_APB2PeriphClockCmd
#define BY9301_USARTx_TX_PORT GPIOA
#define BY9301_USARTx_TX_PIN GPIO_Pin_2
#define BY9301_USARTx_RX_PORT GPIOA
#define BY9301_USARTx_RX_PIN GPIO_Pin_3
#define BY9301_USARTx_IRQ USART2_IRQn
#define BY9301_USARTx_IRQHandler USART2_IRQHandler
#endif
#define BUSY_GPIO_PORT GPIOB /* GPIO端口 */
#define BUSY_GPIO_CLK RCC_APB2Periph_GPIOB /* GPIO端口时钟 */
#define BUSY_GPIO_PIN GPIO_Pin_12 /* 连接到SCL时钟线的GPIO */
void BY9301_USARTx_IRQHandler(void)
{
if(USART_GetITStatus(BY9301_USARTx_PORT, USART_IT_RXNE) != RESET) {
USART_ClearITPendingBit(BY9301_USARTx_PORT, USART_IT_RXNE);
}
}
/**
* @brief 语音串口USART初始化
* @param baudRate: 波特率
* @retval None
*/
static void BY9301_USART_Init(uint32_t baudRate)
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
/* GPIO时钟配置 */
BY9301_USARTx_PORT_APBxClkCmd(BY9301_USARTx_PORT_CLK, ENABLE);
/* 串口时钟配置 */
BY9301_USARTx_APBxClkCmd(BY9301_USARTx_CLK, ENABLE);
/* USART Tx--复用推挽输出 */
GPIO_InitStructure.GPIO_Pin = BY9301_USARTx_TX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(BY9301_USARTx_TX_PORT, &GPIO_InitStructure);
/* USART Rx--浮空输入 */
GPIO_InitStructure.GPIO_Pin = BY9301_USARTx_RX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(BY9301_USARTx_RX_PORT, &GPIO_InitStructure);
// BUSY输入
RCC_APB2PeriphClockCmd(BUSY_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = BUSY_GPIO_PIN;
GPIO_Init(BUSY_GPIO_PORT, &GPIO_InitStructure);
/* 串口参数配置 */
USART_InitStructure.USART_BaudRate = baudRate; // 波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 数据位
USART_InitStructure.USART_StopBits = USART_StopBits_1; // 停止位
USART_InitStructure.USART_Parity = USART_Parity_No; // 校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 硬件流控
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 工作模式 收发一起
USART_Init(BY9301_USARTx_PORT, &USART_InitStructure); // 串口初始化
/* 串口使能 */
USART_Cmd(BY9301_USARTx_PORT, ENABLE);
/* 串口中断使能 */
USART_ITConfig(BY9301_USARTx_PORT, USART_IT_RXNE, ENABLE);
/* NVIC优先级分组 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
/* NVIC参数配置*/
NVIC_InitStructure.NVIC_IRQChannel = BY9301_USARTx_IRQ; // 中断源 有特定的命名
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 主优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能NVIC
NVIC_Init(&NVIC_InitStructure); // NVIC初始化
}
/**
* @brief 语音串口发送 具体协议参见手册
* @param str: 要发送的内容
* @retval None
*/
static void BY9301_SendString(uint8_t *str)
{
if(str[1] == 0) return;
uint8_t i;
for(i = 0; i < str[1] + 2; i++) {
USART_SendData(BY9301_USARTx_PORT, str[i]);
while (USART_GetFlagStatus(BY9301_USARTx_PORT, USART_FLAG_TXE) == RESET){}
}
while(USART_GetFlagStatus(BY9301_USARTx_PORT, USART_FLAG_TC) == RESET){}
}
/**
* @brief 指定序号播报
* @param NOx: mp3文件序号
* @retval None
*/
static void BY9301_Say(uint8_t NOx)
{
uint8_t arr[8] = {0};
arr[0] = 0x7E;
arr[1] = 0x05;
arr[2] = 0x41;
arr[3] = 0x00;
arr[4] = NOx;
arr[5] = arr[1]^arr[2]^arr[3]^arr[4];
arr[6] = 0xEF;
BY9301_SendString(arr);
}
/**
* @brief 设置音量
* @param volume: 0-30
* @retval None
*/
static void BY9301_setVolume(uint8_t volume)
{
if(volume > 30) volume = 30;
uint8_t arr[7];
arr[0] = 0x7E;
arr[1] = 0x04;
arr[2] = 0x31;
arr[3] = volume;
arr[4] = arr[1]^arr[2]^arr[3];
arr[5] = 0xEF;
BY9301_SendString(arr);
}
/**
* @brief 设置播放暂停
* @param playPause: 0:pause 1:play
* @retval None
*/
static void BY9301_playPause(uint8_t playPause)
{
uint8_t arr[6];
arr[0] = 0x7E;
arr[1] = 0x03;
if(playPause) {
arr[2] = 0x01;
} else {
arr[2] = 0x02;
}
arr[3] = arr[1]^arr[2];
arr[4] = 0xEF;
BY9301_SendString(arr);
}
/**
* @brief Busy引脚状态
* @param None
* @retval 返回Busy引脚电平状态 1:busy 0:idle
*/
static uint8_t BY9301_Busy(void)
{
return GPIO_ReadInputDataBit(BUSY_GPIO_PORT, BUSY_GPIO_PIN);
}
BY9301.h
#ifndef __BY9301_AS_H
#define __BY9301_AS_H
#include "main.h"
typedef struct {
void (* init)(uint32_t);
void (* sayFileID)(uint8_t);
void (* setVolume)(uint8_t);
void (* playPause)(uint8_t);
uint8_t (* isBusy)(void);
} BY9301ClassStruct;
extern BY9301ClassStruct BY9301Class;
#endif
驱动下载地址:
https://download.csdn.net/download/m0_50669075/87672764
STM32工程模板、外设模板、模块模板下载地址:
版权声明:本文为m0_50669075原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。