基于LD3320的51智能遥控语音小车

这篇具有很好参考价值的文章主要介绍了基于LD3320的51智能遥控语音小车。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于LD3320的51智能遥控语音小车小车实物图 

本实验基于51单片机和LD3320语音识别模块

小车能够实现遥控器直接控制,语音控制以及自动避障

涉及到的知识有:I/O口的配置(点亮led),定时器(循迹),串口通信(两个板子的连接),SPI同步通信(遥控器),中断(定时器中断和串口中断),PWM(循迹)

原理图如下

基于LD3320的51智能遥控语音小车

 值得注意的是,串口通信使用的是串口2,要接到P4.6和P4.7

其实串口2和串口1没什么本质区别,只是其中某些寄存器不能直接赋值

代码的逻辑如下图所示基于LD3320的51智能遥控语音小车

 遥控器通过按下不同的按键,得到不同的flag值从而进入不同的驱动模式

初始定时器中断默认打开

但串口中断优先级更低

所以在选择语音模式的时候要将定时器中断关闭

此外,通过板载led灯可以观察小车的状态

上电后小车亮蓝灯,进入语音模式后亮红灯

前进时灯都亮,后退时全灭

左转亮红灯,右转亮蓝灯

通过板载指示灯能看出运动状态

以下是详细的代码(主控51单片机和LD3320)

头文件都是默认的因此只给出main函数

51单片机函数:

#include  "delay.h"
#include "ps2.h"
#include "stdio.h"
#include "15W4KxxS4.h"
#include "uart.h"
#include "beep.h"
/**********引脚设置***********/
sbit IN1=P2^6;
sbit IN2=P0^2;
sbit IN3=P2^0;
sbit IN4=P2^4;
sbit OUTR=P0^0;
sbit OUTL=P0^1;
sbit led1=P0^6;
sbit led2=P0^7;
 /*********变量设置**********/
volatile uint8 Flag1=FALSE;
uint8 uart2temp,sig;
int g_carstate = 0;
int pwm_control=0;
int flag=0;
/************函数调用********************/
void TIME0_Init(void);//定时器设置
void Uart2_Init(void);//串口2设置
void run(void);//运动函数设置
void back(void);
void left(void);
void right(void);
void stop(void);
void PS2_control();//ps2按键控制
void SendDataByUart2(uint8 dat);//串口2发送数据函数
void UART2_Tx_Puts(void);//串口2接收到数据后发送出去
/************枚举按键状态****************/
 enum{
  enSTOP = 0,
  enRUN,
  enBACK,
  enLEFT,
  enRIGHT,
	enTRIANGLE,
	enCIRCLE,
	enCROSS,
	enSQUARE,
	enR2,
 }enCarState;
 /***********主函数***************/
int main()
{	
	int i=0;
	int pwm=0;
	Uart2_Init();		//串口初始化	
	TIME0_Init();			//定时器0初始化
	PS2_Init();			//PS2初始化
 	P0M1 &= 0x3F;	P0M0 &= 0x3F;   //设置P0.6,P0.7为准双向口
	P3M1 &= 0x7F;	P3M0 &= 0x7F;	  //设置P3.7为准双向口
	P2M1 &= 0xDF;	P2M0 &= 0xDF;	  //设置P2.5为准双向口 
  delay_ms(10);                                 //初始化后延时
  while (1)
	{ 
		
		PS2_control();
		IN1=0;
		IN2=0;
		IN3=0;
		IN4=0;//电机接收电流置零
		
		if(g_carstate==enTRIANGLE)
		{
			flag=1;//将遥控器发出的对应模式以flag的形式记录
		}
		else if(g_carstate==enCROSS)
		{
			flag=3;
		}
			else if(g_carstate==enCIRCLE)
		{
			flag=2;
		}
			else if(g_carstate==enSQUARE)
		{
			flag=0;
		}
		if(flag==1)
		{
			
		 BEEP_off();
			EA=1;
		 switch(g_carstate)     
		 {					 
				case enRUN:	
				{
					run();
				}
					break;	
			 case enBACK: 
			 {
				back();
			 }
				break;
			case enLEFT:
			{
				left();
			}
			
			break;		   
			case enRIGHT:
			{
				right();
			}
				break;	
			default: 
			{
			stop();
			}
			break;				    
	   }
	 }
		delay_ms(10);
	 if(flag==2)//语音模式
	 {
		
		 BEEP_off();
		 EA=1;
		 ET0=0;//关闭定时器中断
	 }
	 
	 if(flag==3)//红外避障模式
	 {
		 BEEP_off();
		 ET0=1;//关闭定时器中断
		 EA=1;

	 }
	if(flag==0)
	{
		
	 stop();
	}
  } 
}


