池州商城网站开发,旅游最新资讯 新闻,西安中风险地区有哪些,如何做企业网站php文章目录 需求一、SU03T语音识别模块二、模块配置流程1.固件烧录2.配置串口和传输引脚3.中断函数4.double类型转换5 数据发送6.接收处理 三、该模块完整代码总结 需求
基于上次完成空气质量传感器#xff0c;利用SU03T语音识别模块#xff0c;实现空气质量的语音问答播报。 … 文章目录 需求一、SU03T语音识别模块二、模块配置流程1.固件烧录2.配置串口和传输引脚3.中断函数4.double类型转换5 数据发送6.接收处理 三、该模块完整代码总结 需求
基于上次完成空气质量传感器利用SU03T语音识别模块实现空气质量的语音问答播报。 一、SU03T语音识别模块
该模块是固件是通过智能公元设计的。 硬件层和协议层以及识别的语音指令也是由固件决定的。 所以使用前需要去该固件的官网进行设计烧录www.smartpi.cn
二、模块配置流程
思路 1.硬件先检测语音指令将语音指令发送给串口5。AA 55 XX 55 AA 2.串口5以10位为一组存到数组中。 3.校验指令是否正确头尾固定。 4.提取得到的指令数组中的第三位进行判断是哪一个指令。 5.根据接收到的指令和外部声明的空气质量数据传输到指令拼接函数中。 6. 制作指令拼接函数其中要将空气质量的double数据转换为8位16进制的。AA 55 04 00 00 00 00 00 80 37 40 55 AA 7. 将拼接好的数据发送给SU03T语音识别模块进行播报。
1.固件烧录
1.先去智能公元的官网设计所需的语音指令和接口本例程选取的以串口5 PC12TX和PD2RX进行数据的通信。设计完成后会生成一个bin二进制文件。 2.清空板子上的代码然后利用板子上的ch340进行烧录。 具体步骤官方也有详细介绍文档一步一步来就可以。
2.配置串口和传输引脚
该模块的协议层为 波特率9600 数据位8位 校验位 0 位 停止位1位
代码如下
void Su03t_U5Config()//串口5 PC12TX PD2RX
{//开时钟U5 PD12TX PD2RXRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOC,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5,ENABLE);//配置PC12TXGPIO_InitTypeDef GPIO_InitStruct {0};GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF_PP;//复用推完输出GPIO_InitStruct.GPIO_Pin GPIO_Pin_12;GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOC,GPIO_InitStruct);//PD2RXGPIO_InitStruct.GPIO_Mode GPIO_Mode_IN_FLOATING;GPIO_InitStruct.GPIO_Pin GPIO_Pin_2;GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOD,GPIO_InitStruct);//配置串口5 波特率9600 数据位8校验位0停止位1USART_InitTypeDef USART_InitStruct {0};//可以通过结构体类型跳转USART_InitStruct.USART_BaudRate 9600;//波特率USART_InitStruct.USART_HardwareFlowControl USART_HardwareFlowControl_None;//硬件控制流不开USART_InitStruct.USART_Mode USART_Mode_Rx|USART_Mode_Tx;//打开接收USART_InitStruct.USART_Parity USART_Parity_No;USART_InitStruct.USART_StopBits USART_StopBits_1;USART_InitStruct.USART_WordLength USART_WordLength_8b;USART_Init(UART5,USART_InitStruct);//使能串口USART_Cmd(UART5,ENABLE);//配置串口5的中断(采用中断接收)USART_ITConfig(UART5,USART_IT_RXNE,ENABLE);//使能串口5 的接收非空中断USART_ITConfig(UART5,USART_IT_IDLE,ENABLE);//总线空闲中断NVIC_SetPriority(UART5_IRQn,6);//设置优先级0~15NVIC_EnableIRQ(UART5_IRQn);//使能中断通道
}3.中断函数
首先先创建一个结构体方便之后操作。 里面包含需要发送的10位数组、数组下标和数据类型。
typedef struct{uint8_t u5_recv[10];//保存数据数组uint8_t u5_cnt;//数组下标uint8_t u5_tflag;
}UART5DATA;//数据类型
然后依旧是去启动文件中找到然后复制。 代码如下
UART5DATA u5_data{0};
void UART5_IRQHandler()//串口5中断执行
{uint8_t data0;//判断接收中断是否发生if(USART_GetITStatus(UART5,USART_IT_RXNE)SET){data UART5-DR;//USART1-DR data;//回显u5_data.u5_recv[u5_data.u5_cnt]data;u5_data.u5_cnt;u5_data.u5_cnt%10;}//触发空闲中断表示总线空闲接收完毕if(USART_GetITStatus(UART5,USART_IT_IDLE)SET){data UART5-SR;//清理空闲中断先读SR再读DRdata UART5-DR; u5_data.u5_tflag1;}
}该处串口5的中断用来接收数据并把数据传送给数组里每十个为一组。 空闲中断用来进行标志位置1方便之后的程序进行判断。 u5_data.u5_tflag为1时代表一组数据传输完成。
4.double类型转换
由于该串口接收的空气质量数据为double类型而传输类型为8字节16进制所以此时需要进行数据转换。
//将double数据转换成8位类型存放到数组arr中
void DoubleToUint8(double data,uint8_t *arr)
{uint8_t *p (uint8_t *)data;uint8_t i0;for(i0;i8;i){arr[i]p[i];printf(%02x ,*(pi));}printf(\r\n);return;
}5 数据发送
根据该语音模块要求进行数据拼接
//拼接指令函数 AA 55 04 00 00 00 00 00 80 37 40 55 AA
void Su03tSendMsg(uint8_t cmd,double data)
{uint8_t msg[13]{0};//存放要发送的指令msg[0]0xAA;msg[1]0x55;msg[2]cmd;DoubleToUint8(data,msg[3]);msg[11]0x55;msg[12]0xAA;//通过串口5发送U5_Sendarr(msg,13);
}cmd为指令data为数据。 不同的指令对应不同的语音播报数据 要将整合的数据进行发送此时还需要构造两个串口5的发送函数
//串口5发送单字节函数
void Uart5Senddata(uint8_t data)
{//等待发送完成while(USART_GetFlagStatus(UART5,USART_FLAG_TC)0);//如果上次发送完成就发送USART_SendData(UART5,data);
}//串口5发送数组函数
void U5_Sendarr(uint8_t * data,uint32_t len)
{uint32_t i0;for(i0;ilen;i){Uart5Senddata(*data);data;}
}6.接收处理
将kqm处理后的数据进行外部声明再判断头尾的固定值查看是否有误然后进行数据类型标志位判断判断收到的指令要播报那个数据最后记得释放结构体防止重复播报。
extern float voc;
extern float ch2o;
extern float co2;
int Su03tDealData()
{if(u5_data.u5_tflag!1){return 1;}if(u5_data.u5_recv[0]!0xAA||u5_data.u5_recv[1]!0x55){printf(数据帧头出错\r\n);return 2;}if(u5_data.u5_recv[4]!0xAA||u5_data.u5_recv[3]!0x55){printf(数据帧尾出错\r\n);return 3;} switch(u5_data.u5_recv[2]){case 1:printf(接收01空气质量指令\r\n);Su03tSendMsg(1,voc);//vocbreak;case 2: printf( 接收02甲醛指令\r\n);Su03tSendMsg(2,ch2o);//vocbreak;case 3: printf( 接收03Co2指令\r\n);Su03tSendMsg(3,co2);//vocbreak;}memset(u5_data,0,sizeof(u5_data));return 0;
}完成后在主函数中调用 Kqm_U4Config();//空气质量检测 Su03t_U5Config();//语音播报
在while(1)中调用 KQM_DealData();//空气质量处理 Su03tDealData(); 即可实现
三、该模块完整代码
su03t.c
#include stm32f10x.h
#include stdio.h
#include string.h
#include su03t.htypedef struct{uint8_t u5_recv[10];//保存数据数组uint8_t u5_cnt;//数组下标uint8_t u5_tflag;
}UART5DATA;//数据类型void Su03t_U5Config()//串口5 PC12TX PD2RX
{//开时钟U5 PD12TX PD2RXRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOC,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5,ENABLE);//配置PC12TXGPIO_InitTypeDef GPIO_InitStruct {0};GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF_PP;//复用推完输出GPIO_InitStruct.GPIO_Pin GPIO_Pin_12;GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOC,GPIO_InitStruct);//PD2RXGPIO_InitStruct.GPIO_Mode GPIO_Mode_IN_FLOATING;GPIO_InitStruct.GPIO_Pin GPIO_Pin_2;GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOD,GPIO_InitStruct);//配置串口5 波特率9600 数据位8校验位0停止位1USART_InitTypeDef USART_InitStruct {0};//可以通过结构体类型跳转USART_InitStruct.USART_BaudRate 9600;//波特率USART_InitStruct.USART_HardwareFlowControl USART_HardwareFlowControl_None;//硬件控制流不开USART_InitStruct.USART_Mode USART_Mode_Rx|USART_Mode_Tx;//打开接收USART_InitStruct.USART_Parity USART_Parity_No;USART_InitStruct.USART_StopBits USART_StopBits_1;USART_InitStruct.USART_WordLength USART_WordLength_8b;USART_Init(UART5,USART_InitStruct);//使能串口USART_Cmd(UART5,ENABLE);//配置串口4的中断(采用中断接收)USART_ITConfig(UART5,USART_IT_RXNE,ENABLE);//使能串口4 的接收非空中断USART_ITConfig(UART5,USART_IT_IDLE,ENABLE);//总线空闲中断NVIC_SetPriority(UART5_IRQn,6);//设置优先级0~15NVIC_EnableIRQ(UART5_IRQn);//使能中断通道
}//串口5发送单字节函数
void Uart5Senddata(uint8_t data)
{//等待发送完成while(USART_GetFlagStatus(UART5,USART_FLAG_TC)0);//如果上次发送完成就发送USART_SendData(UART5,data);
}//串口5发送数组函数
void U5_Sendarr(uint8_t * data,uint32_t len)
{uint32_t i0;for(i0;ilen;i){Uart5Senddata(*data);data;}
}UART5DATA u5_data{0};
void UART5_IRQHandler()//串口5中断执行
{uint8_t data0;//判断接收中断是否发生if(USART_GetITStatus(UART5,USART_IT_RXNE)SET){data UART5-DR;//USART1-DR data;//回显u5_data.u5_recv[u5_data.u5_cnt]data;u5_data.u5_cnt;u5_data.u5_cnt%10;}//触发空闲中断表示总线空闲接收完毕if(USART_GetITStatus(UART5,USART_IT_IDLE)SET){data UART5-SR;//清理空闲中断先读SR再读DRdata UART5-DR; u5_data.u5_tflag1;}
}//将double转换成8位类型数组arr
void DoubleToUint8(double data,uint8_t *arr)
{uint8_t *p (uint8_t *)data;uint8_t i0;for(i0;i8;i){arr[i]p[i];printf(%02x ,*(pi));}printf(\r\n);return;
}extern float voc;
extern float ch2o;
extern float co2;
int Su03tDealData()
{if(u5_data.u5_tflag!1){return 1;}if(u5_data.u5_recv[0]!0xAA||u5_data.u5_recv[1]!0x55){printf(数据帧头出错\r\n);return 2;}if(u5_data.u5_recv[4]!0xAA||u5_data.u5_recv[3]!0x55){printf(数据帧尾出错\r\n);return 3;} switch(u5_data.u5_recv[2]){case 1:printf(接收01空气质量指令\r\n);Su03tSendMsg(1,voc);//vocbreak;case 2: printf( 接收02甲醛指令\r\n);Su03tSendMsg(2,ch2o);//vocbreak;case 3: printf( 接收03Co2指令\r\n);Su03tSendMsg(3,co2);//vocbreak;}memset(u5_data,0,sizeof(u5_data));return 0;
}//拼接指令函数 AA 55 04 00 00 00 00 00 80 37 40 55 AA
void Su03tSendMsg(uint8_t cmd,double data)
{uint8_t msg[13]{0};//存放要发送的指令msg[0]0xAA;msg[1]0x55;msg[2]cmd;DoubleToUint8(data,msg[3]);msg[11]0x55;msg[12]0xAA;//通过串口5发送U5_Sendarr(msg,13);
}
su03t.h
#ifndef _SU03T_H_
#define _SU03T_H_
#include stm32f10x.h
void Su03t_U5Config();
void Uart5Senddata(uint8_t data);
void U5_Sendarr(uint8_t * data,uint32_t len);
void UART5_IRQHandler();
void DoubleToUint8(double data,uint8_t *arr);
int Su03tDealData();
void Su03tSendMsg(uint8_t cmd,double data);
#endif 总结
1.学会了如何配置半成品模块。 2.学会了如何根据需求进行数据处理和类型转换。