当前位置:   article > 正文

su-03t语音模块固件的制作与烧录(stm32实战)_su03t链接32

su03t链接32

目录

su-03t简介

管脚定义

​​智能公元语音固件制作​​

账号注册

创建产品

产品配置

唤醒词自定义

命令词自定义

发音人配置

其他配置

生成和下载语音固件

固件烧录

下载SDK固件烧录工具

SU-03T驱动分享


su-03t简介

SU-03T 是一款低成本、低功耗、小体积的离线语音识别模组,能快速应用于智能家居,各类智能小家电,86 盒,玩具,灯具等需要语音操控的产品,SU-03T也具备强大的软件开发能力,我们可以在“​​智能公元​​”平台上实现语音固件的零代码开发,提高工作效率。

管脚定义

其中需要注意的是UART0的B0、B1是调试器的语音固件烧录口,串口烧录则选择UART1的B6、B7引脚,当固件烧录完成之后则可以使用UART1的B2、B3 引脚和MCU进行通信。

​智能公元语音固件制作​

账号注册

打开​智能公元​网页进行账号注册

创建产品

产品配置

创建产品成功后会进入产品配置,在大部分情况下都可以使用默认配置,我们只需要关注以下几个配置即可:

唤醒词自定义

唤醒词自定义可以定义语音模块的唤醒词以及唤醒之后的回复,用于唤醒语音模块,开始使用自定义命令词与模块进行语音交互

命令词自定义

命令词自定义可以自己定义的关键词来控制语音模块,例如“开灯”、“关灯”等,免唤醒的命令词可以不需要使用唤醒词直接和模块进行交互。

发音人配置

发音人配置可以用来配置语音模块的音色、音调和语速。

其他配置

生成和下载语音固件

固件烧录

下载SDK固件烧录工具

在SDK固件包的 uni_hb_m_solution-121028-20230920\uni_hb_m_solution\image_demo\Hummingbird-M-Update-Tool 下可以看到以下文件

UniOneUpdateTool.exe为串口烧录工具

USB_Update_Tool_User_Guide.pdf为烧录指导书,写的很详细,跟着烧录即可