/**************定时器设置**************/
void TIME0_Init(void)
{
		
		
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
  TL0 = (65526-1000/1.085)/256;		//设置定时初始值
	TH0 = 65526-1000/1.085;		//设置定时重载值
	TR0= 1;		    //启动T0工作
	TF0=0;
	ET0= 1;		    //允许T0中断,定时器中断开
	EA = 1;	        //开总中断
}
/********** 串口2初始化函数************/
void Uart2_Init(void)
{	
	P_SW2|=S2_S;   //选择P46 P47为串口2
		
	S2CON = 0x50;		//8位数据,可变波特率,启动串行接收器	
	AUXR |= 0x04;		//定时器2时钟为Fosc,即1T
	T2L = 0xE0;		  //设定定时初值
	T2H = 0xFE;     //设定定时初值
	AUXR |= 0x10;   //启动定时器2
	IE2 |= 0x01;    //串口2中断打开
}
/**************运动状态函数设定*********/
void run(void)
{
	IN1=0;
	IN2=1;
	IN3=0;
	IN4=1;
	led1=0;
	led2=0;
	return;
}
void back(void)
{
	IN1=1;
	IN2=0;
	IN3=1;
	IN4=0;
	led1=1;
	led2=1;
	return;
}
void left(void)
{
    IN1=1;
	  IN2=0;
	  IN3=0;
	  IN4=1;
    led1=0;
		led2=1;
	return;
}

void right(void)
{
	 IN1=0;
	 IN2=1;
	 IN3=1;
	 IN4=0;
	 led1=1;
	 led2=0;
	return;
}
void stop(void)
{
	IN1=0;
	IN2=0;
	IN3=0;
	IN4=0;
	return;
}

/******************ps2按键控制***************/
 void PS2_control()
{
        //PS2按键变量定义
        stPS2KeyValue * PS2;
    	
		PS2 = ReadPS2KeyValue();	    //检测手柄按键之后获得的值
		//由data[3]和data[4]返回来的组合成16位的数组
		//如data[4]data[3]:当select按下时
		//FunBtn:0x1111 1111 1111 1110
		if((PS2->FunBtn & PSB_SELECT) == 0)
		{
		 
		}
		
		if((PS2->FunBtn & PSB_START) == 0)
		{
		  
		}
		 
		if((PS2->FunBtn & PSB_L3) == 0)
		{
			
			 g_carstate = enSTOP;      //将小车定义为停止状态
		}

		if((PS2->FunBtn & PSB_R3) == 0)
		{
			
			 g_carstate = enSTOP;      //将小车定义为停止状态
		}

		if((PS2->FunBtn & PSB_PAD_UP) == 0)
		{
			
			 g_carstate = enRUN;       //将小车定义为前进状态
		}

		else if((PS2->FunBtn & PSB_PAD_RIGHT) == 0)
		{
			 
			 g_carstate = enRIGHT;     //将小车定义为状态右转
		}
		else if((PS2->FunBtn & PSB_PAD_DOWN) == 0)
		{
			
			g_carstate = enBACK;       //将小车定义为后退状态
		}
		else if((PS2->FunBtn & PSB_PAD_LEFT) == 0)
		{
			 
			 g_carstate = enLEFT;       //将小车定义为左转状态
		}
	   else if((PS2->FunBtn & PSB_TRIANGLE) == 0) // 遥控器操作模式
		{
			  BEEP_on();
		delay_ms(10);
			g_carstate= enTRIANGLE;
			 
		} 
		 
		 else if((PS2->FunBtn & PSB_CIRCLE) == 0)	// 声控模式
		{
			BEEP_on();
		 delay_ms(10);
			  g_carstate= enCIRCLE;
		}  
	
		else if((PS2->FunBtn & PSB_CROSS) == 0) // 自动避障模式
		{
			delay_ms(10);
	     g_carstate= enCROSS;
		BEEP_on();
		 
		} 
		 
		else if((PS2->FunBtn & PSB_SQUARE) == 0)	  //停止
		{
			g_carstate= enSQUARE;
		}  
		else if((PS2->FunBtn & PSB_R2) == 0)
		{
			g_carstate= enR2;
		}
		else                           //去掉则按下一直执行,加此段则放开停止
		{
		  g_carstate = enSTOP;        //将小车定义为停止状态
		}
		
 	
}
/**********串口2发送数据函数*****************/
void SendDataByUart2(uint8 dat)
{
    S2BUF = dat;                 //写数据到UART数据寄存器
		while(!(S2CON&S2TI));        //在停止位没有发送时,S2TI为0即一直等待
    S2CON&=~S2TI;                //清除S2CON寄存器对应S2TI位(该位必须软件清零)
}
/************ 串口2接收到数据后发送出去****************/
void UART2_Tx_Puts(void)
{
  if(Flag1)      //有新数据通过串口被接收到
	{
		
	
		IE2 &= 0xFE; 			                     // 串口2中断关闭	
		SendDataByUart2(uart2temp);            //发送字符 
    SendDataByUart2(0x0D);                 //发送换行符
    SendDataByUart2(0x0A);                 //发送换行符						
		IE2 |= 0x01;                           // 串口2中断打开													
		Flag1=FALSE;                            //清除接收标识符
  }
}
/**********串口2中断服务函数********************/
void Uart2() interrupt UART2_VECTOR using 1
{
	IE2 &= 0xFE; 			               // 串口2中断关闭
	Flag1=TRUE;                       //接收到数据,接收标识符有效

	led1=0;                           //串口2指示灯亮,红灯
		
	if (S2CON & S2RI)                //串行接收到停止位的中间时刻时,该位置1
  {
      S2CON &= ~S2RI;              //清除S2CON寄存器对应S2RI位(该位必须软件清零)
			uart2temp = S2BUF;       
   }
	 switch(uart2temp)
    {
			 case 0x01:   //收到“1”
       run();
			 delay_ms(300);
			 stop();
            break;
        
        case 0x02:    //收到“2”
       back();
				 delay_ms(300);
				stop();
            break;
        
        case 3:    //收到“3”
       left();
				 delay_ms(250);
				stop();
            break;
        
        case 4:    //收到“4”
       right();
				 delay_ms(250);
				stop();
            break;
        
        default:
            P2=0XFF;
            break;
    }
  if (S2CON & S2TI)                //在停止位开始发送时,该位置1
   {
      S2CON &= ~S2TI;   			     //清除S2CON寄存器对应S2TI位(该位必须软件清零)
   }
	 IE2 |= 0x01;                    // 串口2中断打开	
}
/**************定时器0中断***************/
void timer0()interrupt 1 
{
    
   TL0 = (65526-1000/1.085)/256;		//设置定时初始值
	TH0 = 65526-1000/1.085;
		if(pwm_control>10)
		{
			pwm_control=0;
		}
		if(flag==3)
		{		
		if(pwm_control<9)
		{
		 if(OUTR==0&&OUTL==0)
			{	
			 back();	
			
			}
		
     	else if(OUTL==0)
			{

				right();
		
			}
			else if(OUTR==0)
			{			
			
			left();
				
			}				
			
      if(OUTR==1&&OUTL==1)		
			
			{	
				run();
			}		
		}
		else
		{
			stop();
		}
	
	}
	
	 pwm_control++;
 }

