STM32F103+语音识别模块HBR640

              STM32F103+语音识别识别模块HBR640

先来看结果演示:用声音控制烧水壶烧水和关闭

链接:https://weibo.com/tv/v/Hbb04FWkY?fid=1034:4326638951797661

 

HBR640实物图

STM32F103+语音识别模块HBR640_第1张图片

HBR640框架结构图:

STM32F103+语音识别模块HBR640_第2张图片

串口工具:

STM32F103+语音识别模块HBR640_第3张图片

上位机

STM32F103+语音识别模块HBR640_第4张图片

串口协议:

STM32F103+语音识别模块HBR640_第5张图片

 

    官方给的STM32F4的样例,太过涉及芯片本身特定库函数的调用了,变量和宏定义太多。后面由于工程紧急,且要使用与官方历程不同的芯片实现适应性功能裁剪,没有时间先理解官方繁琐的变量和宏定义变换,再一一对应自己所用芯片就的相同功能修改。

     所以自己照着不是很复杂的通信协议写了一个模块历程。我曾经在网上搜索这个模块,发现根本没有它的资料,所以我就写了一个命令集齐全的,且对本身芯片型号控制资源依赖少的程序模块出来和大家分享。

工程目录:

STM32F103+语音识别模块HBR640_第6张图片

main()函数:

void main()
{
    int num=0;  
    hbr640_init();
    
    
  while(1)
  {
     num=Continuous_Recognition(2);
     
      if(num==4)
      {
         num=0;
         Play_Voice(0x00,0x00);//叮当-》你好
         //Play_Voice_Stop();//停止播放
         //delay_ms(500);
         
         soundBee(1);//长响一下
         delay_ms(300);
         num=0;
         Continuous_Recognition(1);
        
      }
      else if(num==1) 
      {
          num=0;
          Play_Voice(0x01,0x00);//烧水-》来个节目吧
          //Play_Voice_Stop();//停止播放
          //delay_ms(900); 
          
          soundBee(0);//短响两下
          delay_ms(300);
          num=0;
          Continuous_Recognition(1);
      }
      else if(num==6) 
      {
          num=0;
          Play_Voice(0x02,0x00);//关闭-》讲个笑话吧
          //Play_Voice_Stop();//停止播放
          //delay_ms(900);
          
          //短响2下
          soundBee(0);
          delay_ms(500);
          soundBee(0);
          delay_ms(300);
          num=0;
          Continuous_Recognition(1); 
      }
      
     
      delay_ms(100);	
  } 

以前发的SendData()有问题,修改如下:

//修改后
void UART_Send_Message_hbr(u8 *Data,u8 lenth)
{
  while(lenth--)
  {
      USART_SendData(USART2, *Data);
      while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
      Data++;
      RX_data_flag=0;
  }
}
//之前的
void SendData(unsigned char date1,unsigned char date2,unsigned char date3)//发送单个字节
{
	delay_us(100);
	USART_SendData(USART2,date1);
    ACCLOG("USART_SendData_date1 = %0X\n",date1);
	while( (USART2->SR&0X40)==0 );//等待前面的数据发送完成
        
        
	delay_us(100);
	USART_SendData(USART2,date2);
    ACCLOG("USART_SendData_date2 = %0X\n",date2);
	while( (USART2->SR&0X40)==0 );//等待前面的数据发送完成
        
        
	delay_us(100);
	USART_SendData(USART2,date3);
    ACCLOG("USART_SendData_date3 = %0X\n",date3);
	while( (USART2->SR&0X40)==0 );//等待前面的数据发送完成
  
	RX_data_flag=0;
}

 

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文件

 

  1. #ifndef __HBR640_H  
  2. #define __HBR640_H  
  3.   
  4. extern unsigned char    USART2_RX_data[3];  
  5. extern unsigned char    RxDataTemp[3];  
  6. extern unsigned char  RX_data_flag;  
  7. extern unsigned char  Play_Voice_flag;  
  8. extern unsigned char  Recognition_flag;  
  9.   
  10. unsigned char hbr640_init(unsigned int BaudRate); // 使用串口的波特率设置  
  11. void SendData(unsigned char date1,unsigned char date2,unsigned char date3);  
  12. unsigned char ReadData(unsigned char date1,unsigned char date2,unsigned char date3,unsigned char mode);  
  13. void Noise_Limit(unsigned int Strength_Series_Low,unsigned int Strength_Series_Hight);  
  14. void Microphone_Sensitivity(unsigned int Strength_Series_Low,unsigned int Strength_Series_Hight);  
  15. unsigned char Recognition_Group(unsigned int Strength_Series_Low,unsigned int Strength_Series_Hight);  
  16. unsigned int Once_Recognition(unsigned char Recognition_Time,unsigned char mode);  
  17. unsigned int Continuous_Recognition(unsigned char mode);  
  18. void Exit_Recognition(void);  
  19. unsigned char hbr640_Sleep(unsigned char mode);  
  20. unsigned int Candidate_Result(unsigned char result,unsigned char mode);  
  21. void Play_Voice(unsigned int Strength_Series_Low,unsigned int Strength_Series_Hight);  
  22. void Play_Voice_Stop(void);  
  23. void Volume_Config(unsigned char Voice_Series);  
  24. void Some_working_640(void);  
  25. #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,关闭蜂鸣器输出
 
}

char n=0;
/*******************************************************************************
* Function Name  : USART2_IRQHandler
* Description    : This function handles USART2 exception.
* Input          : 
* Output         : 
* Return         : 
*******************************************************************************/
void USART2_IRQHandler(void)
{
  
  unsigned char  RX_data_flag=0; 
  char n=0;

    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) 
       {              
            unsigned char key=1;
            
            if(!RX_data_flag) //MCU发送命令完成后RX_data_flag置0
            {
                
                if(RX_data_count<3)
                {  
                  USART2_RX_data[RX_data_count] = USART_ReceiveData(USART2); 
                  RX_data_count++;
                }
                   
                
                if(RX_data_count==3) 
                {
                    RX_data_count=0;
                    RX_data_flag=1;
                }
                key=0;
            }
            
            if(Recognition_flag==1 && key)// 启动识别MCU成功收到命令后Recognition_flag置1 
            {
                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);//清除溢出中断 
         USART_ReceiveData(USART2);  
     }     

}

 

你可能感兴趣的:(项目,HBR640)