完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
在网上买的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; } } 识别不准确的问题 能识别之后,发现,识别非常的不准确,添加垃圾词之后,勉强能准确那么一点,但是有时候甚至开灯识别到关灯,这个的话后期经过调整语音监测点寄存器应该能好点,或者说,这个芯片就是识别的这么不准确,那就没办法了 |
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2956 浏览 16 评论
3458 浏览 1 评论
9002 浏览 16 评论
4051 浏览 18 评论
1112浏览 3评论
573浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
570浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2303浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1859浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 01:29 , Processed in 1.099968 second(s), Total 78, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号