语音模块函数

main.c

/*******************************************************
**	CPU: STC11L08XE
**	晶振:22.1184MHZ
**	波特率:9600 bit/S
**  口令模式: 即每次识别时都需要说“大哥”这个口令 ,才能够进行下一级的识别
/*********************************************************/
#include "config.h"
/************************************************************************************/
//	nAsrStatus 用来在main主程序中表示程序运行的状态,不是LD3320芯片内部的状态寄存器
//	LD_ASR_NONE:		表示没有在作ASR识别
//	LD_ASR_RUNING:		表示LD3320正在作ASR识别中
//	LD_ASR_FOUNDOK:		表示一次识别流程结束后,有一个识别结果
//	LD_ASR_FOUNDZERO:	表示一次识别流程结束后,没有识别结果
//	LD_ASR_ERROR:		表示一次识别流程中LD3320芯片内部出现不正确的状态
/***********************************************************************************/
uint8 idata nAsrStatus = 0;
void MCU_init();
void ProcessInt0(); //识别处理函数
void delay(unsigned long uldata);
void User_handle(uint8 dat);//用户执行操作函数
void Delay200ms();
void Led_test(void);//单片机工作指示
void Send_Data(uint8_t Key_val);//串口发送函数
uint8_t G0_flag = DISABLE; //运行标志,ENABLE:运行。DISABLE:禁止运行
sbit LED = P4 ^ 2; //信号指示灯
sbit SRD1 = P1 ^ 0;
sbit SRD2 = P1 ^ 1;
sbit SRD3 = P1 ^ 3;
sbit SRD4 = P1 ^ 2;
/***********************************************************
* 名    称: void  main(void)
* 功    能: 主函数	程序入口
* 入口参数:
* 出口参数:
* 说    明:
* 调用方法:
**********************************************************/
void  main(void)
{
	uint8 idata nAsrRes;
	uint8 i = 0;
	P1M0 = 0xFF;
	P1M1 = 0x00;
	SRD1 = SRD2 = SRD3 = SRD4 = 0;
	Led_test();
	MCU_init();
	LD_Reset();
	UartIni(); /*串口初始化*/
	nAsrStatus = LD_ASR_NONE;		//	初始状态:没有在作ASR
	PrintCom("<G>欢迎使用");
	while(1)
	{
		switch(nAsrStatus)
		{
		case LD_ASR_RUNING:
		case LD_ASR_ERROR:
			break;
		case LD_ASR_NONE:
		{
			nAsrStatus = LD_ASR_RUNING;
			if (RunASR() == 0)	/*	启动一次ASR识别流程:ASR初始化,ASR添加关键词语,启动ASR运算*/
			{
				nAsrStatus = LD_ASR_ERROR;
			}
			break;
		}
		case LD_ASR_FOUNDOK: /*	一次ASR识别流程结束,去取ASR识别结果*/
		{
			nAsrRes = LD_GetResult();		/*获取结果*/
			User_handle(nAsrRes);//用户执行函数
			nAsrStatus = LD_ASR_NONE;
			break;
		}
		case LD_ASR_FOUNDZERO:
		default:
		{
			nAsrStatus = LD_ASR_NONE;
			break;
		}
		}// switch
	}// while

}
/***********************************************************
* 名    称: 	 LED灯测试
* 功    能: 单片机是否工作指示
* 入口参数: 无
* 出口参数:无
* 说    明:
**********************************************************/
void Led_test(void)
{
	LED = ~ LED;
	Delay200ms();
	LED = ~ LED;
	Delay200ms();
	LED = ~ LED;
	Delay200ms();
	LED = ~ LED;
	Delay200ms();
	LED = ~ LED;
	Delay200ms();
	LED = ~ LED;
}
/***********************************************************
* 名    称: void MCU_init()
* 功    能: 单片机初始化
* 入口参数:
* 出口参数:
* 说    明:
* 调用方法:
**********************************************************/
void MCU_init()
{
	P0 = 0xff;
	P1 = 0x00;
	P2 = 0xff;
	P3 = 0xff;
	P4 = 0xff;



		AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x00;		//设置定时初值
	TH0 = 0x28;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0 = 1;
	
     	SM0=0;//设置串口工作方式
      SM1=1;
      ES=1;//打开串口中断
	
	LD_MODE = 0;		//	设置MD管脚为低,并行模式读写
	IE0 = 1;
	EX0 = 1;
	EA = 1;
	WDT_CONTR = 0x3D;
}
/***********************************************************
* 名    称:	延时函数
* 功    能:
* 入口参数:
* 出口参数:
* 说    明:
* 调用方法:
**********************************************************/
void Delay200us()		//@22.1184MHz
{
	unsigned char i, j;
	_nop_();
	_nop_();
	i = 5;
	j = 73;
	do
	{
		while (--j);
	}
	while (--i);
}

