飞思卡尔KL36和LD3320结合的语音识别系统

KL36和LD3320结合的语音识别系统

前言

在网上买的LD3320一般都是STM32或者STC或者Arduino的,没有比较冷门的板子,比如飞思卡尔的M+系列或者KL系列,但是我学的又是这些冷门的板子,所以进行了移植,现在算是移植成功了,移植过程遇到了许多问题,来分享一下

两个板子之间的通信原理

首先我们要知道他的通信原理,就是一句话,通过读或者写LD33320的寄存器来进行对控制,具体的寄存器可以查看LD3320的开发手册,读和写寄存器有两种方式,我们常用的就是用SPI通信,所以刚一开始遇到的问题就是不能正常读取寄存器,通过查找问题发现,是SPI通信的问题。

SPI通信遇到的问题

1.读取寄存器的值为0

首先我们要理解SPI通信的原理,具体的通信机制可以上网查,我这里最后理解的是,在接受数据的时候,主不能没事干,只充当一个接收者,也要发送数据,才能接收到数据,因为KL36板子的spi提供的驱动函数把发送函数和接收函数是分开的,所以当初一直读取寄存器为0,头疼了几天,最后把两个函数结合起来,在读取寄存器函数里面也要发送0x00过去,就能正常读取到寄存器的值了。要注意的是要把CPOL=0,CPHA=1

根本不用进入到SPI中断拿返回值(KDS提供的中断都会统一写在isr.c文件)
当初也一直以为中断拿返回值卡了很久

static uint_8 spi_send_byte(uint_8 No,uint_8 data)
		{
		    SPI_MemMapPtr baseadd=SPI_baseadd(No);
		    while(!(SPI_S_REG(baseadd)&SPI_S_SPTEF_MASK));//等待发送缓冲区空闲
		           SPI_DL_REG(baseadd)=data;//数据寄存器接收数据

		    while(!(SPI_S_REG(baseadd)& SPI_S_SPRF_MASK));    //检测SPI是否收到了数据。
		        return SPI_DL_REG(baseadd);
		}
unsigned char LD_ReadReg( unsigned char address )
		{
			uint_8 i;

			gpio_set(WR, 0);

			gpio_set(GEC_22, 0);

			spi_send_byte(SPIB,0x05); // 发送 0x05

			spi_send_byte(SPIB,address); // 发送 address

			i=spi_send_byte(SPIB,0x00);

			gpio_set(GEC_22, 1);

			return i;
		}

关于初始化的配置遇到的问题

我们要对一些引脚进行初始化,这些也是我遇到的一些问题

1 初始化了SPIB之后,执行不下去

KL36提供了两组SPI,当我想使用SPIB进行通信时,发现程序执行不下去了,但是当我把两组都初始化之后,就能正常执行下去了,所以应该是要把全部的SPI都进行初始化,才能使用,不知道是不是所有的单片机都是这样。

解决方法:把两组SPI都进行初始化

    gpio_init(GEC_31,0,0);    //设置SS为输入
    spi_init(SPIA,1,6000,0,0);  //初始化SPI0为主机
	spi_init(SPIB,1,1500,0,1);  //初始化SPI1为主机
	gpio_init(GEC_22,1,0);    //设置SS为输入     连LD的CS

2 不能将CS片选信号进行控制,就是输出高电平还是低电平

我们知道,SPI通信有一根线是CS片选信号,对LD3320进行通信的时候,要求CS片选信号是低电平,但是我们利用get获取引脚电平或者软件模拟的时候,发现CS引脚总是高电平,就算是用函数输出低电平还是一样,经过研究发现,改引脚在SPI_init的时候,把引脚设置为了输入,所以才总是高电平,控制不了,但是要求是低电平

解决方法:在SPI初始化之后,再将引脚复用为GPIO,输出,就可以对引脚进行输出高低电平的控制了

运行的时候遇到的问题

在能正常读取寄存器之后,以为就能很快进行语音的控制了,但是又遇到了一大堆问题,卡了好几天

1 不能多次循环识别,烧录进去之后只能执行一次

这个的问题就是不能回到主函数执行循环体,当时以为是LD3320不能多次产生中断,或者是以为退出不了中断处理程序,因此还加了恩智浦的讨论群,后来发现其实不是这样,这个模块是只要有声音,就会产生中断,多次试验后发现,是自己写的中断出问题了
解决方法:直接在中断里面写开发手册写好的中断,然后自己在关外部中断开外部中断

void GPIOB_Handler(void)
{

	ProcessInt0();
	gpio_clear_int(IRQ);
	gpio_reverse(LIGHT_RED);
	ENABLE_INTERRUPTS;

}

2 中断处理函数得到LD3320当前状态后,不能将LD_ASR_FOUNDOK返回值给主函数,case到然后执行处理函数

这个问题其实是和上面的那个问题结合起来的,所以当时不知道是哪里出了问题,明明产生中断了并且识别成功有正确返回值了,但是回到主函数之后就是不能被case到LD_ASR_FOUNDOK,就非常纳闷,正常的流程就应该获取结果然后进行引脚操作,后来参考了别人的程序,

解决方法:执行函数是在switch和while之前插入一个执行函数,就能进入到LD_ASR_FOUNDOK里面并且能循环执行了,非常奇怪,然后自己写了一个
接口函数

	       }//switch
			control(nAsrRes);//这里插入
    	}//while
static void control(uint_8 Coad_val)
{
	switch(Coad_val)
	{
	case 1:
			gpio_set(LIGHT_GREEN, LIGHT_ON);
			break;
	case 3:
			gpio_set(LIGHT_GREEN, LIGHT_OFF);
			break;
	default:
		break;
	}
}

识别不准确的问题

能识别之后,发现,识别非常的不准确,添加垃圾词之后,勉强能准确那么一点,但是有时候甚至开灯识别到关灯,这个的话后期经过调整语音监测点寄存器应该能好点,或者说,这个芯片就是识别的这么不准确,那就没办法了

Alt

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值