本帖最后由 hcm0915 于 2026-1-20 14:50 编辑
概述:
- TW_TTS共有六个引脚,分别是——地:G,电源:V(5V),输入:R,输出:T,喇叭+:SPK+(红线),喇叭-:SPK-(黑线)
注意: a. 语音模块使用 G、V、R 三引脚连接方案时,支持对语音合成播放模式的控制 b. 语音模块使用 G、V、R、T 四引脚连接方案时,满足原方案应用的同时,还具备语音合成芯片状态的查询功能
- 支持简体中文及英文单字母合成,兼容GB2312和UTF-8编码,能智能解析标点、多音字与数字,还可通过标记自定义发音和停顿,单次合成文本不超4K字节。
- 模块提供10级音量、语速、语调可调,默认中等档位,同时支持暂停、继续、停止合成等控制指令,操作灵活,满足不同场景下的语音输出需求。
- 内置15种提示音效,含5首铃声、5首信息提示音和5首警示音,分类清晰,可直接调用对应音效,丰富语音交互的多样性。
- 采用9600波特率的串口协议,1位起始位、8位数据位、1位停止位且无校验,通讯参数明确,连接上位机或MCU便捷。
语音合成模块指令协议表可以通过连接电脑进行串口指令调试:
指令类型 | 指令格式(十六进制) | 参数说明 | 播放实例(好好搭搭) | 0xFD 0x00 0x0A 0x01 0x00 0xBA 0xC3 0xBA 0xC3 0xB4 0xEE 0xB4 0xEE | 固定指令,用于播放 “好好搭搭” 音频 | 音量调整 | 0xFD 0x00 0x06 0x01 0x01 0x5B 0x76 0x(30-39) 0x5D | 0x30-0x39对应音量 [v0]- [v9]- v0音量最小,v9 音量最大- 默认音量 v5(对应 0x35) | 语速调整 | 0xFD 0x00 0x06 0x01 0x01 0x5B 0x73 0x(30-39) 0x5D | 0x30-0x39 对应语速 [s0]-[s9]- s0语速最快,s9语速最慢- 默认语速 s5(对应 0x35) | 语调调整 | 0xFD 0x00 0x06 0x01 0x01 0x5B 0x74 0x(30-39) 0x5D | - 0x30-0x39 对应语调 [t0]-[t9]- t0语调最低,t9 语调最高- 默认语调 t5(对应 0x35) | 停止合成 | 0xFD 0x00 0x01 0x02 | 无额外参数 | 暂停合成 | 0xFD 0x00 0x01 0x03 | 无额外参数 | 继续合成 | 0xFD 0x00 0x01 0x04 | 无额外参数 | 铃声播放 | 0xFD 0x00 0x08 0x01 0x01 0x72 0x69 0x6E 0x67 0x5F 0x(31-35) | 0x31-0x35对应铃声 1-5 | 提示音播放 | 0xFD 0x00 0x0B 0x01 0x01 0x6D 0x65 0x73 0x73 0x61 0x67 0x65 0x5F 0x(31-35) | 0x31-0x35对应提示音 1-5 | 警示音播放 | 0xFD 0x00 0x09 0x01 0x01 0x61 0x6C 0x65 0x72 0x74 0x5F 0x(31-35) | 0x31-0x35 对应警示音 1-5 | 查询播放状态 | 0xFD 0x00 0x01 0x21 | 无额外参数 | 播放状态返回值 | - | 0x4E:播放中 0x4F:空闲状态 |
STC89C52--C51
电路连接:
单片机的P3_0引脚(RX)连接语音合成模块的T引脚,单片机的P3_1引脚(TX)连接语音合成模块的R引脚 范例: C51串口控制播放语音
程序效果:
语音合成模块接入电源上电以后,C51单片机收到指令,控制语音合成播放“初始化完成”之后循环播放”你好“
STM32
电路连接:
STM32的PA9(TX)引脚接TW_TTS的(R)引脚,STM32的PA10(RX)引脚接TW_TTS的(T)引脚。
范例: stm32串口控制播放语音 TW_TTS.c - #include "usart.h"
- #include "TW_TTS.h"
- #include <string.h>
- // static TTS_PLAY[] = {0xfd, 0x00, 0x0a, 0x01, 0x00, 0xba, 0xc3, 0xba, 0xc3, 0xb4, 0xee, 0xb4, 0xee};
- static uint8_t TTS_VOLUME_CMD[] = {0xfd, 0x00, 0x06, 0x01, 0x01, 0x5b, 0x76, 0x30, 0x5d};
- static uint8_t TTS_SPEED_CMD[] = {0xfd, 0x00, 0x06, 0x01, 0x01, 0x5b, 0x73, 0x30, 0x5d};
- static uint8_t TTS_TONE_CMD[] = {0xfd, 0x00, 0x06, 0x01, 0x01, 0x5b, 0x74, 0x30, 0x5d};
- static uint8_t TTS_STOP_CMD[] = {0xfd, 0x00, 0x01, 0x02};
- static uint8_t TTS_PAUSE_CMD[] = {0xfd, 0x00, 0x01, 0x03};
- static uint8_t TTS_RESUME_CMD[] = {0xfd, 0x00, 0x01, 0x04};
- static uint8_t TTS_QUERY_CMD[] = {0xFD, 0x00, 0x02, 0x21, 0x00};
- void tts_writeData(unsigned char *DAT, unsigned char len)
- {
- HAL_UART_Transmit(&huart1,DAT,len,100);
- }
- /**
- * @brief 播放函数
- * @param str 播放内容(字符串)
- */
- void TTS_play(unsigned char* str)
- {
- unsigned char Frame_Info[50];
- uint16_t str_len = 0;
- str_len = strlen((char*)str);
-
- if (str_len == 0 || str_len > 4094) {
- return;
- }
- Frame_Info[0] = 0xFD ;
- Frame_Info[1] = 0x00 ;
- Frame_Info[2] = str_len + 2;
- Frame_Info[3] = 0x01 ;
- Frame_Info[4] = 0x00;
- // // 设置帧头后的数据长度字段
- Frame_Info[1] = (str_len + 2) >> 8;
- Frame_Info[2] = (str_len + 2) & 0xFF;
- // 发送帧头
- memcpy(&Frame_Info[5], str, str_len);
-
- tts_writeData(Frame_Info, 5+str_len);
-
- }
- /**
- * @brief 设置音量
- * @param vol 音量值,范围0-9,默认5
- */
- void TTS_volume(uint8_t vol)
- {
- uint8_t volume_buf[9];
- uint8_t i;
-
- if (vol > 9)
- {
- vol = 9;
- }
-
- // 复制常量数据到临时数组
- for(i = 0; i < 9; i++)
- {
- volume_buf = TTS_VOLUME_CMD;
- }
-
- volume_buf[7] = 0x30 + vol;
- tts_writeData(volume_buf, 9);
- }
- /**
- * @brief 设置播放速度
- * @param speed 速度值,范围0-9,默认5
- */
- void TTS_speed(uint8_t speed)
- {
- uint8_t speed_buf[9];
- uint8_t i;
-
- if (speed > 9)
- {
- speed = 9;
- }
-
- // 复制常量数据到临时数组
- for(i = 0; i < 9; i++)
- {
- speed_buf = TTS_SPEED_CMD;
- }
-
- speed_buf[7] = 0x30 + speed;
- tts_writeData(speed_buf, 9);
- }
- /**
- * @brief 设置语调
- * @param tone 语调值,范围0-9,默认5
- */
- void TTS_tone(uint8_t tone)
- {
- uint8_t tone_buf[9];
- uint8_t i;
-
- if (tone > 9)
- {
- tone = 9;
- }
-
- // 复制常量数据到临时数组
- for(i = 0; i < 9; i++)
- {
- tone_buf = TTS_TONE_CMD;
- }
-
- tone_buf[7] = 0x30 + tone;
- tts_writeData(tone_buf, 9);
- }
- /**
- * @brief 播报警示音
- * @param alert 警示音标号,1-5
- */
- void TTS_alert(uint8_t alert)
- {
- unsigned char str[8];
-
- if (alert < 1)
- {
- alert = 1;
- }
- else if (alert > 5)
- {
- alert = 5;
- }
-
- // 直接构造字符串,避免使用字符串常量
- str[0] = 'a';
- str[1] = 'l';
- str[2] = 'e';
- str[3] = 'r';
- str[4] = 't';
- str[5] = '_';
- str[6] = 0x30 + alert;
- str[7] = '\0';
-
- TTS_play(str);
- }
- /**
- * @brief 播报信息提示音
- * @param msg 标号,1-5
- */
- void TTS_play_msg(uint8_t msg)
- {
- unsigned char str[10];
-
- if (msg < 1)
- {
- msg = 1;
- }
- else if (msg > 5)
- {
- msg = 5;
- }
-
- str[0] = 'm';
- str[1] = 'e';
- str[2] = 's';
- str[3] = 's';
- str[4] = 'a';
- str[5] = 'g';
- str[6] = 'e';
- str[7] = '_';
- str[8] = 0x30 + msg;
- str[9] = '\0';
-
- TTS_play(str);
- }
- /**
- * @brief 播放铃声
- * @param ring 标号,1-5
- */
- void TTS_play_ring(uint8_t ring)
- {
- unsigned char str[7];
-
- if (ring < 1)
- {
- ring = 1;
- }
- else if (ring > 5)
- {
- ring = 5;
- }
-
- str[0] = 'r';
- str[1] = 'i';
- str[2] = 'n';
- str[3] = 'g';
- str[4] = '_';
- str[5] = 0x30 + ring;
- str[6] = '\0';
-
- TTS_play(str);
- }
- /**
- * @brief 停止播放
- */
- void TTS_stop(void)
- {
- uint8_t TW_tts_buf[4];
- uint8_t i;
-
- // 复制常量数据到临时数组
- for(i = 0; i < 4; i++)
- {
- TW_tts_buf = TTS_STOP_CMD;
- }
-
- tts_writeData(TW_tts_buf, 4);
- }
- /**
- * @brief 暂停播放
- */
- void TTS_pause(void)
- {
- uint8_t TW_tts_buf[4];
- uint8_t i;
-
- // 复制常量数据到临时数组
- for(i = 0; i < 4; i++)
- {
- TW_tts_buf = TTS_PAUSE_CMD;
- }
-
- tts_writeData(TW_tts_buf, 4);
- }
- /**
- * @brief 继续播放
- */
- void TTS_resume(void)
- {
- uint8_t TW_tts_buf[4];
- uint8_t i;
-
- // 复制常量数据到临时数组
- for(i = 0; i < 4; i++)
- {
- TW_tts_buf = TTS_RESUME_CMD;
- }
-
- tts_writeData(TW_tts_buf, 4);
- }
- /**
- * @brief 读取CITW-TTS芯片当前播放状态
- */
- uint8_t TTS_queryState(uint8_t response)
- {
- uint8_t query_buf[5];
- uint8_t i;
-
- // 复制常量数据到临时数组
- for(i = 0; i < 5; i++)
- {
- query_buf = TTS_QUERY_CMD;
- }
-
- // 发送查询命令
- tts_writeData(query_buf, 5);
-
- // 短暂延时等待响应
- HAL_Delay(10);
- // 检查串口接收标志
-
- if (response == 0x4E)
- {
- return TTS_STATE_PLAYING; // 播放中
- }
- else if (response == 0x4F)
- {
- return TTS_STATE_IDLE; // 空闲
- }
- else if (response == 0x4A)
- {
- return TTS_STATE_INIT; // 初始化
- }
- else if (response == 0x41)
- {
- return TTS_STATE_CHECK; // 检查
- }
- else
- {
- return TTS_STATE_ERROR; // 查询失败(命令错误)
- }
- }
复制代码TW_TTS.h - #ifndef __TW_TTS_H
- #define __TW_TTS_H
- #define TTS_STATE_ERROR 0 // 查询失败(命令错误)
- #define TTS_STATE_PLAYING 1 // 播放中(对应芯片返回0x4E)
- #define TTS_STATE_IDLE 2 // 空闲(对应芯片返回0x4F)
- #define TTS_STATE_INIT 3 // 初始化(对应芯片返回0x4A)
- #define TTS_STATE_CHECK 4 // 检查(对应芯片返回0x41)
- void tts_writeData(unsigned char *DAT, unsigned char len);
- void TTS_play(unsigned char* str);
- void TTS_volume(uint8_t vol);
- void TTS_speed(uint8_t speed);
- void TTS_tone(uint8_t tone);
- void TTS_alert(uint8_t alert);
- void TTS_play_msg(uint8_t msg);
- void TTS_play_ring(uint8_t ring);
- void TTS_stop(void);
- void TTS_pause(void);
- void TTS_resume(void);
- uint8_t TTS_queryState(uint8_t response);
- #endif
- uart.c
- /**
- ******************************************************************************
- * @file usart.c
- * @brief This file provides code for the configuration
- * of the USART instances.
- ******************************************************************************
- * @attention
- *
- * <h2><center>© Copyright (c) 2025 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
- */
- /* Includes ------------------------------------------------------------------*/
- #include "usart.h"
- /* USER CODE BEGIN 0 */
- /* USER CODE END 0 */
- UART_HandleTypeDef huart1;
- UART_HandleTypeDef huart2;
- /* USART1 init function */
- void MX_USART1_UART_Init(void)
- {
- huart1.Instance = USART1;
- huart1.Init.BaudRate = 9600;
- huart1.Init.WordLength = UART_WORDLENGTH_8B;
- huart1.Init.StopBits = UART_STOPBITS_1;
- huart1.Init.Parity = UART_PARITY_NONE;
- huart1.Init.Mode = UART_MODE_TX_RX;
- huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
- huart1.Init.OverSampling = UART_OVERSAMPLING_16;
- if (HAL_UART_Init(&huart1) != HAL_OK)
- {
- Error_Handler();
- }
- }
- /* USART2 init function */
- void MX_USART2_UART_Init(void)
- {
- huart2.Instance = USART2;
- huart2.Init.BaudRate = 9600;
- huart2.Init.WordLength = UART_WORDLENGTH_8B;
- huart2.Init.StopBits = UART_STOPBITS_1;
- huart2.Init.Parity = UART_PARITY_NONE;
- huart2.Init.Mode = UART_MODE_TX_RX;
- huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
- huart2.Init.OverSampling = UART_OVERSAMPLING_16;
- if (HAL_UART_Init(&huart2) != HAL_OK)
- {
- Error_Handler();
- }
- }
- void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
- {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- if(uartHandle->Instance==USART1)
- {
- /* USER CODE BEGIN USART1_MspInit 0 */
- /* USER CODE END USART1_MspInit 0 */
- /* USART1 clock enable */
- __HAL_RCC_USART1_CLK_ENABLE();
- __HAL_RCC_GPIOA_CLK_ENABLE();
- /**USART1 GPIO Configuration
- PA9 ------> USART1_TX
- PA10 ------> USART1_RX
- */
- GPIO_InitStruct.Pin = GPIO_PIN_9;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
- GPIO_InitStruct.Pin = GPIO_PIN_10;
- GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
- /* USART1 interrupt Init */
- HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
- HAL_NVIC_EnableIRQ(USART1_IRQn);
- /* USER CODE BEGIN USART1_MspInit 1 */
- /* USER CODE END USART1_MspInit 1 */
- }
- else if(uartHandle->Instance==USART2)
- {
- /* USER CODE BEGIN USART2_MspInit 0 */
- /* USER CODE END USART2_MspInit 0 */
- /* USART2 clock enable */
- __HAL_RCC_USART2_CLK_ENABLE();
- __HAL_RCC_GPIOA_CLK_ENABLE();
- /**USART2 GPIO Configuration
- PA2 ------> USART2_TX
- PA3 ------> USART2_RX
- */
- GPIO_InitStruct.Pin = GPIO_PIN_2;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
- GPIO_InitStruct.Pin = GPIO_PIN_3;
- GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
- /* USART2 interrupt Init */
- HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
- HAL_NVIC_EnableIRQ(USART2_IRQn);
- /* USER CODE BEGIN USART2_MspInit 1 */
- /* USER CODE END USART2_MspInit 1 */
- }
- }
- void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
- {
- if(uartHandle->Instance==USART1)
- {
- /* USER CODE BEGIN USART1_MspDeInit 0 */
- /* USER CODE END USART1_MspDeInit 0 */
- /* Peripheral clock disable */
- __HAL_RCC_USART1_CLK_DISABLE();
- /**USART1 GPIO Configuration
- PA9 ------> USART1_TX
- PA10 ------> USART1_RX
- */
- HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
- /* USART1 interrupt Deinit */
- HAL_NVIC_DisableIRQ(USART1_IRQn);
- /* USER CODE BEGIN USART1_MspDeInit 1 */
- /* USER CODE END USART1_MspDeInit 1 */
- }
- else if(uartHandle->Instance==USART2)
- {
- /* USER CODE BEGIN USART2_MspDeInit 0 */
- /* USER CODE END USART2_MspDeInit 0 */
- /* Peripheral clock disable */
- __HAL_RCC_USART2_CLK_DISABLE();
- /**USART2 GPIO Configuration
- PA2 ------> USART2_TX
- PA3 ------> USART2_RX
- */
- HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
- /* USART2 interrupt Deinit */
- HAL_NVIC_DisableIRQ(USART2_IRQn);
- /* USER CODE BEGIN USART2_MspDeInit 1 */
- /* USER CODE END USART2_MspDeInit 1 */
- }
- }
- /* USER CODE BEGIN 1 */
- /* USER CODE END 1 */
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码main.c - /* USER CODE BEGIN Header */
- /**
- ******************************************************************************
- * @file : main.c
- * @brief : Main program body
- ******************************************************************************
- * @attention
- *
- * <h2><center>© Copyright (c) 2025 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
- */
- /* USER CODE END Header */
- /* Includes ------------------------------------------------------------------*/
- #include "main.h"
- #include "usart.h"
- #include "gpio.h"
- #include "TW_TTS.h"
- /* Private includes ----------------------------------------------------------*/
- /* USER CODE BEGIN Includes */
- uint8_t rec1Byte;
- uint8_t rec2Byte;
- /* USER CODE END Includes */
- /* Private typedef -----------------------------------------------------------*/
- /* USER CODE BEGIN PTD */
- /* USER CODE END PTD */
- /* Private define ------------------------------------------------------------*/
- /* USER CODE BEGIN PD */
- /* USER CODE END PD */
- /* Private macro -------------------------------------------------------------*/
- /* USER CODE BEGIN PM */
- /* USER CODE END PM */
- /* Private variables ---------------------------------------------------------*/
- /* USER CODE BEGIN PV */
- /* USER CODE END PV */
- /* Private function prototypes -----------------------------------------------*/
- void SystemClock_Config(void);
- /* USER CODE BEGIN PFP */
- /* USER CODE END PFP */
- /* Private user code ---------------------------------------------------------*/
- /* USER CODE BEGIN 0 */
- /* USER CODE END 0 */
- /**
- * @brief The application entry point.
- * @retval int
- */
- int main(void)
- {
- /* USER CODE BEGIN 1 */
- /* USER CODE END 1 */
- /* MCU Configuration--------------------------------------------------------*/
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
- HAL_Init();
- /* USER CODE BEGIN Init */
- /* USER CODE END Init */
- /* Configure the system clock */
- SystemClock_Config();
- /* USER CODE BEGIN SysInit */
- /* USER CODE END SysInit */
- /* Initialize all configured peripherals */
- MX_GPIO_Init();
- MX_USART1_UART_Init();
- MX_USART2_UART_Init();
- /* USER CODE BEGIN 2 */
- HAL_UART_Receive_IT(&huart1, &rec1Byte, sizeof(rec1Byte));//打开串口接收中断
- HAL_UART_Receive_IT(&huart2, &rec2Byte, sizeof(rec2Byte));//打开串口接收中断
- /* USER CODE END 2 */
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- TTS_volume(1);
- while (1)
- {
-
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
- if(TTS_queryState(rec1Byte)==TTS_STATE_INIT)
- {
- HAL_Delay(100);
- TTS_play("初始化完成");
- HAL_Delay(2000);
- }
- TTS_play("好好搭搭");
- HAL_Delay(2000);
- }
- /* USER CODE END 3 */
- }
- /**
- * @brief System Clock Configuration
- * @retval None
- */
- void SystemClock_Config(void)
- {
- RCC_OscInitTypeDef RCC_OscInitStruct = {0};
- RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
- /** Initializes the RCC Oscillators according to the specified parameters
- * in the RCC_OscInitTypeDef structure.
- */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
- RCC_OscInitStruct.HSEState = RCC_HSE_ON;
- RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
- RCC_OscInitStruct.HSIState = RCC_HSI_ON;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
- RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
- if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
- {
- Error_Handler();
- }
- /** Initializes the CPU, AHB and APB buses clocks
- */
- RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
- |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
- {
- Error_Handler();
- }
- }
- /* USER CODE BEGIN 4 */
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
- {
- if (huart == &huart1)
- {
- HAL_UART_Transmit(&huart2, &rec1Byte, 1, 100);
- }
-
- HAL_UART_Receive_IT(&huart1, &rec1Byte, 1);
-
- if (huart == &huart2)
- {
- HAL_UART_Transmit(&huart2, &rec2Byte, 1, 100);
- }
- HAL_UART_Receive_IT(&huart2, &rec2Byte, 1);
- }
- /* USER CODE END 4 */
- /**
- * @brief This function is executed in case of error occurrence.
- * @retval None
- */
- void Error_Handler(void)
- {
- /* USER CODE BEGIN Error_Handler_Debug */
- /* User can add his own implementation to report the HAL error return state */
- __disable_irq();
- while (1)
- {
- }
- /* USER CODE END Error_Handler_Debug */
- }
- #ifdef USE_FULL_ASSERT
- /**
- * @brief Reports the name of the source file and the source line number
- * where the assert_param error has occurred.
- * @param file: pointer to the source file name
- * @param line: assert_param error line source number
- * @retval None
- */
- void assert_failed(uint8_t *file, uint32_t line)
- {
- /* USER CODE BEGIN 6 */
- /* User can add his own implementation to report the file name and line number,
- ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
- /* USER CODE END 6 */
- }
- #endif /* USE_FULL_ASSERT */
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码 程序效果:语音合成模块上电播放:“初始化完成”,之后每两秒播放一次“好好搭搭” 串口1用于控制语音合成模块,串口2查看语音合成播放的信息。
Arduino电路连接:
Arduino端程序 范例:Arduino控制语音合成播放- #include "Arduino.h"
- #include "Wire.h"
- #include "Servo.h"
- #include "SoftwareSerial.h"
- #include "TW_TTS.h"
- TW_TTS syn;
- void setup()
- {
- syn.begin();
- }
- void loop()
- {
- if(syn.tts_queryState()==TTS_STATE_INIT){
- syn.tts_play("初始化完成");
- delay(2000);
- }
- syn.tts_play("你好");
- delay(2000);
- }
复制代码 程序效果:语音合成模块上电播放:“初始化完成”,之后每两秒播放一次“你好”
esp32 电路连接:
esp32c3的引脚0(TX)连接语音合成模块的R引脚,esp32c3的引脚1(RX)连接语音合成模块的T引脚 范例: esp32实时天气时钟播报(好搭 Block 案例)
范例: esp32实时天气时钟播报(字符代码编程案例) TW_TTS.py - from machine import UART
- from machine import Pin
- TTS_STATE_ERROR = 0
- TTS_STATE_PLAYING = 1
- TTS_STATE_IDLE = 2
- TTS_STATE_INIT = 3
- TTS_STATE_CHECK = 4
- '''
- 协议格式
- 帧头 数据长度 命令字 编码参数 文本
- 0xfd 0x00 0xLL 0x01 0x00 text(n字节)
- '''
- class TW_TTS:
- #全局变量,保存编码格式
- #0x00:GB2312编码,目前只支持GB2312
- global code_type
- code_type = 0x0
- def __init__(self,tx_pin,rx_pin):
- self.uart = UART(1, baudrate=9600, tx=tx_pin, rx=rx_pin, timeout=10)
- #向芯片发送数据
- def write(self,dat):
- if type(dat) == type('a'):
- self.uart.write(dat)
- else:
- self.uart.write(bytes(dat))
- #设置文字编码
- def set_code(self,code):
- global code_type
- code_type = code
-
- #播放语音
- def play(self, str):
- global code_type
- asr_tts_buf = [0xfd,0x00,0x00,0x01,code_type]
- #最大支持4K字节文本
- asr_tts_buf[1] = (len(str) + 2)//256
- asr_tts_buf[2] = (len(str) + 2)%256
- asr_tts_buf.extend(str)
- # print(asr_tts_buf)
- self.uart.write(bytes(asr_tts_buf))
- #设置音量,vol:音量:0-9,默认5,音量0为静音
- def volume(self,vol):
- volume_buf = [0xfd,0x00,0x06,0x01,0x01,0x5b,0x76,0x30,0x5d]
- volume_buf[7] = (0x30 + vol)
- self.uart.write(bytes(volume_buf))
-
- #设置语音播报速度 0-9,默认5
- def speed(self,spd):
- speed_buf = [0xfd,0x00,0x06,0x01,0x01,0x5b,0x73,0x30,0x5d]
- speed_buf[7] = (0x30 + spd)
- self.uart.write(bytes(speed_buf))
-
- #设置语音播报语调 0-9,默认5
- def tone(self,tone):
- speed_buf = [0xfd,0x00,0x06,0x01,0x01,0x5b,0x74,0x30,0x5d]
- speed_buf[7] = (0x30 + tone)
- self.uart.write(bytes(speed_buf))
- #播报警示音,index:1-5
- def play_alert(self,index):
- if index > 5:
- index = 5
- str = "alert_" + chr(0x30+index)
- self.set_code(0)
- self.play(bytes(str,'utf_8'))
- self.set_code(code_type)
- #播报信息提示音,index:1-5
- def play_msg(self,index):
- if index > 5:
- index = 5
- str = "message_" + chr(0x30+index)
- self.play(bytes(str,'utf_8'))
- #播报铃声,index:1-5
- def play_ring(self,index):
- if index > 5:
- index = 5
- str = "ring_" + chr(0x30+index)
- self.set_code(0)
- self.play(bytes(str,'utf_8'))
- self.set_code(code_type)
- #停止播报
- def stop(self):
- buf = [0xfd,0x00,0x01,0x02]
- self.uart.write(bytes(buf))
- #暂停播报
- def pause(self):
- buf = [0xfd,0x00,0x01,0x03]
- self.uart.write(bytes(buf))
- #继续播报
- def resume(self):
- buf = [0xfd,0x00,0x01,0x04]
- self.uart.write(bytes(buf))
- def queryState(self):
- buf = [0xFD, 0x00, 0x02, 0x21, 0x00]
- self.uart.write(bytes(buf))
- response = self.uart.read() # 返回bytes或None
-
- # 修正:先判断响应是否存在,再提取字节比较
- if response and len(response) > 0:
- resp_byte = response[0] # 提取响应的第一个字节
- if resp_byte == 0x4E:
- return TTS_STATE_PLAYING
- elif resp_byte == 0x4F:
- return TTS_STATE_IDLE
- elif resp_byte == 0x4A:
- return TTS_STATE_INIT
- elif resp_byte == 0x41:
- return TTS_STATE_CHECK
- # 无有效响应返回错误状态
- return TTS_STATE_ERROR
复制代码main.py - from machine import Pin
- from machine import UART
- from TW_TTS import TW_TTS, TTS_STATE_ERROR, TTS_STATE_PLAYING, TTS_STATE_IDLE, TTS_STATE_INIT, TTS_STATE_CHECK
- from board import *
- import network
- import time
- from machine import RTC
- import ntptime
- import urequests
- import json
- import ujson
- my_wifi = wifi()
- rtc = RTC()
- def 时间校准():
- global tts_text, 今日风向, 今天夜晚天气现象, 今天白天天气现象, 最高气温, 最低气温, 日, 月, 年, 秒, 分, 时, 今日风速, 星期, daily_list, 后天最高气温, 后天最低气温, 明天最高气温, 明天最低气温, 后台天气现象, 明天天气现象, 今日湿度, results_list, location_list, text_dict, _response
- ntptime.settime(8,"ntp3.aliyun.com")
- 年 = rtc.datetime()[0]
- 月 = rtc.datetime()[1]
- 日 = rtc.datetime()[2]
- 星期 = rtc.datetime()[3]
- 时 = rtc.datetime()[4]
- 分 = rtc.datetime()[5]
- 秒 = rtc.datetime()[6]
- def 天气判断():
- global tts_text, 今日风向, 今天夜晚天气现象, 今天白天天气现象, 最高气温, 最低气温, 日, 月, 年, 秒, 分, 时, 今日风速, 星期, daily_list, 后天最高气温, 后天最低气温, 明天最高气温, 明天最低气温, 后台天气现象, 明天天气现象, 今日湿度, results_list, location_list, text_dict, _response
- print('获取温度,不同天气显示不同图案', end='')
- _response = urequests.get('http://www.haohaodada.com/project/weather/',headers={},timeout=10)
- text_dict = ujson.loads((_response.text))
- results_list = text_dict.get('results')
- location_list = results_list[0].get('location')
- daily_list = results_list[0].get('daily')
- 最高气温 = str(daily_list[0].get('high'))
- 最低气温 = str(daily_list[0].get('low'))
- 今天白天天气现象 = str(daily_list[0].get('text_day'))
- 今天夜晚天气现象 = str(daily_list[0].get('text_night'))
- 今日风速 = str(daily_list[0].get('wind_scale'))
- 今日风向 = str(daily_list[0].get('wind_direction'))
- 今日湿度 = str(daily_list[0].get('humidity'))
- 明天天气现象 = str(daily_list[1].get('text_day'))
- 后台天气现象 = str(daily_list[2].get('text_day'))
- 明天最低气温 = str(daily_list[1].get('low'))
- 明天最高气温 = str(daily_list[1].get('high'))
- 后天最低气温 = str(daily_list[2].get('low'))
- 后天最高气温 = str(daily_list[2].get('high'))
- syn=TW_TTS(0,1)
- IO09 = BoardPin(9, PinMode.IN, pull=None)
- my_wifi.connectWiFi('haoda7', '0123456789')
- while not my_wifi.sta.isconnected():
- time.sleep_ms(1)
- 时间校准()
- 天气判断()
- while True:
- 时 = rtc.datetime()[4]
- 分 = rtc.datetime()[5]
- 秒 = rtc.datetime()[6]
- oled.fill(0)
- oled.DispChar(str((''.join([str(x) for x in [年, '年', 月, '/', 日]]))), 0, 0, 1)
- oled.DispChar(str((''.join([str(x2) for x2 in [时, ':', 分, ':', 秒]]))), 0, 16, 1)
- oled.DispChar(str((''.join([str(x3) for x3 in [最低气温, '℃ - ', 最高气温, '℃', ' ', 今天白天天气现象]]))), 0, 32, 1)
- oled.DispChar(str((''.join([str(x4) for x4 in [今日风向, '风 ', 今日风速, 'm/s']]))), 0, 48, 1)
- oled.show()
- if 时 == 0 and 分 == 0 and 秒 == 1:
- print('每日凌晨校准时间', end='')
- syn.set_code(0x04)
- syn.play(bytes('每日凌晨校准时间', 'utf-8'))
- 时间校准()
- if 分 % 5 == 0 and 秒 == 0:
- print('每五分钟刷新一次天气', end='')
- syn.set_code(0x04)
- syn.play(bytes('每五分钟刷新一次天气', 'utf-8'))
- 天气判断()
- if IO09.read_digital() == 0:
- time.sleep_ms(10)
- if IO09.read_digital() == 0:
- while IO09.read_digital() == 0:
- pass
- tts_text = ''.join([str(x5) for x5 in ['今天是', 年, '年', 月, '月', 日, '日,', '最低气温', 最低气温, '摄氏度,', '最高气温', 最高气温, '摄氏度,', '今天白天', 今天白天天气现象, ',晚间', 今天夜晚天气现象, ',', 今日风向, '风']])
- syn.set_code(0x04)
- syn.play(bytes(tts_text, 'utf-8'))
复制代码 程序效果:esp32WiFi连接,实时从网络获取天气数据,通过按键触发播放当前天气数据。
ASRPRO电路连接:
ASRPRO的PA2(TX)引脚接TW_TTS的(R)引脚,ASRPRO的PA3(RX)引脚接TW_TTS的(T)引脚。
范例:ASRPRO控制语音合成播放指定文字
程序效果: 通过语音指令触发指定散文文本的 TTS 朗读,支持暂停 / 继续 / 停止等播放控制 。
STC8 电路连接:
本案例以P5_0为RX,P5_1为TX举例。P5_0与TW_TTS的T连接,P5_1与TW_TTS的R连接注意STC8的电源插脚接到5V,GND引脚互相连接。
范例: STC8串口控制播放语音
程序效果: 语音合成模块上电播放:“初始化完成”,之后每两秒播放一次“好好搭搭”
米思齐esp32 电路连接:
范例: esp32串口控制播放语音
程序效果:语音合成模块上电播放:“初始化完成”,语音合成空闲状态播放铃声1,之后每两秒播放一次“好好搭搭”
MIND+ arduino UNO 电路连接:
范例: arduino串口控制播放语音
程序效果:上电初始化完成播放:“初始化完成”,模块结束播放状态则播放一段铃声,随后循环播放:“欢迎使用语音合成模块”
TW32F003 电路连接:
TW32的PA0(TX)引脚接TW_TTS的(R)引脚,TW32的PA1(RX)引脚接TW_TTS的(T)引脚。
范例:TW32F003控制语音合成播放指定文字
程序效果: 上电初始化以后,语音合成会发出:“初始化完成”的语音提醒。语音合成当前状态会通过串口打印出来:
附录
TW_TTS.zip
(14.14 MB, 下载次数: 108)
|