void  delay(unsigned long uldata)
{
	unsigned int j  =  0;
	unsigned int g  =  0;
	while(uldata--)
		Delay200us();
}

void Delay200ms()		//@22.1184MHz
{
	unsigned char i, j, k;

	i = 17;
	j = 208;
	k = 27;
	do
	{
		do
		{
			while (--k);
		}
		while (--j);
	}
	while (--i);
}

/***********************************************************
* 名    称: 中断处理函数
* 功    能:
* 入口参数:
* 出口参数:
* 说    明:
* 调用方法:
**********************************************************/
void ExtInt0Handler(void) interrupt 0
{
	ProcessInt0();
}
/***********************************************************
* 名    称:串口发送函数
* 功    能:识别成功后,执行动作可在此进行修改
* 入口参数: 无
* 出口参数:无
* 说    明:
**********************************************************/
void Send_Data(uint16_t Key_val)
{
    SBUF=Key_val;      //将要发送的数据存入发送缓冲器中
    while(!TI);        //若发送中断标志位没有置1(正在发送数据),就等待
    TI=0;              //若发送完成,TI自动置1,这里把它清零
}
/***********************************************************
* 名    称:用户执行函数
* 功    能:识别成功后,执行动作可在此进行修改
* 入口参数: 无
* 出口参数:无
* 说    明:
**********************************************************/
void 	User_handle(uint16_t dat)
{
	if(0 == dat)
	{
		G0_flag = ENABLE;
		LED = 0;
	}
	else if(ENABLE == G0_flag)
	{
		G0_flag = DISABLE;
		LED = 1;
		switch(dat)
		{
		case CODE_1:	 /*命令“前进”*/
			Send_Data(0x01);
		  SRD1 = 1;
		  SRD2 = 0;
		  SRD3 = 1;
		  SRD4 = 0;	
		Delay200ms();
		Delay200ms();
		Delay200ms();
		Delay200ms();
		Delay200ms();
			SRD1 = 0;
		  SRD2 = 0;
		  SRD3 = 0;
		  SRD4 = 0;
			break;
		case CODE_2:			/*命令“后退”*/
			Send_Data(2);	
		SRD1 = 0;
		  SRD2 = 1;
		  SRD3 = 0;
		  SRD4 = 1;
				Delay200ms();
		Delay200ms();
		Delay200ms();
		Delay200ms();
		Delay200ms();
			SRD1 = 0;
		  SRD2 = 0;
		  SRD3 = 0;
		  SRD4 = 0;
			break;
		case CODE_3:		/*命令“左转”*/
			Send_Data(3);	
		SRD1 = 1;
		  SRD2 = 0;
		  SRD3 = 0;
		  SRD4 = 1;
		Delay200ms();
		Delay200ms();
		Delay200ms();
			SRD1 = 0;
		  SRD2 = 0;
		  SRD3 = 0;
		  SRD4 = 0;
			break;
		case CODE_4:			/*命令“右转”*/
			Send_Data(4);	
		SRD1 = 0;
		  SRD2 = 1;
		  SRD3 = 1;
		  SRD4 = 0;
		Delay200ms();
		Delay200ms();
		Delay200ms();
			SRD1 = 0;
		  SRD2 = 0;
		  SRD3 = 0;
		  SRD4 = 0;
			break;
		case CODE_5:		/*命令“打开冰箱”*/
			SRD3 = 1;
			PrintCom("<G>冰箱已打开\r\n");
			break;
		case CODE_6:		/*命令“关闭冰箱”*/
			SRD3 = 0;
			PrintCom("<G>冰箱已关闭\r\n");
			break;
		case CODE_7:		/*命令“打开空调”*/
			SRD4 = 1;
			PrintCom("<G>空条已打开\r\n");
			break;
		case CODE_8:		/*命令“关闭空调”*/
			SRD4 = 0;
			PrintCom("<G>空条已关闭\r\n");
			break;
		case CODE_9:		/*命令“全部打开”*/
			SRD1 = 1;
			SRD2 = 1;
			SRD3 = 1;
			SRD4 = 1;
			PrintCom("<G>已全部打开\r\n");
			break;
		case CODE_10:		/*命令“全部关闭”*/
			SRD1 = 0;
			SRD2 = 0;
			SRD3 = 0;
			SRD4 = 0;
			PrintCom("<G>已全部关闭\r\n");
			break;
		case CODE_11:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_12:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_13:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_14:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_15:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_16:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_17:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_18:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_19:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_20:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_21:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_22:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_23:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_24:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_25:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_26:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_27:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_28:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_29:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_30:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_31:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_32:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_33:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_34:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_35:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_36:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_37:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_38:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_39:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_40:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_41:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_42:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_43:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_44:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_45:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_46:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_47:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_48:		/*命令“.....”*/

			PrintCom("");
			break;
		case CODE_49:		/*命令“.....”*/

			PrintCom("");
			break;
		default:/*text.....*/
			break;
		}
	}
	else
	{
		//PrintCom("请说出一级口令\r\n"); /*text.....*/
	}
}

