完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
前些天博主课程设计做了一个基于STM32的循迹避障小车,用的是在某宝上买的智能小车的套件,后来闲来无事想改造成一个语音控制的小车,于是又淘了一个ld3320的语音模块,通过语音命令能够控制小车前进、后退、转弯和停止。
资料里面有stm32的例程,是用语音控制开发板的LED灯,看了资料后发现例程中使用的开发板芯片和我使用的正好相同,都是使用的stm32f103zet6芯片,所以语音模块的串口没有改动,只简单改动了一下LED灯的串口就能用了。 下面是LD3320的引脚图: 如果你的开发板上有对应的串口,可以直接按下图的引脚连接: 博主把代码烧录到板子后才发现自己的板子没有LED灯,是的,没有LED灯,博主都要哭了,于是一生气就把核心板撬掉了,换了一个指南者的板子,花费了两个小时把指南者板子上的引脚连到扩展板对应的引脚上,再烧录程序后发现程序可以正常运行。 下一步把板子装到小车上 接下来就是程序的问题了,把语音代码和红外避障的代码整合起来,虽然听起来简单,但实际遇到很多问题,比如中断冲突等,博主呕心沥血花了一周时间查阅数据手册和开发手册,终于解决了问题。 于是赶紧把小车放到地上调试,结果遇到了一个更麻烦的问题,LD3320自带的咪头引脚很短,而语音识别的距离很近,所以小车放在地上根本无法识别语音指令,于是博主不得不接着查阅数据手册,发现35寄存器可以修改语音识别的距离,历程中默认值是0x43,值越大识别距离越远,但同时识别的准确率会严重降低,官方推荐的值为40H—55H,重新调试程序后发现语音识别的距离还不是很理想(其实并没有多大改变),不得已,只能想其他的办法。 某天博主正在吃午饭的时候,突发奇想,能不能把咪头拆下来,再引两根线出来不就解决了吗(窃喜),幸亏博主在付诸实践之前先逛了逛论坛,里面有大牛说线太长会导致信号衰减,语音无法识别,于是博主放弃了这个念头,没敢用于实践。但这个问题怎么解决呢?博主盯着手中的筷子,突然有了一个大胆的想法,用筷子把语音模块架高, 最后,博主含泪牺牲了自己的筷子解决了这个问题。 做到这里语音控制小车基本上就完成了,但博主可不是就这样轻易满足的,博主开始想的是小车转弯的角度是90度然后停下,但实际小车会一直不停的旋转,原因是输入语音命令后,代码会把语音命令写到芯片中,然后main()函数会一直循环扫描等待新的语音命令输入,在这个规程中,代码会一直执行上次输入的语音命令,于是修改了部分代码,使每次循环把语音命令清零,解决了这个问题。 #include "LD3320.h" #include "motor.h" #include "redvoid.h" #include "stm32f10x_spi.h" #include "inteRFace.h" uint8 nAsrStatus = 0; uint8 nLD_Mode = LD_MODE_IDLE; uint8 ucRegVal; int f=1; int key=1; int key1=1; extern uint8 nAsrRes=0; ///Óû§ÐÞ¸Ä void LD3320_main(void) { LD3320_init(); nAsrStatus = LD_ASR_NONE; } static uint8 LD_AsrAddFixed(void) { uint8 k, flag; uint8 nAsrAddLength; #define DATE_A 11 #define DATE_B 20 uint8 sRecog[DATE_A][DATE_B] = { "zhi xing", "qian jin", "hou tui", "zuo zhuan", "you zhuan", "bi zhang", "ting zhi" , "ting", "bian dao", "zuopian", "youpian" }; uint8 pCode[DATE_A] = { CODE_ZX, CODE_QJ, CODE_HT, CODE_ZZ, CODE_YZ, CODE_BZ, CODE_TZ , CODE_TI , CODE_BD , CODE_ZP , CODE_YP }; flag = 1; for (k=0; k { if(LD_Check_ASRBusyFlag_b2() == 0) { flag = 0; break; } LD_WriteReg(0xc1, pCode[k] ); LD_WriteReg(0xc3, 0); LD_WriteReg(0x08, 0x04); LD3320_delay(1); LD_WriteReg(0x08, 0x00); LD3320_delay(1); for (nAsrAddLength=0; 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; } void Board_text(uint8 Code_Val) { switch(Code_Val) { case CODE_ZX: CarGo(); Key_LED(); break; case CODE_QJ: CarGo(); Key_LED(); break; case CODE_HT: CarBack(); Flicker_LED(); break; case CODE_ZZ: // if(key1==1){key=1;} CarLeft(); Jt_LED(); Delayms(1000); CarStop(); // Code_Val=7; break; case CODE_YZ: CarRight(); On_LED(); break; case CODE_BZ: VoidRun(); Off_LED(); break; case CODE_TZ: CarStop(); break; case CODE_TI: CarStop(); break; case CODE_BD: CarChange(); break; case CODE_ZP: CarStop(); break; case CODE_YP: CarStop(); break; default: break; } } /* */ //static void Delay_ms(uint16 i) //{ // unsigned char a,b; // for(;i>0;i--) // for(b=4;b>0;b--) // for(a=113;a>0;a--); //} void Flicker_LED(void) { LED1_ON(); LED2_OFF(); LED3_OFF(); Delayms(1000); LED1_OFF(); LED2_OFF(); LED3_OFF(); Delayms(1000); } void Key_LED(void) { LED2_ON(); LED1_OFF(); LED3_OFF(); } void Off_LED(void) { LED1_OFF(); LED2_OFF(); LED3_OFF(); } void On_LED(void) { LED1_ON(); LED2_ON(); LED3_ON(); } void Jt_LED(void) { LED3_ON(); LED1_OFF(); LED2_OFF(); Delayms(1000); LED3_OFF(); LED1_OFF(); LED2_OFF(); Delayms(1000); } static void LD3320_init(void) { LD3320_GPIO_Cfg(); LD3320_EXTI_Cfg(); LD3320_SPI_cfg(); LED_GPIO_cfg(); LD_reset(); } static void LD3320_GPIO_Cfg(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphclockCmd(LD3320RST_GPIO_CLK | LD3320CS_GPIO_CLK,ENABLE); //LD_CS /RSET GPIO_InitStructure.GPIO_Pin =LD3320CS_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(LD3320CS_GPIO_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin =LD3320RST_PIN; GPIO_Init(LD3320RST_GPIO_PORT,&GPIO_InitStructure); } |
|
|
|
static void LD3320_EXTI_Cfg(void)
{ EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); RCC_APB2PeriphClockCmd(LD3320IRQ_GPIO_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin =LD3320IRQ_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LD3320IRQ_GPIO_PORT, &GPIO_InitStructure); GPIO_EXTILineConfig(LD3320IRQEXIT_PORTSOURCE, LD3320IRQPINSOURCE); EXTI_InitStructure.EXTI_Line = LD3320IRQEXITLINE; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_trigger =EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = LD3320IRQN; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } static void LD3320_SPI_cfg(void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(LD3320SPI_CLK,ENABLE); RCC_APB2PeriphClockCmd(LD3320WR_GPIO_CLK | LD3320SPIMISO_GPIO_CLK | LD3320SPIMOSI_GPIO_CLK | LD3320SPISCK_GPIO_CLK,ENABLE); GPIO_InitStructure.GPIO_Pin = LD3320SPIMISO_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(LD3320SPIMISO_GPIO_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LD3320SPIMOSI_PIN; GPIO_Init(LD3320SPIMOSI_GPIO_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LD3320SPISCK_PIN; GPIO_Init(LD3320SPISCK_GPIO_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LD3320WR_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(LD3320WR_GPIO_PORT, &GPIO_InitStructure); LD_CS_H(); SPI_Cmd(LD3320SPI, DISABLE); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; SYSCLK/128 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(LD3320SPI, &SPI_InitStructure); SPI_Cmd(LD3320SPI, ENABLE); } static void LED_GPIO_cfg(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(LED1_GPIO_CLK | LED2_GPIO_CLK | LED3_GPIO_CLK,ENABLE); GPIO_InitStructure.GPIO_Pin = LED1_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LED2_PIN; GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LED3_PIN; GPIO_Init(LED3_GPIO_PORT, &GPIO_InitStructure); LED1_OFF(); LED2_OFF(); LED3_OFF(); } void EXTI15_10_IRQHandler(void) { if(EXTI_GetITStatus(LD3320IRQEXITLINE)!= RESET ) { ProcessInt(); EXTI_ClearFlag(LD3320IRQEXITLINE); } } static void LD3320_delay(unsigned long uldata) { unsigned int i = 0; unsigned int j = 0; unsigned int k = 0; for (i=0;i<5;i++) { for (j=0;j { k = 200; while(k--); } } } uint8 RunASR(void) { uint8 i=0; uint8 asrflag=0; for (i=0; i<5; i++) { LD_AsrStart(); LD3320_delay(100); if (LD_AsrAddFixed()==0) { LD_reset(); LD3320_delay(50); continue; } LD3320_delay(10); if (LD_AsrRun() == 0) { LD_reset(); LD3320_delay(50); continue; } asrflag=1; break; } return asrflag; } static void LD_reset(void) { LD_RST_H(); LD3320_delay(100); LD_RST_L(); LD3320_delay(100); LD_RST_H(); LD3320_delay(100); LD_CS_L(); LD3320_delay(100); LD_CS_H(); LD3320_delay(100); } static void LD_AsrStart(void) { LD_Init_ASR(); } uint8 LD_Check_ASRBusyFlag_b2(void) { uint8 j; uint8 flag = 0; for (j=0; j<10; j++) { if (LD_ReadReg(0xb2) == 0x21) { flag = 1; break; } LD3320_delay(10); } return flag; } ///Öмä²ãend ///¼Ä´æÆ÷²Ù×÷ static uint8 spi_send_byte(uint8 byte) { while (SPI_I2S_GetFlagStatus(LD3320SPI, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(LD3320SPI,byte); while (SPI_I2S_GetFlagStatus(LD3320SPI,SPI_I2S_FLAG_RXNE) == RESET); return SPI_I2S_ReceiveData(LD3320SPI); } static void LD_WriteReg(uint8 data1,uint8 data2) { LD_CS_L(); LD_SPIS_L(); spi_send_byte(0x04); spi_send_byte(data1); spi_send_byte(data2); LD_CS_H(); } static uint8 LD_ReadReg(uint8 reg_add) { uint8 i; LD_CS_L(); LD_SPIS_L(); spi_send_byte(0x05); spi_send_byte(reg_add); i=spi_send_byte(0x00); LD_CS_H(); return(i); } uint8 LD_GetResult(void) { return LD_ReadReg(0xc5); } static uint8 LD_AsrRun(void) { LD_WriteReg(0x35, MIC_VOL); LD_WriteReg(0x1C, 0x09); LD_WriteReg(0xBD, 0x20); LD_WriteReg(0x08, 0x01); LD3320_delay( 5 ); LD_WriteReg(0x08, 0x00); LD3320_delay( 5); if(LD_Check_ASRBusyFlag_b2() == 0) { return 0; } LD_WriteReg(0xB2, 0xff); LD_WriteReg(0x37, 0x06); LD_WriteReg(0x37, 0x06); LD3320_delay(5); LD_WriteReg(0x1C, 0x0b); LD_WriteReg(0x29, 0x10); LD_WriteReg(0xBD, 0x00); return 1; } |
|
|
|
static void ProcessInt(void)
{ uint8 nAsrResCount=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 } static void LD_Init_Common(void) { LD_ReadReg(0x06); LD_WriteReg(0x17, 0x35); LD3320_delay(5); LD_ReadReg(0x06); LD_WriteReg(0x89, 0x03); LD3320_delay(5); LD_WriteReg(0xCF, 0x43); LD3320_delay(5); LD_WriteReg(0xCB, 0x02); /*PLL setting*/ LD_WriteReg(0x11, LD_PLL_11); if (nLD_Mode == LD_MODE_MP3) { LD_WriteReg(0x1E, 0x00); LD_WriteReg(0x19, LD_PLL_MP3_19); LD_WriteReg(0x1B, LD_PLL_MP3_1B); LD_WriteReg(0x1D, LD_PLL_MP3_1D); } else { 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); } LD3320_delay(5); LD_WriteReg(0xCD, 0x04); LD_WriteReg(0x17, 0x4c); LD3320_delay(1); LD_WriteReg(0xB9, 0x00); LD_WriteReg(0xCF, 0x4F); LD_WriteReg(0x6F, 0xFF); } static void LD_Init_ASR(void) { nLD_Mode=LD_MODE_ASR_RUN; LD_Init_Common(); LD_WriteReg(0xBD, 0x00); LD_WriteReg(0x17, 0x48); LD3320_delay(5); 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); LD3320_delay( 1 ); } /*********************************************END OF FILE**********************/ |
|
|
|
只有小组成员才能发言,加入小组>>
imx6ull 和 lan8742 工作起来不正常, ping 老是丢包
3362 浏览 0 评论
3369 浏览 9 评论
3059 浏览 16 评论
3551 浏览 1 评论
9182 浏览 16 评论
1304浏览 3评论
669浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
661浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2410浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1978浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-2-22 23:06 , Processed in 1.048629 second(s), Total 53, Slave 44 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191