专栏名称: CW32生态社区
以开放、共享、互助为理念,致力于构建武汉芯源半导体CW32系列MCU生态社区。无论是嵌入式MCU小白还是想要攻破技术难题的工程师,亦或是需求解决方案的产品经理,都可在CW32生态社区汲取营养、共同成长。
目录
相关文章推荐
51好读  ›  专栏  ›  CW32生态社区

【CW32模块使用】语音合成播报模块

CW32生态社区  · 公众号  ·  · 2025-02-27 15:55

正文

请到「今天看啥」查看全文


SYN6288E 中文语音合成芯片是北京宇音天下科技有限公司在 2010 年初推出的一款性/价比更高的 SYN6288 芯片的基础上更改封装方式的,效果更自然的一款中高端语音合成芯片。SYN6288E 通过异步串 口(UART)通讯方式,接收待合成的文本数据,实现文本到语音(或 TTS 语音)的转换。
模块来源

>>>

模块实物展示

资料链接:https://pan.baidu.com/s/1FjoAuJm387bxaZxS6g9HEg

资料提取码: 8888

规格参数

>>>

输入电压 :2.4V~5.1V

额定电流 2.0uA~280mA

控制方式 串口

以上信息见厂家资料文件

移植过程

>>>

我们的目标是将例程移植至CW32F030C8T6开发板上【能够播报语音的功能】。首先要获取资料,查看数据手册应如何实现读取数据,再移植至我们的工程。

3. 1
查看资料

语音播报控制,只要配置出串口,再根据数据手册要求的命令帧格式发送数据,就能实现播报功能。

注意!该模块只能实现语音播报,没有语音识别功能!也无法录音。

3. 2
引脚选择

想要使用uart串口,需要确定使用的引脚是否有串口外设功能,可以通过用户手册进行查看。在用户手册的第146页。

这里选择使用PA2和PA3的附加串口2功能。

图 0

有串口功能的引脚

图 1

块接线图

3.3
移植至工程

移植步骤中的导入.c和.h文件与 【CW32模块使用】DHT11温湿度传感器 相同, 只是将.c和.h文件更改为bsp_syn6288.c与bsp_syn6288.h。这里不再过多讲述,移植完成后面修改相关代码。

在文件bsp_syn6288.c中,编写如下代码。

/* * Change Logs: * Date           Author       Notes * 2024-06-25     LCKFB-LP    first version */#include "bsp_syn6288.h"#include "stdio.h"#include "stdlib.h"#include "string.h"
#define SYN6288RX_LEN_MAX 255
unsigned char SYN6288RX_BUFF[SYN6288RX_LEN_MAX];unsigned char SYN6288RX_LEN = 0;