void tm0_isr() interrupt 1
{
    TL0 = 0x00;		//设置定时初值
	TH0 = 0x28;		//设置定时初值
	WDT_CONTR=0x3D;
		
}

 LDChip.c

/*******************************************************
**	CPU: STC11L08XE
**	晶振:22.1184MHZ
**	波特率:9600 bit/S
**  口令模式: 即每次识别时都需要说“小杰”这个口令 ,才能够进行下一级的识别
/*********************************************************/
#include "config.h"

extern void  delay(unsigned long uldata);

uint8 idata ucRegVal;
extern uint8 idata nAsrStatus;

void ProcessInt0(void);

/************************************************************************
功能描述: 	 复位LD模块
入口参数:	 none
返 回 值: 	 none
其他说明:	 none
**************************************************************************/
void LD_Reset()
{
  RSTB=1;
  delay(5);
  RSTB=0;
  delay(5);
  RSTB=1;

  delay(5);
  CSB=0;
  delay(5);
  CSB=1;
  delay(5);
}
/************************************************************************
功能描述: LD模块命令初始化
入口参数: none
返 回 值: none
其他说明: 该函数为出厂配置,一般不需要修改;
					 有兴趣的客户可对照开发手册根据需要自行修改。
**************************************************************************/
void LD_Init_Common()
{
  LD_ReadReg(0x06);
  LD_WriteReg(0x17, 0x35);
  delay(10);
  LD_ReadReg(0x06);

  LD_WriteReg(0x89, 0x03);
  delay(5);
  LD_WriteReg(0xCF, 0x43);
  delay(5);
  LD_WriteReg(0xCB, 0x02);

  /*PLL setting*/
  LD_WriteReg(0x11, LD_PLL_11);

  LD_WriteReg(0x1E,0x00);
  LD_WriteReg(0x19, LD_PLL_ASR_19);
  LD_WriteReg(0x1B, LD_PLL_ASR_1B);
  LD_WriteReg(0x1D, LD_PLL_ASR_1D);
  delay(10);

  LD_WriteReg(0xCD, 0x04);
//	LD_WriteReg(0x17, 0x4c);
  delay(5);
  LD_WriteReg(0xB9, 0x00);
  LD_WriteReg(0xCF, 0x4F);
  LD_WriteReg(0x6F, 0xFF);
}

/************************************************************************
功能描述: 	 LD模块 ASR功能初始化
入口参数:	 none
返 回 值: 	 none
其他说明:	 该函数为出厂配置,一般不需要修改;
					 有兴趣的客户可对照开发手册根据需要自行修改。
**************************************************************************/
void LD_Init_ASR()
{
  LD_Init_Common();
  LD_WriteReg(0xBD, 0x00);
  LD_WriteReg(0x17, 0x48);
  delay( 10 );
  LD_WriteReg(0x3C, 0x80);
  LD_WriteReg(0x3E, 0x07);
  LD_WriteReg(0x38, 0xff);
  LD_WriteReg(0x3A, 0x07);
  LD_WriteReg(0x40, 0);
  LD_WriteReg(0x42, 8);
  LD_WriteReg(0x44, 0);
  LD_WriteReg(0x46, 8);
  delay( 1 );
}

/************************************************************************
功能描述: 	中断处理函数
入口参数:	 none
返 回 值: 	 none
其他说明:	当LD模块接收到音频信号时,将进入该函数,
						判断识别是否有结果,如果没有从新配置寄
            存器准备下一次的识别。
**************************************************************************/
void ProcessInt0(void)
{
  uint8 nAsrResCount=0;

  EX0=0;
  ucRegVal = LD_ReadReg(0x2B);
  LD_WriteReg(0x29,0) ;
  LD_WriteReg(0x02,0) ;
  if((ucRegVal & 0x10) &&
      LD_ReadReg(0xb2)==0x21 &&
      LD_ReadReg(0xbf)==0x35)			/*识别成功*/
  {
    nAsrResCount = LD_ReadReg(0xba);
    if(nAsrResCount>0 && nAsrResCount<=4)
    {
      nAsrStatus=LD_ASR_FOUNDOK;
    }
    else
    {
      nAsrStatus=LD_ASR_FOUNDZERO;
    }
  }															 /*没有识别结果*/
  else
  {
    nAsrStatus=LD_ASR_FOUNDZERO;
  }

  LD_WriteReg(0x2b, 0);
  LD_WriteReg(0x1C,0);/*写0:ADC不可用*/

  LD_WriteReg(0x29,0) ;
  LD_WriteReg(0x02,0) ;
  LD_WriteReg(0x2B,  0);
  LD_WriteReg(0xBA, 0);
  LD_WriteReg(0xBC,0);
  LD_WriteReg(0x08,1);	 /*清除FIFO_DATA*/
  LD_WriteReg(0x08,0);	/*清除FIFO_DATA后 再次写0*/


  EX0=1;
}