SU-03T驱动分享

  1. #include "su_03t.h"
  2. uint8_t usart_su_RXdata; //存放接收数据寄存器的值
  3. uint8_t usart_su_RXflag; //接收数据标志位
  4. uint8_t usart_su_RXpacket[6] = {0}; //hex数据包接收数组
  5. uint8_t usart_su_TXpacket[14] = {0}; //hex数据包接收数组
  6. /**
  7. * @brief 配置串口 PC10 发送复用推挽 PC11 接收浮空模式
  8. * @param None
  9. * @retval None
  10. */
  11. void su_o3t_init(void){
  12. //初始化GPIO口
  13. //PA9复用推挽
  14. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  15. GPIO_InitTypeDef GPIO_InitStructure;
  16. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  17. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  18. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  19. GPIO_Init(GPIOC, &GPIO_InitStructure);
  20. //PA10浮空
  21. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  22. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  23. GPIO_Init(GPIOC, &GPIO_InitStructure);
  24. //串口初始化
  25. //开启串口时钟
  26. RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
  27. //初始化串口
  28. USART_InitTypeDef USART_InitStruct = {0};
  29. USART_InitStruct.USART_BaudRate = 115200; //设置波特率
  30. USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制失能
  31. USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //选择串口发送模式和接收模式
  32. USART_InitStruct.USART_Parity = USART_Parity_No; //不需要校验
  33. USART_InitStruct.USART_StopBits = USART_StopBits_1; //一位停止位
  34. USART_InitStruct.USART_WordLength = USART_WordLength_8b; //字长选择8位
  35. USART_Init(UART4, &USART_InitStruct);
  36. //开启串口中断
  37. USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);
  38. //初始化NVIC
  39. //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  40. NVIC_InitTypeDef NVIC_InitStruct;
  41. NVIC_InitStruct.NVIC_IRQChannel = UART4_IRQn;
  42. NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  43. NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 4;
  44. NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
  45. NVIC_Init(&NVIC_InitStruct);
  46. //使能串口
  47. USART_Cmd(UART4, ENABLE);
  48. }
  49. /**
  50. * @brief 串口一中断服务函数,接收一个字节的数据,并将标志位置1
  51. * hex数据包 长度 6 开始标志位 0xAA
  52. * @param None
  53. * @retval None
  54. */
  55. void UART4_IRQHandler(void){
  56. static uint8_t RX_su_State = 0;
  57. static uint8_t su_pRXpacket = 0;
  58. //usart_init();
  59. if(USART_GetITStatus(UART4, USART_IT_RXNE) == SET){
  60. USART_ClearITPendingBit(UART4, USART_IT_RXNE);
  61. //usart_send_string("y");
  62. usart_su_RXdata = USART_ReceiveData(UART4);
  63. //判断接收的数据包头
  64. if(RX_su_State == 0){
  65. if(usart_su_RXdata == 0XAA){ //接收到的使hex文件
  66. usart_su_RXpacket[0] = usart_su_RXdata;
  67. RX_su_State = 1;
  68. su_pRXpacket = 1;
  69. }
  70. }
  71. else if(RX_su_State == 1){ //接收hex文件的内容
  72. usart_su_RXpacket[su_pRXpacket] = usart_su_RXdata;
  73. su_pRXpacket++;
  74. if(su_pRXpacket >= 5){ //接收数据包长度位4的数据
  75. RX_su_State = 2;
  76. }
  77. }
  78. else if(RX_su_State == 2){ //判断hex数据包结束标志位
  79. if(usart_su_RXdata == 0XAA){
  80. usart_send_array(USART1, usart_su_RXpacket,6);
  81. usart_su_RXpacket[su_pRXpacket] = usart_su_RXdata;
  82. RX_su_State = 0;
  83. usart_su_RXflag = 1;
  84. }
  85. else{
  86. RX_su_State = 0;
  87. usart_su_RXflag = 0;
  88. usart_send_array(USART1, usart_su_RXpacket,6);
  89. usart_su_RXpacket[su_pRXpacket] = usart_su_RXdata;
  90. //usart_send_string("$");
  91. }
  92. }
  93. }
  94. }
  95. /**
  96. * @brief 获取usart_su_flag的值
  97. * @param None
  98. * @retval usart_su_RXflag 串口2接收标志位
  99. */
  100. uint8_t usart_get_su_RXflag(void){
  101. if(usart_su_RXflag == 1){
  102. usart_su_RXflag = 0;
  103. return 1;
  104. }
  105. return 0;
  106. }
  107. /**
  108. * @brief 处理su_03t的数据
  109. * @param None
  110. * @retval None
  111. */
  112. void vioce_analysis(void){
  113. //usart_send_array(usart_su_RXpacket, 5);
  114. time_t rawtime;
  115. struct tm *info = NULL;
  116. //info = localtime(&rawtime);
  117. if(usart_get_su_RXflag() == 1){
  118. //char str[5] = {0};
  119. switch(usart_su_RXpacket[3]){
  120. case 0x01: //温度
  121. usart_su_TXpacket[0] = 0XAA;
  122. usart_su_TXpacket[1] = 0X55;
  123. usart_su_TXpacket[3] = dht_data.tmp;
  124. usart_su_TXpacket[4] = dht_data.tmp_flo;
  125. usart_su_TXpacket[5] = 0X55;
  126. usart_su_TXpacket[6] = 0XAA;
  127. if(dht_data.tmp_flag == 0){ //温度为正
  128. usart_su_TXpacket[2] = 0x02;
  129. }
  130. else{
  131. usart_su_TXpacket[2] = 0x09;
  132. }
  133. usart_send2su_array(usart_su_TXpacket, 6);
  134. break;
  135. case 0x02://湿度
  136. usart_su_TXpacket[0] = 0XAA;
  137. usart_su_TXpacket[1] = 0X55;
  138. usart_su_TXpacket[2] = 0X03;
  139. usart_su_TXpacket[3] = dht_data.hum;
  140. usart_su_TXpacket[4] = 0X55;
  141. usart_su_TXpacket[5] = 0XAA;
  142. usart_send2su_array(usart_su_TXpacket, 6);
  143. break;
  144. case 0x03://空气成分
  145. usart_su_TXpacket[0] = 0XAA;
  146. usart_su_TXpacket[1] = 0X55;
  147. usart_su_TXpacket[2] = 0X01;
  148. usart_su_TXpacket[6] = 0X55;
  149. usart_su_TXpacket[7] = 0XAA;
  150. //sprintf(str,"0x%x",(int)(kqm_data.VOC * 100));
  151. //usart_su_TXpacket[4] = atoi(str);
  152. usart_su_TXpacket[3] = (uint8_t)(kqm_data.VOC * 100);
  153. // printf("%d", usart_su_TXpacket[3]);
  154. usart_su_TXpacket[4] = (uint8_t)(kqm_data.CHO * 100);
  155. //printf("%d", usart_su_TXpacket[4]);
  156. usart_su_TXpacket[5] = kqm_data.CO2;
  157. // printf("%d", usart_su_TXpacket[5]);
  158. usart_send2su_array(usart_su_TXpacket, 8);
  159. // usart_send_array(usart_su_TXpacket,8);
  160. break;
  161. case 0x04://开灯
  162. led_enable(LED1);
  163. break;
  164. case 0x05://关灯
  165. led_disable(LED1);
  166. break;
  167. case 0x06://甲烷
  168. usart_su_TXpacket[0] = 0XAA;
  169. usart_su_TXpacket[1] = 0X55;
  170. usart_su_TXpacket[3] = (uint8_t)(kqm_data.CHO * 100);
  171. usart_su_TXpacket[4] = 0X55;
  172. usart_su_TXpacket[5] = 0XAA;
  173. if(kqm_data.CHO <0.03){
  174. usart_su_TXpacket[2] = 0x04;
  175. }
  176. else if(kqm_data.CHO >=0.03 && kqm_data.CHO <0.1){
  177. usart_su_TXpacket[2] = 0x05;
  178. }
  179. else{
  180. usart_su_TXpacket[2] = 0x06;
  181. }
  182. usart_send2su_array(usart_su_TXpacket, 6);
  183. break;
  184. case 0x07://开启蜂鸣器
  185. buzzer_enable();
  186. break;
  187. case 0x08://关闭蜂鸣器
  188. buzzer_disable();
  189. break;
  190. case 0x9://二氧化碳
  191. usart_su_TXpacket[0] = 0XAA;
  192. usart_su_TXpacket[1] = 0X55;
  193. usart_su_TXpacket[2] = 0x07;
  194. usart_su_TXpacket[3] = kqm_data.CO2;
  195. usart_su_TXpacket[4] = 0X55;
  196. usart_su_TXpacket[5] = 0XAA;
  197. usart_send2su_array(usart_su_TXpacket, 6);
  198. break;
  199. case 0x10://时间
  200. rawtime = RTC_GetCounter();
  201. info = localtime(&rawtime);
  202. //info=gmtime(&rawtime);
  203. usart_su_TXpacket[0] = 0XAA;
  204. usart_su_TXpacket[1] = 0X55;
  205. usart_su_TXpacket[2] = 0x08;
  206. usart_su_TXpacket[3] = (info->tm_year + 1900) / 1000;
  207. usart_su_TXpacket[4] = ((info->tm_year + 1900) / 100) % 10;
  208. usart_su_TXpacket[5] = ((info->tm_year + 1900) / 10) % 100;
  209. usart_su_TXpacket[6] = (info->tm_year + 1900) % 10;
  210. usart_su_TXpacket[7] = info->tm_mon + 1;
  211. usart_su_TXpacket[8] = info->tm_mday;
  212. usart_su_TXpacket[9] = info->tm_hour;
  213. usart_su_TXpacket[10] = info->tm_min;
  214. usart_su_TXpacket[11] = info->tm_sec;
  215. usart_su_TXpacket[12] = 0X55;
  216. usart_su_TXpacket[13] = 0XAA;
  217. usart_send_array(USART1, usart_su_TXpacket, 14);
  218. printf("%d\t%d\t%d\t%d\t", info->tm_year, info->tm_mon, info->tm_mday, info->tm_hour);
  219. usart_send2su_array(usart_su_TXpacket, 14);
  220. break;
  221. }
  222. }
  223. }
  224. /**
  225. * @brief 发送一个数组
  226. * @param uint8_t *array 需要发送的数组
  227. * @param uint16_t len 发送的数组长度
  228. * @retval None
  229. */
  230. void usart_send2su_array(uint8_t *array, uint16_t len){
  231. uint16_t i = 0;
  232. for(i = 0; i < len; i++){
  233. usart_send2su_bit(array[i]);
  234. }
  235. }
  236. /**
  237. * @brief 发送单个字节
  238. * @param uint8_t data 需要发送的字节
  239. * @retval None
  240. */
  241. void usart_send2su_bit(uint8_t data){
  242. while(USART_GetFlagStatus(UART4, USART_FLAG_TC) != 1); //等待上一次数据发送完成
  243. USART_SendData(UART4, data); //发送数据
  244. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/535029
推荐阅读
相关标签
  

闽ICP备14008679号