单片机学习小组
直播中

贾虎世

7年用户 1662经验值
私信 关注

怎样去设计一种基于STM32的循迹避障小车呢

LD3320 Board模块如何与MCU进行连接啊?
怎样去设计一种基于STM32的循迹避障小车呢?

回帖(3)

王冬梅

2022-1-27 11:55:35
前些天博主课程设计做了一个基于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);
}
举报

周奕

2022-1-27 11:55:46
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;
}
举报

孔维源

2022-1-27 11:55:55
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**********************/
举报

更多回帖

×
20
完善资料,
赚取积分