/************************************************************************
功能描述: 	运行ASR识别流程
入口参数:	none
返 回 值:  asrflag:1->启动成功, 0—>启动失败
其他说明:	识别顺序如下:
						1、RunASR()函数实现了一次完整的ASR语音识别流程
						2、LD_AsrStart() 函数实现了ASR初始化
						3、LD_AsrAddFixed() 函数实现了添加关键词语到LD3320芯片中
						4、LD_AsrRun()	函数启动了一次ASR语音识别流程
						任何一次ASR识别流程,都需要按照这个顺序,从初始化开始
**************************************************************************/
uint8 RunASR(void)
{
  uint8 i=0;
  uint8 asrflag=0;
  for (i=0; i<5; i++)			//	防止由于硬件原因导致LD3320芯片工作不正常,所以一共尝试5次启动ASR识别流程
  {
    LD_AsrStart();
    delay(50);
    if (LD_AsrAddFixed()==0)
    {
      LD_Reset();			//	LD3320芯片内部出现不正常,立即重启LD3320芯片
      delay(50);			//	并从初始化开始重新ASR识别流程
      continue;
    }
    delay(10);
    if (LD_AsrRun() == 0)
    {
      LD_Reset();			//	LD3320芯片内部出现不正常,立即重启LD3320芯片
      delay(50);			//	并从初始化开始重新ASR识别流程
      continue;
    }
    asrflag=1;
    break;					//	ASR流程启动成功,退出当前for循环。开始等待LD3320送出的中断信号
  }

  return asrflag;
}
/************************************************************************
功能描述:  检测LD模块是否空闲
入口参数:	none
返 回 值: 	flag:1-> 空闲
其他说明:	none
**************************************************************************/
uint8 LD_Check_ASRBusyFlag_b2()
{
  uint8 j;
  uint8 flag = 0;
  for (j=0; j<10; j++)
  {
    if (LD_ReadReg(0xb2) == 0x21)
    {
      flag = 1;
      break;
    }
    delay(10);
  }
  return flag;
}
/************************************************************************
功能描述: 	启动ASR
入口参数:	none
返 回 值: 	none
其他说明:	none
**************************************************************************/
void LD_AsrStart()
{
  LD_Init_ASR();
}
/************************************************************************
功能描述: 	运行ASR
入口参数:	none
返 回 值: 	1:启动成功
其他说明:	none
**************************************************************************/
uint8 LD_AsrRun()
{
  EX0=0;
  LD_WriteReg(0x35, MIC_VOL);
  LD_WriteReg(0x1C, 0x09);
  LD_WriteReg(0xBD, 0x20);
  LD_WriteReg(0x08, 0x01);
  delay( 1 );
  LD_WriteReg(0x08, 0x00);
  delay( 1 );

  if(LD_Check_ASRBusyFlag_b2() == 0)
  {
    return 0;
  }
//	LD_WriteReg(0xB6, 0xa); //识别时间	 1S
//	LD_WriteReg(0xB5, 0x1E); //背景音段时间 300ms
//	LD_WriteReg(0xB8, 10); //结束时间

//	LD_WriteReg(0x1C, 0x07); //配置双通道音频信号做为输入信号
  LD_WriteReg(0x1C, 0x0b); //配置麦克风做为输入信号


  LD_WriteReg(0xB2, 0xff);
  delay( 1);
  LD_WriteReg(0x37, 0x06);
  delay( 1 );
  LD_WriteReg(0x37, 0x06);
  delay( 5 );
  LD_WriteReg(0x29, 0x10);

  LD_WriteReg(0xBD, 0x00);
  EX0=1;
  return 1;
}
/************************************************************************
功能描述: 向LD模块添加关键词
入口参数: none
返 回 值: flag:1->添加成功
其他说明: 用户修改.
					 1、根据如下格式添加拼音关键词,同时注意修改sRecog 和pCode 数组的长度
					 和对应变了k的循环置。拼音串和识别码是一一对应的。
					 2、开发者可以学习"语音识别芯片LD3320高阶秘籍.pdf"中
           关于垃圾词语吸收错误的用法,来提供识别效果。
					 3、”xiao jie “ 为口令,故在每次识别时,必须先发一级口令“小捷”
**************************************************************************/
uint8 LD_AsrAddFixed()
{
  uint8 k, flag;
  uint8 nAsrAddLength;
#define DATE_A 50   /*数组二维数值*/
#define DATE_B 20		/*数组一维数值*/
  uint8 code sRecog[DATE_A][DATE_B] =
  {
    "da ge",\
    "qian jin",\
    "hou tui",\
    "zuo zhuan",\
    "you zhuan",\
    "da kai bing xiang",\
    "guan bi bing xiang",\
    "da kai kong tiao",\
    "guan bi kong tiao",\
    "quan bu da kai",\
    "quan bu guan bi",\
  };	/*添加关键词,用户修改*/
  uint8 code pCode[DATE_A] =
  {
    CODE_CMD, \
		CODE_1, \
		CODE_2, \
		CODE_3, \
		CODE_4, \
		CODE_5, \
		CODE_6, \
		CODE_7, \
		CODE_8, \
		CODE_9, \
		CODE_10, \
		CODE_11, \
		CODE_12, \
		CODE_13, \
		CODE_14, \
		CODE_15, \
		CODE_16, \
		CODE_17, \
		CODE_18, \
		CODE_19, \
		CODE_20, \
		CODE_21, \
		CODE_22, \
		CODE_23, \
		CODE_24, \
		CODE_25, \
		CODE_26, \
		CODE_27, \
		CODE_28, \
		CODE_29, \
		CODE_30, \
		CODE_31, \
		CODE_32, \
		CODE_33, \
		CODE_34, \
		CODE_35, \
		CODE_36, \
		CODE_37, \
		CODE_38, \
		CODE_39, \
		CODE_40, \
		CODE_41, \
		CODE_42, \
		CODE_43, \
		CODE_44, \
		CODE_45, \
		CODE_46, \
		CODE_47, \
		CODE_48, \
		CODE_49, \
  };	/*添加识别码,用户修改*/
  flag = 1;
  for (k=0; k<DATE_A; k++)
  {

    if(LD_Check_ASRBusyFlag_b2() == 0)
    {
      flag = 0;
      break;
    }

    LD_WriteReg(0xc1, pCode[k] );
    LD_WriteReg(0xc3, 0 );
    LD_WriteReg(0x08, 0x04);
    delay(1);
    LD_WriteReg(0x08, 0x00);
    delay(1);

    for (nAsrAddLength=0; nAsrAddLength<DATE_B; nAsrAddLength++)
    {
      if (sRecog[k][nAsrAddLength] == 0)
        break;
      LD_WriteReg(0x5, sRecog[k][nAsrAddLength]);
    }
    LD_WriteReg(0xb9, nAsrAddLength);
    LD_WriteReg(0xb2, 0xff);
    LD_WriteReg(0x37, 0x04);
  }
  return flag;
}
/************************************************************************
功能描述: 	获取识别结果
入口参数:	none
返 回 值: 	LD_ReadReg(0xc5 );  读取内部寄存器返回识别码。
其他说明:	none
**************************************************************************/
uint8 LD_GetResult()
{
  return LD_ReadReg(0xc5 );
}



  LDChip.h文章来源地址https://www.toymoban.com/news/detail-457828.html

