语音识别识别模块HBR640
做一个语音交互项目,不用自己写识别算法,直接用芯片就好了,快速开发而且要求不高的话用LD3320芯片还可以,不仅便宜,识别词条多,还集成了小型功放电路由于语音播放。但是我的识别量比较少在100个左右,用不了LD3320那么多识别词条。hbr640模块,芯片国产,便宜。优点是配备上位机,修改添加识别词条简单,还可以分识别组,单片机只需要遵守串口协议就可以读出结果或者播放语音了。控制方便,识别率挺高,词条刚好100个,缺点:1.上位机没有集成语音生成WAV音频文件功能,需要第三方软件完成。
*实物图
HBR640框架结构图:
串口工具:
*上位机
串口协议:
官方给的STM32F4的样例,太过涉及芯片本身特定库函数的调用了,变量和宏定义太多。后面由于工程紧急,且要使用与官方历程不同的芯片实现适应性功能裁剪,没有时间先理解官方繁琐的变量和宏定义变换,再一一对应自己所用芯片就的相同功能修改。
所以自己照着不是很复杂的通信协议写了一个模块历程。我曾经在网上搜索这个模块,发现根本没有它的资料,所以我就写了一个命令集齐全的,且对本身芯片型号控制资源依赖少的程序模块出来和大家分享。
工程目录:
HBR640.c文件
/******************************************************************************* 功能:HBR640 TIME:2018年6月3日 NAME:魏波 1.函数名称:hbr640_init;函数功能:初始化hbr640 2.函数名称:ReadData;函数功能: mode=1:接收hbr640传回的三组数据并与入口进行比对校验 3.函数名称:SendData;函数功能:date1 date2 date3 分别向hbr640发送一个字节的命令信息 4.函数名称:Microphone_Sensitivity;函数功能:设置hbr640的麦克风灵敏度强度级数 5.函数名称:Noise_Limit;函数功能:设置hbr640的麦克风噪声门限设置 6.函数名称:Recognition_Group;函数功能:设置需要识别的语音组 7.函数名称:Some_working_640;函数功能:在Once_Recognition或Continuous_Recognition之一的mode2调用它,起到循环接收640数据的作用。 8.函数名称:Once_Recognition;函数功能:启动一次识别模式,并且设置识别处理的最大时间 9.函数名称:Continuous_Recognition;函数功能:启动连续识别模式 10.函数名称:Exit_Recognition;函数功能:退出识别,等待命令 11.函数名称:hbr640_Sleep;函数功能:进入休眠模式 12.函数名称:Continuous_Recognition;函数功能:提取候选结果 13.函数名称:Play_Voice;函数功能:设置播放语音,并设置播放语音的组序号 14.函数名称:Play_Voice_Stop;函数功能:设置停止播放语音 15.函数名称:Volume_Config;函数功能:设置播放语音的音量 *********************************************************************************/ #include "sys.h" #include "hbr640.h" #include "usart2.h" //#include "usart.h" #include "delay.h" /*改:芯片延时函数*/ /******************************************************************************* 功能:是否开启DEBUG模式 开启:#define _DEBUG_ 1 关闭:#define _DEBUG_ 0 *********************************************************************************/ #define _DEBUG_ 1 #if _DEBUG_ #define PRINTF(...) printf(__VA_ARGS__) #else #define PRINTF(...) #endif extern unsigned char Recognition_data[3]; unsigned char USART2_RX_data[3]; // 储存接收的3个数据 unsigned char RX_data_flag=0; // 接收3个数据成功标志 /********************************************************************************* 函数名称:BEEP_Init 函数功能:初始化BEEP 入口参数:beep_time 响的时长 返回值:void *********************************************************************************/ void BEEP_OPEN(int beep_time) { BEEP_Init(); GPIO_SetBits(GPIOB,GPIO_Pin_5);//开 delay_ms(beep_time); GPIO_ResetBits(GPIOB,GPIO_Pin_5);//关 return; } /********************************************************************************* 函数名称:hbr640_init 函数功能:初始化hbr640 入口参数:BaudRate hbr640所用到的串口的波特率值 返回值:1 模块存在初始化成功 0 没有检测到模块初始化失败 *********************************************************************************/ unsigned char hbr640_init(unsigned int BaudRate) // 默认为115200 需要设置请在语音命令生成软件设置 { USART2_Init(BaudRate); /*改:芯片串口初始化*/ SendData(0xA0,0xA0,0xA0);// 初始化语音模块命令 //delay_ms(500); if( ReadData(0x50,0x50,0x20,1) )// 检查hbr640是否存在,0x20是芯片版本号(每个模块的版本号不同) { //Microphone_Sensitivity(0x2F,0x0C);//设置麦克风灵敏度强度上下限 //Noise_Limit(0x16,0x1c); //设置麦克风噪声门限设置 Volume_Config(0x03); //设置放音音量 if(Recognition_Group(0x01,0x00)) //设置需要识别的语音组 { Continuous_Recognition(1);//启动连续识别模式,mode=1 初始化 Recognition_flag=1; // 初始化完成,开启识别结果储存 } return 1; } return 0; } /********************************************************************************* 函数名称:ReadData 函数功能: mode=1:接收hbr640传回的三组数据并与入口进行比对校验 mode=2:将接收数据暂存入RxDataTemp数组中 入口参数:date1 date2 date3 说明书的接收命令集 mode=1:用于接收命令不变的情况 mode=2:用于接收命令变的情况 返回值:1 与入口参数相同 0 与入口参数不同 *********************************************************************************/ unsigned char RxDataTemp[3]={0,0,0}; unsigned char ReadData(unsigned char date1,unsigned char date2,unsigned char date3,unsigned char mode) { u32 sum=0; //PRINTF("mode = %0X\n",mode); //PRINTF("ReadData_RX_data_flag = %0X\n",RX_data_flag); while(!RX_data_flag) // 等待模块回应, RX_data_flag=0; 接收3个数据成功标志 { sum++; if(sum>80000) break; } if(mode==1) { PRINTF("USART2_RX_data[0] = %0X\n",USART2_RX_data[0]); PRINTF("USART2_RX_data[1] = %0X\n",USART2_RX_data[1]); PRINTF("USART2_RX_data[2] = %0X\n",USART2_RX_data[2]); if( sum<80000 && USART2_RX_data[0]==date1 && USART2_RX_data[1]==date2 && USART2_RX_data[2]==date3 ) { USART2_RX_data[0]=0; USART2_RX_data[1]=0; USART2_RX_data[2]=0; return 1; } } else if(mode==2) { //printf("->%d %d %d ",USART2_RX_data[0],USART2_RX_data[1],USART2_RX_data[2]); if(sum<80000) { RxDataTemp[0]=USART2_RX_data[0]; RxDataTemp[1]=USART2_RX_data[1]; RxDataTemp[2]=USART2_RX_data[2]; USART2_RX_data[0]=0; USART2_RX_data[1]=0; USART2_RX_data[2]=0; return 1; } } USART2_RX_data[0]=0; USART2_RX_data[1]=0; USART2_RX_data[2]=0; return 0; } /********************************************************************************* 函数名称:SendData 函数功能:date1 date2 date3 分别向hbr640发送一个字节的命令信息 入口参数:date1 date2 date3 都表示8位的1个字节数据 返回值:无 *********************************************************************************/ void SendData(unsigned char date1,unsigned char date2,unsigned char date3)//发送单个字节 { delay_us(50); USART_SendData(USART2,date1); PRINTF("USART_SendData_date1 = %0X\n",date1); while( (USART2->SR&0X40)==0 );//等待前面的数据发送完成 delay_us(50); USART_SendData(USART2,date2); PRINTF("USART_SendData_date2 = %0X\n",date2); while( (USART2->SR&0X40)==0 );//等待前面的数据发送完成 delay_us(50); USART_SendData(USART2,date3); PRINTF("USART_SendData_date3 = %0X\n",date3); while( (USART2->SR&0X40)==0 );//等待前面的数据发送完成 RX_data_flag=0; } /********************************************************************************* 函数名称:Microphone_Sensitivity 函数功能:设置hbr640的麦克风灵敏度 入口参数:Strength_Series_Low 麦克风灵敏度下限 trength_Series_Hight 麦克风灵敏度上限 返回值:无 *********************************************************************************/ void Microphone_Sensitivity(unsigned int Strength_Series_Low,unsigned int Strength_Series_Hight) { if( Strength_Series_Low!=0x2F && Strength_Series_Hight!=0X0B ) //默认值:Strength_Series_Low=0x2F;Strength_Series_Hight=0X0B { if(Strength_Series_Low>0x3F) //麦克风灵敏度下限范围0x00 至 0x3f (十进制是0~77) { Strength_Series_Low=0x3F; } if(Strength_Series_Hight>0x0f) //麦克风灵敏度上限范围0x00 至 0x0f (十进制是0~15) { Strength_Series_Hight=0x0F; } SendData(0xA1,Strength_Series_Low,Strength_Series_Hight); } } /********************************************************************************* 函数名称:Noise_Limit 函数功能:设置hbr640的麦克风噪声门限和语音音量门限 入口参数:Strength_Series_Low 麦克风噪声下限 Strength_Series_Hight 麦克风噪声上限 返回值:无 *********************************************************************************/ void Noise_Limit(unsigned int Strength_Series_Low,unsigned int Strength_Series_Hight) { if( Strength_Series_Low!=0x16 && Strength_Series_Hight!=0X19 ) //默认值:Strength_Series_Low=0x16;Strength_Series_Hight=0X19 { //噪声下限范围0x16 至 0x28 (十进制是22~40) if(Strength_Series_Low>0x28) { Strength_Series_Low=0x28; } else if(Strength_Series_Low<0x16) { Strength_Series_Low=0x16; } //噪声上限范围0x19 至 0x30 (十进制是25~48) if(Strength_Series_Hight>0x30) { Strength_Series_Hight=0x30; } else if(Strength_Series_Hight<0x19) { Strength_Series_Hight=0x19; } SendData(0xA2,Strength_Series_Low,Strength_Series_Hight);//配置输入语音音量:主机->从机,0xA2 0xLL,0xHH } } /********************************************************************************* 函数名称:Recognition_Group 函数功能:设置需要识别的语音组 入口参数:Strength_Series_Hight(0x**) Strength_Series_Low(0x**) 组成 0xHHLL 的识别组数序号 返回值:1 设置成功 0 设置失败 *********************************************************************************/ unsigned char Recognition_Group(unsigned int Strength_Series_Low,unsigned int Strength_Series_Hight) // 0xHHLL 为需要设定识别的组数序号 { if(Strength_Series_Low<0x01) { Strength_Series_Low=0x01;//默认是第一组 } if(Strength_Series_Hight>0x64) { Strength_Series_Hight=0x64; // hbr640的识别组数范围0x01至0x64 (十进制是1~100,最多识别100条) } SendData(0xA9,Strength_Series_Low,Strength_Series_Hight);//配置识别组:0xA9 0xLL,0xHH ,主机-->从机, ReadData(0,0,0,2);//mode=2:将接收数据暂存入RxDataTemp数组中 //PRINTF("->%d %d %d ",RxDataTemp[0],RxDataTemp[1],RxDataTemp[2]); //配置识别组:0x59 0xll,0xhh ,从机-->主机, if( RxDataTemp[0]==0x59 && RxDataTemp[1]==Strength_Series_Low && RxDataTemp[2]==Strength_Series_Hight ) { return 1; } return 0; } /********************************************************************************* 函数名称:Some_working_640 函数功能:在Once_Recognition或Continuous_Recognition之一的mode2调用它, 起到循环接收640数据的作用 入口参数:无 返回值:无 *********************************************************************************/ void Some_working_640(void) { // 检测语音播放是否结束,播放完成返回0x79 0x01 0x00 if(Recognition_data[0]==0x79 && Recognition_data[1]==0x01 && Recognition_data[2]==0x00) { Play_Voice_flag=0; //播放结束标记 Continuous_Recognition(1); //启动连续识别模式,mode=1 初始化 mode=2 循环检测识别结果 } //Candidate_Result();提取候选结果 } /********************************************************************************* 函数名称:Once_Recognition 函数功能:启动一次识别模式,并且设置识别处理的最大时间 入口参数:Recognition_Time 设置识别最大时间 mode=1 初始化 mode=2 循环检测识别结果 返回值:!0 设置成功,并返回该组语音的识别结果的序号 0 设置失败 *********************************************************************************/ unsigned int Once_Recognition(unsigned char Recognition_Time,unsigned char mode) //0x00(不超时)秒内进行识别 { unsigned int result=0; if(mode==1) { SendData(0xAA,Recognition_Time,0x00); } if(mode==2) { if(Recognition_flag==10) { //Some_working_640();//循环接收640数据的作用 if(RxDataTemp[0]==0x5a) //返回值:0x5a 0x11 0xhh 从机->主机 { /*超时、有语音输入但无正确结果的处理*/ // 0x7fff表示超时,0xffff表示有语音输入但无正确结果 if( (Recognition_data[1]==0xff && Recognition_data[2]==0xff) || (Recognition_data[1]==0xff && Recognition_data[2]==0x7f) ) { Recognition_data[0]=0; Recognition_data[1]=0; Recognition_data[2]=0; Recognition_flag=1; return 0; } result=Recognition_data[1]+(Recognition_data[2]<<2)+1; Recognition_data[0]=0; Recognition_data[1]=0; Recognition_data[2]=0; Recognition_flag=1; return result;//返回该组语音的识别结果的序号 } } } return 0; } /********************************************************************************* 函数名称:Continuous_Recognition 函数功能:启动连续识别模式 入口参数:mode=1 初始化 mode=2 循环检测识别结果 返回值:!0 设置成功,并返回该组语音的识别结果的序号 0 设置失败 *********************************************************************************/ unsigned char Recognition_flag=0; unsigned int Continuous_Recognition(unsigned char mode) { unsigned int result=0; if(mode==1) { delay_us(50); USART_SendData(USART2,0xAB); while( (USART2->SR&0X40)==0 );//等待前面的数据发送完成 delay_us(50); USART_SendData(USART2,0xAB); while( (USART2->SR&0X40)==0 );//等待前面的数据发送完成 delay_us(50); USART_SendData(USART2,0x00); while( (USART2->SR&0X40)==0 );//等待前面的数据发送完成 } if(mode==2) { if(Recognition_flag==10) { //PRINTF("-》%d %d %d ",Recognition_data[0],Recognition_data[1],Recognition_data[2]); Some_working_640();//mode2调用它,起到循环接收640数据的作用 if( Recognition_data[0]==0x5b && Recognition_data[1]==0xff && Recognition_data[2]==0xff ) // 0xffff表示有语音输入但无正确结果 { Recognition_data[0]=0; Recognition_data[1]=0; Recognition_data[2]=0; Recognition_flag=1; return 0; } if( Recognition_data[0]==0x5b ) { result=Recognition_data[1]+(Recognition_data[2]<<2)+1; Recognition_data[0]=0; Recognition_data[1]=0; Recognition_data[2]=0; Recognition_flag=1; return result;//返回该组语音的识别结果的序号 } } } Recognition_data[0]=0; Recognition_data[1]=0; Recognition_data[2]=0; Recognition_flag=1; return 0; } /********************************************************************************* 函数名称:Exit_Recognition 函数功能:退出识别,等待命令 入口参数:无 返回值:无 *********************************************************************************/ void Exit_Recognition(void) { Recognition_flag=0; SendData(0xAC,0xAC,0x00);//退出识别:0xAC 0xAC 0x00 主机->从机 } /********************************************************************************* 函数名称:hbr640_Sleep 函数功能:进入休眠模式(低功耗模式) 入口参数:mode=1 进入休眠 mode=2 解除休眠 返回值:1 设置成功 0 设置失败 *********************************************************************************/ unsigned char hbr640_Sleep(unsigned char mode) { if(mode==1) SendData(0xAE,0xAE,0x00);//正常返回:0x5e if(mode==2) { delay_us(50); USART_SendData(USART2,0xA0); while( (USART2->SR&0X40)==0 );//等待前面的数据发送完成 return 1; } return 0; } /********************************************************************************* 函数名称:Continuous_Recognition 函数功能:提取候选结果 入口参数:result(0至7级)其值越小优先级越高,识别相似度越高 mode=1 初始化 mode=2 循环检测识别结果 返回值:!0 设置成功,并返回该组语音的识别候选结果的序号 0 设置失败 *********************************************************************************/ unsigned int Candidate_Result(unsigned char result,unsigned char mode) { if(mode==1) { if(result>7) { result=7; } SendData(0xAF,result,0x00); } if(mode==2) if( RxDataTemp[0]==0x5f ) { if( (RxDataTemp[1]==0xff && RxDataTemp[2]==0xff) ) // 0xffff表示无候选词 { return 0; } return RxDataTemp[1]+(RxDataTemp[2]<<2)+1;//返回第0xLL(0--7)个候选词的序号0xhhll } return 0; } /********************************************************************************* 函数名称:Play_Voice 函数功能:设置播放语音,并设置播放语音的组序号 入口参数:Strength_Series_Hight(0x**) Strength_Series_Low(0x**) 组成0xHHLL来设定播放的组数序号 返回值:无 *********************************************************************************/ unsigned char Play_Voice_flag=0; //播放结束标记 void Play_Voice(unsigned int Strength_Series_Low,unsigned int Strength_Series_Hight) { if(!Play_Voice_flag) { SendData(0xC8,Strength_Series_Low,Strength_Series_Hight); if( RxDataTemp[0]==0x78 && RxDataTemp[1]==0x01 && RxDataTemp[2]==0x00 )//启动播放返回0x78 0x01 0x00 { Play_Voice_flag=1; } } } /********************************************************************************* 函数名称:Play_Voice_Stop 函数功能:设置停止播放语音 入口参数:无 返回值:无 *********************************************************************************/ void Play_Voice_Stop(void) { SendData(0xC9,0x00,0x00); } /********************************************************************************* 函数名称:Volume_Config 函数功能:设置播放语音的音量 入口参数:Voice_Series 设置播放语音的音量大小 返回值:无 *********************************************************************************/ void Volume_Config(unsigned char Voice_Series) // 调节音量的范围是 0x00~0x0F (十进制是1~15) { if(Voice_Series>0x0F) { Voice_Series=0x0F; } SendData(0xCA,Voice_Series,0x00); }
HBR640.h文件
- #ifndef __HBR640_H
- #define __HBR640_H
- extern unsigned char USART2_RX_data[3];
- extern unsigned char RxDataTemp[3];
- extern unsigned char RX_data_flag;
- extern unsigned char Play_Voice_flag;
- extern unsigned char Recognition_flag;
- unsigned char hbr640_init(unsigned int BaudRate); // 使用串口的波特率设置
- void SendData(unsigned char date1,unsigned char date2,unsigned char date3);
- unsigned char ReadData(unsigned char date1,unsigned char date2,unsigned char date3,unsigned char mode);
- void Noise_Limit(unsigned int Strength_Series_Low,unsigned int Strength_Series_Hight);
- void Microphone_Sensitivity(unsigned int Strength_Series_Low,unsigned int Strength_Series_Hight);
- unsigned char Recognition_Group(unsigned int Strength_Series_Low,unsigned int Strength_Series_Hight);
- unsigned int Once_Recognition(unsigned char Recognition_Time,unsigned char mode);
- unsigned int Continuous_Recognition(unsigned char mode);
- void Exit_Recognition(void);
- unsigned char hbr640_Sleep(unsigned char mode);
- unsigned int Candidate_Result(unsigned char result,unsigned char mode);
- void Play_Voice(unsigned int Strength_Series_Low,unsigned int Strength_Series_Hight);
- void Play_Voice_Stop(void);
- void Volume_Config(unsigned char Voice_Series);
- void Some_working_640(void);
- #endif
最近在做一个工程要用到多个串口同时通讯的,就参考了正点原子的串口通讯例程,发现例程是USART1 串口1的,后面我想改成USART2 串口2的,上网找了资料,要不是不靠谱,要不就是要积分下载。所以后面自己写了一个可用程序来和大家分享!
废话不多说!贴代码!
usart2.c文件
#include "usart2.h" #include "hbr640.h" #include "delay.h" unsigned char RX_data_count=0; unsigned char Recognition_flag_count=0; unsigned char Recognition_data[3]; //是否开启DEBUG模式 #define _DEBUG_ 1 #if _DEBUG_ #define PRINTF(...) printf(__VA_ARGS__) #else #define PRINTF(...) #endif void USART2_Init(u32 My_BaudRate) { GPIO_InitTypeDef GPIO_InitStrue; USART_InitTypeDef USART_InitStrue; NVIC_InitTypeDef NVIC_InitStrue; // 外设使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE); USART_DeInit(USART2); //复位串口2 -> 可以没有 // 初始化 串口对应IO口 TX-PA2 RX-PA3 GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStrue.GPIO_Pin=GPIO_Pin_2; GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStrue); GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING; //浮空输入 GPIO_InitStrue.GPIO_Pin=GPIO_Pin_3; GPIO_Init(GPIOA,&GPIO_InitStrue); // 初始化 串口模式状态 USART_InitStrue.USART_BaudRate=My_BaudRate; // 波特率 USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None; // 硬件流控制 USART_InitStrue.USART_Mode=USART_Mode_Tx|USART_Mode_Rx; // 发送 接收 模式都使用 USART_InitStrue.USART_Parity=USART_Parity_No; // 没有奇偶校验 USART_InitStrue.USART_StopBits=USART_StopBits_1; // 一位停止位 USART_InitStrue.USART_WordLength=USART_WordLength_8b; // 每次发送数据宽度为8位 USART_Init(USART2,&USART_InitStrue); USART_Cmd(USART2,ENABLE); //使能串口 USART_ITConfig(USART2,USART_IT_RXNE,ENABLE); //开启接收中断 // 初始化 中断优先级 NVIC_InitStrue.NVIC_IRQChannel=USART2_IRQn; NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE; NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1; NVIC_InitStrue.NVIC_IRQChannelSubPriority=1; NVIC_Init(&NVIC_InitStrue); } //BEEP void BEEP_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB,PE端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5 //GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 输出高 GPIO_ResetBits(GPIOB,GPIO_Pin_5); //输出0,关闭蜂鸣器输出 } /* void USART2_IRQHandler(void) // 串口2中断服务函数 { u8 res; if(USART_GetITStatus(USART2,USART_IT_RXNE)) // 中断标志 { res= USART_ReceiveData(USART2); // 串口2 接收 USART_SendData(USART2,res); // 串口2 发送 } } */ char n=0; void USART2_IRQHandler(void) { //if(USART_GetITStatus(USART2,USART_IT_RXNE)) //接收中断(接收到的数据必须是0x0d 0x0a结尾) if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //查寻串口标志,为0还是1(reset 为0,set 为1) { unsigned char key=1; //PRINTF("USART_DO_RX_data_flag = %0X\n",RX_data_flag); if(!RX_data_flag) // 1.命令集的返回值收集,用于判断所发命令是否有效;RX_data_flag接收3个数据成功标志 { if(RX_data_count<3) { USART2_RX_data[RX_data_count++] = USART_ReceiveData(USART2); //改:芯片获取串口数据 //PRINTF("RX_data_count = %0X\n",RX_data_count); //PRINTF("USART2_IRQHandler_RX_data%0x = %0X\n",RX_data_count,USART2_RX_data[RX_data_count]); } if(RX_data_count==3) { RX_data_count=0; RX_data_flag=1; } key=0; } if(Recognition_flag==1 && key) // 2.用于与命令集返回值区分开来,单独接储存收识别的结果 { if(Recognition_flag_count<3) { Recognition_data[Recognition_flag_count++] = USART_ReceiveData(USART2); //改:芯片获取串口数据 } if(Recognition_flag_count==3) { Recognition_flag=10; Recognition_flag_count=0; } } } if(USART_GetFlagStatus(USART2,USART_FLAG_ORE)==SET) //溢出 { USART_ClearFlag(USART2,USART_FLAG_ORE); //读SR USART_ReceiveData(USART2); //读DR } }