/****************************************************************** * 函 数 名 称:SYN6288_GPIO_Init * 函 数 说 明:SYN6288引脚初始化 * 函 数 形 参:band_rate GPS通信波特率 * 函 数 返 回:无 * 作 者:LC * 备 注:默认波特率为9600********************************************* *********************/void SYN6288_GPIO_Init(uint32_t band_rate){ GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化结构体
BSP_SYN6288_GPIO_RCC_ENABLE(); // 使能GPIO时钟 BSP_SYN6288_UART_RCC_ENABLE(); // 使能UART时钟
GPIO_InitStruct.Pins = BSP_SYN6288_TX_PIN; // GPIO引脚 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; // 输出速度高 GPIO_Init(BSP_SYN6288_GPIO_PORT, &GPIO_InitStruct); // 初始化
GPIO_InitStruct.Pins = BSP_SYN6288_RX_PIN; // GPIO引脚 GPIO_InitStruct.Mode = GPIO_MODE_INPUT_PULLUP; // 上拉输入 GPIO_Init(BSP_SYN6288_GPIO_PORT, &GPIO_InitStruct); // 初始化
BSP_SYN6288_AF_UART_TX(); // UART_TX复用 BSP_SYN6288_AF_UART_RX(); // UART_RX复用
// 配置UART USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = band_rate; // 波特率 USART_InitStructure.USART_Over = USART_Over_16; // 配置USART的过采样率。 USART_InitStructure.USART_Source = USART_Source_PCLK; // 设置时钟源 USART_InitStructure.USART_UclkFreq = 64000000; //设置USART时钟频率(和主频一致即可) USART_InitStructure.USART_StartBit = USART_StartBit_FE; //RXD下降沿开始 USART_InitStructure.USART_StopBits = USART_StopBits_1; // 停止位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(BSP_SYN6288, &USART_InitStructure); // 初始化串口2
// 优先级,无优先级分组 NVIC_SetPriority(BSP_SYN6288_IRQ, 0);
// UARTx中断使能 NVIC_EnableIRQ(BSP_SYN6288_IRQ);
// 使能UARTx RC中断 USART_ITConfig(BSP_SYN6288, USART_IT_RC, ENABLE);}
/****************************************************************** * 函 数 名 称:SYN6288_Send_Bit * 函 数 说 明:向SYN6288发送单个字符 * 函 数 形 参:ch发送的字符 * 函 数 返 回:无 * 作 者:LC * 备 注:无******************************************************************/void SYN6288_Send_Bit(unsigned char ch){ USART_SendData(BSP_SYN6288, (uint8_t)ch);
while( RESET == USART_GetFlagStatus(BSP_SYN6288, USART_FLAG_TXE) ){} // 等待发送数据缓冲区标志置位}
/****************************************************************** * 函 数 名 称:SYN6288_send_String * 函 数 说 明:SYN6288发送字符串 * 函 数 形 参:str要发送的字符串 * 函 数 返 回:无 * 作 者:LC * 备 注:无******************************************************************/void SYN6288_send_String(unsigned char *str){ while( str && *str ) // 地址为空或者值为空跳出 { SYN6288_Send_Bit(*str++); }}//获取串口接收的数据unsigned char *Get_SYN6288RX_BUFF(void){ return SYN6288RX_BUFF;}
//清除串口接收的数据void Clear_SYN6288RX_BUFF(void){ unsigned char i = SYN6288RX_LEN_MAX-1; while(i) { SYN6288RX_BUFF[i--] = '\0'; } SYN6288RX_LEN = 0;}
/************************************************************ * 函数名称:SYN6288_Send_Cmd * 函数说明:向SYN6288发送命令 * 型 参: * 【CmdType=命令字】 可使用参数有: * 0x01 语音合成命令 * 0x31 设置波特率(默认9600) * 0x02 停止合成命令 * 0x03 暂停合成命令 * 0x04 恢复合成命令 * 0x21 芯片状态查询命令 * 0x88 芯片进入低功耗模式 * 【CmdPar=命令参数】 可使用参数有: * 字节高5位的十进制为0时,表示不加背景音乐 * 字节高5位的十进制为1~15时,表示所选背景音乐的编号 * 字节低3位的十进制为0~3,并且命令字为语音合成命令时,分别代表设置文本为GB2312格式、GBK格式、BIG5格式、UNICODE格式; * 字节低3位的十进制为0~2,并且命令字为设置波特率时,分别代表设置波特率为9600、19200、38400; * 【text=播报的文本】
* 返 回 值:0=发送成功 * 备 注:
* 接收到控制命令帧,芯片会向上位机发送1个字节的状态回传,上位机可根据这个回传来判断芯片目前的工作状态 * 初始化成功回传 0X4A * 收到正确的命令帧回传 0x41 * 收到不能识别命令帧回传 0x45 * 芯片播音状态回传 0x4E * 芯片空闲状态回传 0x4F*************************************************************/unsigned char SYN6288_Send_Cmd(uint8_t CmdType, uint8_t CmdPar, uint8_t *text){ unsigned char frame_header = 0XFD; //帧头 unsigned int Text_Len = strlen((const char*)text);//待发送文本的长度 unsigned int Data_Len = Text_Len + 3; //数据区长度;3=帧头、帧尾和异或校验 unsigned char Xor_Check = 0; //异或校验存储 unsigned char Send_Buff[210]; //待发送的命令帧,命令帧最大206个字节 uint8_t i = 0;
Send_Buff[0] = frame_header; //帧头 Send_Buff[1] = Data_Len>>8; //高位在前 Send_Buff[2] = Data_Len&0x00ff; //低位在前 Send_Buff[3] = CmdType; //命令字 Send_Buff[4] = CmdPar; //命令数据 sprintf((char*)Send_Buff+5, "%s", text );
//发送数据 for( i = 0; i < Text_Len+5; i++ ) { Xor_Check = Xor_Check ^ Send_Buff[i];//对每一个数据进行异或校验保存 SYN6288_Send_Bit( Send_Buff[i] );//发送数据 } SYN6288_Send_Bit( Xor_Check );//发送最后一位:异或校验数据
return 0;}

/****************************************************************** * 函 数 名 称:BSP_SYN6288_IRQHandler * 函 数 说 明:串口中断服务函数 * 函 数 形 参:无 * 函 数 返 回:无 * 作 者:LC * 备 注:无******************************************************************/void BSP_SYN6288_IRQHandler(void){ if(USART_GetITStatus(BSP_SYN6288,USART_IT_RC) != RESET) // 接收缓冲区不为空 { SYN6288RX_BUFF[ SYN6288RX_LEN ] = USART_ReceiveData(BSP_SYN6288); SYN6288RX_LEN = ( SYN6288RX_LEN + 1 ) % SYN6288RX_LEN_MAX;
SYN6288RX_BUFF[SYN6288RX_LEN] = '\0';
USART_ClearITPendingBit(BSP_SYN6288, USART_IT_RC); // 清除中断标志位 }}

在文件bsp_syn6288.h中,编写如下代码。

/* * Change Logs: * Date           Author       Notes * 2024-06-25     LCKFB-LP    first version */#ifndef _BSP_SYN6288_H#define _BSP_SYN6288_H
#include "board.h"
#define BSP_SYN6288_GPIO_RCC_ENABLE() __RCC_GPIOA_CLK_ENABLE() // GPIO端口时钟#define BSP_SYN6288_UART_RCC_ENABLE() __RCC_UART2_CLK_ENABLE() // 串口2的时钟

#define BSP_SYN6288_AF_UART_TX() PA02_AFx_UART2TXD()#define BSP_SYN6288_AF_UART_RX() PA03_AFx_UART2RXD()
#define BSP_SYN6288_GPIO_PORT CW_GPIOA // GPIO的端口
#define BSP_SYN6288_TX_PIN GPIO_PIN_2 // 串口TX的引脚#define BSP_SYN6288_RX_PIN GPIO_PIN_3 // 串口RX的引脚
#define BSP_SYN6288 CW_UART2 // 串口2#define BSP_SYN6288_IRQ UART2_IRQn // 串口2中断#define BSP_SYN6288_IRQHandler UART2_IRQHandler // 串口2中断服务函数


void SYN6288_GPIO_Init(uint32_t band_rate);unsigned char SYN6288_Send_Cmd(uint8_t CmdType, uint8_t CmdPar, uint8_t *text);#endif
移植验证

>>>

在自己工程中的main主函数中,编写如下。

/* * Change Logs: * Date           Author       Notes * 2024-06-25     LCKFB-LP    first version */#include "board.h"#include "stdio.h"#include "bsp_uart.h"#include "bsp_syn6288.h"
int32_t main(void){ board_init();
uart1_init(9600);
SYN6288_GPIO_Init(9600); printf("start\r\n"); delay_ms(1000);
SYN6288_Send_Cmd(0x01,0x00,(uint8_t *)"立创开发板");
while(1) {
}}

移植现象:模块播报"立创开发板"。

模块移植成功案例代码:

链接: https://pan.baidu.com/s/1eaj1otbe_v5xWZtn7We84w?pwd=LCKF

提取码:LCKF


END

往期回顾

REVIEW

【产品应用】CW32电动工具产品开源

【产品方案】基于CW32L010低成本电动工具方案

【产品应用】基于CW32的智能充电宝(方案开源)

【产品应用】CW-W88水泵通用控制板设计方案(已开源)

【产品应用】基于CW32的角磨机控制器产品方案

【产品方案】基于CW32F030C8的低压无刷风机无感控制器

【产品方案】基于CW32的无刷直流空心杯电机有感控制驱动方案

【产品方案】基于CW32的无刷直流空心杯电机无感方波控制驱动方案

【产品方案】基于CW32F003E4P7的数字电压电流表产品方案

【产品方案】CW32L010低成本工业仪表

CW32生态社区(WX)群



扫码加入QQ群

4群| 478586307

获取资料及 “开发者扶持计划” 第一手资讯









请到「今天看啥」查看全文