/*******************************************************
**	CPU: STC11L08XE
**	晶振:22.1184MHZ
**	波特率:9600 bit/S
**  口令模式: 即每次识别时都需要说“小杰”这个口令 ,才能够进行下一级的识别
/*********************************************************/


#ifndef LD_CHIP_H
#define LD_CHIP_H

#define uint8 unsigned char
#define uint16 unsigned int
#define uint32 unsigned long

//	以下五个状态定义用来记录程序是在运行ASR识别过程中的哪个状态
#define LD_ASR_NONE				0x00	 /*	表示没有在作ASR识别*/
#define LD_ASR_RUNING			0x01	/*	表示LD3320正在作ASR识别中*/
#define LD_ASR_FOUNDOK			0x10	/*表示一次识别流程结束后,有一个识别结果*/
#define LD_ASR_FOUNDZERO 		0x11	/*表示一次识别流程结束后,没有识别结果*/
#define LD_ASR_ERROR	 		0x31	/*表示一次识别流程中LD3320芯片内部出现不正确的状态*/


#define CLK_IN   		22.1184	/* 用户注意修改输入的晶振时钟大小 */
#define LD_PLL_11			(uint8)((CLK_IN/2.0)-1)
#define LD_PLL_MP3_19		0x0f
#define LD_PLL_MP3_1B		0x18
#define LD_PLL_MP3_1D   	(uint8)(((90.0*((LD_PLL_11)+1))/(CLK_IN))-1)

#define LD_PLL_ASR_19 		(uint8)(CLK_IN*32.0/(LD_PLL_11+1) - 0.51)
#define LD_PLL_ASR_1B 		0x48
#define LD_PLL_ASR_1D 		0x1f

//函数声明
void LD_Reset();
void LD_Init_Common();
void LD_Init_ASR();
uint8 RunASR(void);
void LD_AsrStart();
uint8 LD_AsrRun();
uint8 LD_AsrAddFixed();
uint8 LD_GetResult();


//识别码客户修改处
#define CODE_CMD  0x00   //该命令码0x00用户不可进行修改。

#define CODE_1	0x01
#define CODE_2	0x02
#define CODE_3 	0x04
#define CODE_4 	0x14

#define CODE_5 	0x15
#define CODE_6 	0x16
#define CODE_7	0x17
#define CODE_8	0x18

#define CODE_9  0x19
#define CODE_10 0x1A
#define CODE_11 0x1B
#define CODE_12 0x1C

#define CODE_13 0x1D
#define CODE_14 0x1E
#define CODE_15 0x1F
#define CODE_16 0x20

#define CODE_17 0x21
#define CODE_18 0x22
#define CODE_19 0x23
#define CODE_20 0x24

#define CODE_21 0x25
#define CODE_22 0x26
#define CODE_23 0x27
#define CODE_24 0x28

#define CODE_25 0x29
#define CODE_26 0x2A
#define CODE_27 0x2B
#define CODE_28 0x2C

#define CODE_29 0x2D
#define CODE_30 0x2E
#define CODE_31 0x2F
#define CODE_32 0x30

#define CODE_33 0x31
#define CODE_34 0x32
#define CODE_35 0x33
#define CODE_36 0x34

#define CODE_37 0x35
#define CODE_38 0x36
#define CODE_39 0x37
#define CODE_40 0x38

#define CODE_41 0x39
#define CODE_42 0x3A
#define CODE_43 0x3B
#define CODE_44 0x3C

#define CODE_45 0x3D
#define CODE_46 0x3E
#define CODE_47 0x3F
#define CODE_48 0x40

#define CODE_49 0x41

//数值越大越灵敏识别距离越远,但误识别率就越大, 根据自己的实际情况调节。
#define MIC_VOL 0x43	 //咪头增益(灵敏度调节) 范围:00-7f 
#endif

到了这里,关于基于LD3320的51智能遥控语音小车的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32F103C8T6+LD3320语音识别模块智能灯控

    由于代码需求量过大,不方便一一回复,请大家关注微信公众号“微电子基地”(头像与CSDN头像一致),点击智能灯控即可获取项目代码及功能介绍,注:仅供参考学习。  LD3320 是一颗基于非特定人语音识别(SI-ASR:Speaker-Independent Automatic SpeechRecognition)技术的语音识别/声

    2023年04月09日
    浏览(32)
  • 毕业设计 单片机语音识别分类智能垃圾桶(STM32 ESP8266 LD3320)

    离线语音识别识别垃圾种类并且垃圾桶自动翻盖: 说出唤醒词“垃圾桶”后,再说一句垃圾名称,语音识别模块端识别到相应,便会将结果通过串口发送到STM32端,STM32端接着会发送打开相应垃圾桶盖的指令,6s后,垃圾桶盖自动关闭。其中翻盖功能是通过STM32端控制舵

    2024年04月26日
    浏览(42)
  • 基于 STM32 的语音识别智能家居控制系统的设计(LD3320语音识别芯片+ESP8266 WIFI模块+DHT11温湿度采集+MQ系列 烟雾及可燃气体+蜂鸣器+步进电机模拟窗帘+OLED液晶显示+

    ## **基于 STM32 的语音识别智能家居控制系统的设计(LD3320语音识别芯片+ESP8266 WIFI模块(阿里云 或ONENET或局域网)+DHT11温湿度采集+MQ系列 烟雾及可燃气体+蜂鸣器+步进电机模拟窗帘+OLED液晶显示+手机APP)** 本文采用LD3320语音识别芯片+ESP8266 WIFI模块+DHT11温湿度采集+MQ系列 烟雾及可

    2024年02月04日
    浏览(36)
  • LD3320语音识别模块分析

       LD3320是非特定人语音识别芯片,即语音声控芯片。最多可以识别50条预先内置的指令。 识别原理  声音分帧:   声音是一种波,常见的mp3等格式都是压缩格式,必须转为非压缩的纯波形文件来处理,比如Windows PCM文件,也就是wav文件。wav文件李存储的除了一个文件头

    2024年02月05日
    浏览(78)
  • 基于51单片机的多功能智能语音循迹避障小车

    目录 一.功能介绍及硬件准备 二.电机控制及调速 三.小车循迹方案 四.跟随功能实现 五.测速功能实现 六.OLED显示车速 七.摇头避障功能实现 八.SU-03T语音模块介绍 九.语音切换小车模式+OLED显示模式 这是一款基于51单片机开发的智能小车,通过这篇文章我会记录下来开发这款小

    2024年02月03日
    浏览(31)
  • 【毕业设计】58-基于51单片机的智能语音密码锁设计(原理工程+PCB工程+仿真工程+源代码+答辩论文+实物图)

    主要研究内容: 掌握电子密码锁的原理、构造、以及运用51单片机设计出一款简易密码锁,实现相应的一些要求;掌握并且实际运用所学知识,将书中知识转化为实际能力;对密码锁的应用和未来的发展进行分析。 研究方法: 通过相关的书籍和网上资料,查阅相关资料,收集有

    2024年02月05日
    浏览(48)
  • 【STM32+HAL】语音识别模块LD3320(SPI版)

    有关CUBEMX的初始化配置,参见我的另一篇blog:【STM32+HAL】CUBEMX初始化配置 1、芯片: STM32F103C6T6(同C8T6) 2、STM32CubeMx软件 3、语言识别模块:LD3320(SPI版) 实现串口打印语音输入 1、SPI功能开启 2、IO口配置 3、中断配置 至此,HAL库配置完成 1、LD3320.C 2、LD3320.H 3、主函数 若要

    2024年02月19日
    浏览(30)
  • STM32单片机与LD3320语音模块的交互方法

    在嵌入式系统中,STM32单片机广泛应用于各种应用领域。而LD3320语音模块是一种常用的语音识别与合成模块。本文将介绍如何在STM32单片机上与LD3320语音模块进行交互,并提供相应的源代码。 硬件连接 首先,我们需要将STM32单片机与LD3320语音模块进行正确的硬件连接。以下是

    2024年03月13日
    浏览(44)
  • “无限交互,全新驾驶体验!智能语音小车,与您共同开创未来出行。”#51单片机最终项目《智能语音小车》【中】

      本篇博文介绍的是用51单片机的最终项目《智能语音小车》【中】,包含循迹小车基本原理和方案,根据循迹原理实现循迹功能代码编写,解决冲出赛道不转弯问题,优化转弯平滑。加入电机调速,跟随小车,摇头测距小车01_舵机和超声波封装,摇头测距小车02_实现疯狂

    2024年02月21日
    浏览(42)
  • 基于Arduino UNO的智能自主避障小车和蓝牙遥控小车

           Hello,大家好!今天我要给大家分享我近期制作的一个arduino小项目----智能避障小车。之前在某站上无意间刷到某位博主制作的一款智能避障小车,觉得很有意思,便打算自己也做一个来玩玩,于是便制作了一款我自己理解的避障小车。在此基础上,我还增加了蓝牙遥控

    2024年02月01日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包