你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32驱动LD3320进行语音识别程序+原理图

[复制链接]
STMCU小助手 发布时间:2022-4-24 16:00
一、原理图

99Ia$W`8_TY4`GM[WZB52.png

二、源代码

LD3320.c

  1. #include "ld3320.h"
  2. #include "delay.h"
  3. #include "usart.h"        
  4. #include "string.h"
  5. u8 ld3320Data;
  6. extern u8 nAsrStatus;

  7. unsigned long nMp3StartPos=0;
  8. unsigned long nMp3Size=0;
  9. unsigned long nMp3Pos=0;
  10. u8 bMp3Play=0;                                                        //        用来记录播放MP3的状态
  11. u8 nLD_Mode = LD_MODE_IDLE;                //        用来记录当前是在进行ASR识别还是在播放MP3
  12. u8 ucRegVal;
  13. u8 ucHighInt;
  14. u8 ucLowInt;
  15. u8 ucStatus;
  16. u8 ucSPVol=15; // MAX=15 MIN=0                //        Speaker喇叭输出的音量



  17. void ld3320_init()
  18. {
  19.         GPIO_InitTypeDef  GPIO_InitStructure;
  20.          EXTI_InitTypeDef EXTI_InitStructure;
  21.          NVIC_InitTypeDef NVIC_InitStructure;

  22.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);         //使能PB,PE端口时钟
  23.         
  24.         GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
  25.         
  26.         
  27.         GPIO_InitStructure.GPIO_Pin =GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_15;                                 
  28.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  
  29.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 
  30.         GPIO_Init(GPIOA, &GPIO_InitStructure);                                       
  31.         GPIO_SetBits(GPIOA,GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_15);
  32.         
  33.         GPIO_InitStructure.GPIO_Pin =GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15 ;                                 
  34.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  
  35.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 
  36.         GPIO_Init(GPIOB, &GPIO_InitStructure);                                       
  37.         GPIO_SetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_14|GPIO_Pin_15);
  38.                
  39.         
  40.         LD3320_MD=0;  //选择并口
  41.         LD3320_RST=1;        
  42.         LD3320_A0=0;
  43.         
  44.         
  45.         GPIO_InitStructure.GPIO_Pin =GPIO_Pin_11;                                 
  46.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                  
  47.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 
  48.         GPIO_Init(GPIOB, &GPIO_InitStructure);               

  49.           RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);        //使能复用功能时钟

  50.     // 中断线以及中断初始化配置   下降沿触发
  51.           GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource11);

  52.           EXTI_InitStructure.EXTI_Line=EXTI_Line11;        
  53.           EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;        
  54.           EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  55.           EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  56.           EXTI_Init(&EXTI_InitStructure);                 //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
  57.         
  58.         NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;                        //使能外部中断通道
  59.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;        //抢占优先级0
  60.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;                                        //子优先级0
  61.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                                //使能外部中断通道
  62.           NVIC_Init(&NVIC_InitStructure);            //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器        

  63. }

  64. //外部中断服务程序
  65. void EXTI15_10_IRQHandler(void)
  66. {
  67.         if(EXTI_GetITStatus(EXTI_Line11)!= RESET )
  68.         {
  69.                 ld3320_process_init();               
  70.                 EXTI_ClearFlag(EXTI_Line11);
  71.                 EXTI_ClearITPendingBit(EXTI_Line11);//清除LINE上的中断标志位  
  72.         }         
  73. }


  74. void ld3320_write_reg( unsigned char address, unsigned char dataout )
  75. {
  76.         
  77.         ld3320Data=address;
  78.         LD3320_D0=bita0;LD3320_D1=bita1;LD3320_D2=bita2;LD3320_D3=bita3;
  79.         LD3320_D4=bita4;LD3320_D5=bita5;LD3320_D6=bita6;LD3320_D7=bita7;
  80.         delay_us(1);
  81.         LD3320_A0  =1;
  82.         LD3320_CS = 0;
  83.         LD3320_WR = 0;

  84.         LD3320_WR = 1;
  85.         LD3320_CS = 1;
  86.         

  87.         
  88.         ld3320Data=dataout;
  89.         LD3320_D0=bita0;LD3320_D1=bita1;LD3320_D2=bita2;LD3320_D3=bita3;
  90.         LD3320_D4=bita4;LD3320_D5=bita5;LD3320_D6=bita6;LD3320_D7=bita7;
  91.         delay_us(1);
  92.         LD3320_A0 = 0;
  93.         LD3320_CS = 0;
  94.         LD3320_WR = 0;

  95.         LD3320_WR = 1;
  96.         LD3320_CS = 1;
  97. }

  98. unsigned char ld3320_read_reg( unsigned char address )
  99. {
  100.         unsigned char datain;

  101.         ld3320Data=address;
  102.         LD3320_D0=bita0;LD3320_D1=bita1;LD3320_D2=bita2;LD3320_D3=bita3;
  103.         LD3320_D4=bita4;LD3320_D5=bita5;LD3320_D6=bita6;LD3320_D7=bita7;
  104.         
  105.         LD3320_A0 = 1;
  106.         delay_us(1);
  107.         LD3320_CS = 0;
  108.         delay_us(1);
  109.         LD3320_WR = 0;
  110.         delay_us(1);

  111.         LD3320_WR = 1;
  112.         delay_us(1);
  113.         LD3320_CS = 1;
  114.         delay_us(1);

  115.         LD3320_A0 = 0;
  116.         delay_us(1);
  117.         LD3320_CS = 0;
  118.         delay_us(1);
  119.         LD3320_RD = 0;
  120.         LD3320_DATA_IN();
  121.         delay_us(1);
  122.         
  123.         bita0=LD3320_D0_R;bita1=LD3320_D1_R;bita2=LD3320_D2_R;bita3=LD3320_D3_R;
  124.         bita4=LD3320_D4_R;bita5=LD3320_D5_R; bita6=LD3320_D6_R;bita7=LD3320_D7_R;
  125.         datain= ld3320Data;
  126.         
  127.         LD3320_DATA_OUT();
  128.         LD3320_RD = 1;
  129.         delay_us(1);
  130.         LD3320_CS = 1;

  131.         return datain;
  132. }


  133. void ld3320_reset()
  134. {
  135.         LD3320_RST=1;
  136.         delay_ms(1);
  137.         LD3320_RST=0;
  138.         delay_ms(1);
  139.         LD3320_RST=1;

  140.         delay_ms(1);
  141.         LD3320_CS=0;
  142.         delay_ms(1);
  143.         LD3320_CS=1;
  144.         delay_ms(1);
  145. }
  146. u8 ld3320_check()
  147. {
  148.         u8 a[3];
  149.         memset(a,0x00,sizeof(a));
  150.         ld3320_reset();
  151.         delay_ms(1);
  152.         ld3320_read_reg(0x06);  
  153.         delay_ms(1);
  154.         ld3320_write_reg(0x35, 0x33);  
  155.         delay_ms(1);
  156.         ld3320_write_reg(0x1b, 0x55);   
  157.         delay_ms(1);
  158.         ld3320_write_reg(0xb3, 0xaa);        
  159.         
  160.         a[0]=ld3320_read_reg(0x35);
  161.         delay_ms(5);
  162.                
  163.         a[1]=ld3320_read_reg(0x1b);
  164.         delay_ms(5);
  165.         a[2]=ld3320_read_reg(0xb3);

  166.         if(a[0]!=0x33||a[1]!=0x55||a[2]!=0xaa)
  167.                 return 1;
  168.         return 0;
  169.         
  170. }



  171. void ld3320_init_common()
  172. {
  173.         bMp3Play = 0;

  174.         ld3320_read_reg(0x06);  
  175.         ld3320_write_reg(0x17, 0x35);
  176.         delay_ms(10);
  177.         ld3320_read_reg(0x06);  

  178.         ld3320_write_reg(0x89, 0x03);  
  179.         delay_ms(5);
  180.         ld3320_write_reg(0xCF, 0x43);   
  181.         delay_ms(5);
  182.         ld3320_write_reg(0xCB, 0x02);
  183.         
  184.         /*PLL setting*/
  185.         ld3320_write_reg(0x11, LD_PLL_11);      
  186.         if (nLD_Mode == LD_MODE_MP3)
  187.         {
  188.                 ld3320_write_reg(0x1E, 0x00);
  189.                 ld3320_write_reg(0x19, LD_PLL_MP3_19);   
  190.                 ld3320_write_reg(0x1B, LD_PLL_MP3_1B);   
  191.                 ld3320_write_reg(0x1D, LD_PLL_MP3_1D);
  192.         }
  193.         else
  194.         {
  195.                 ld3320_write_reg(0x1E,0x00);
  196.                 ld3320_write_reg(0x19, LD_PLL_ASR_19);
  197.                 ld3320_write_reg(0x1B, LD_PLL_ASR_1B);               
  198.             ld3320_write_reg(0x1D, LD_PLL_ASR_1D);
  199.         }
  200.         delay_ms(10);
  201.         
  202.         ld3320_write_reg(0xCD, 0x04);
  203.         ld3320_write_reg(0x17, 0x4c);
  204.         delay_ms(5);
  205.         ld3320_write_reg(0xB9, 0x00);
  206.         ld3320_write_reg(0xCF, 0x4F);
  207.         ld3320_write_reg(0x6F, 0xFF);
  208. }

  209. void ld3320_init_mp3()
  210. {
  211.         nLD_Mode = LD_MODE_MP3;
  212.         ld3320_init_common();

  213.         ld3320_write_reg(0xBD,0x02);
  214.         ld3320_write_reg(0x17, 0x48);
  215.         delay_ms(10);

  216.         ld3320_write_reg(0x85, 0x52);
  217.         ld3320_write_reg(0x8F, 0x00);  
  218.         ld3320_write_reg(0x81, 0x00);
  219.         ld3320_write_reg(0x83, 0x00);
  220.         ld3320_write_reg(0x8E, 0xff);
  221.         ld3320_write_reg(0x8D, 0xff);
  222.     delay_ms(1);
  223.         ld3320_write_reg(0x87, 0xff);
  224.         ld3320_write_reg(0x89, 0xff);
  225.         delay_ms(1);
  226.         ld3320_write_reg(0x22, 0x00);   
  227.         ld3320_write_reg(0x23, 0x00);
  228.         ld3320_write_reg(0x20, 0xef);   
  229.         ld3320_write_reg(0x21, 0x07);
  230.         ld3320_write_reg(0x24, 0x77);         
  231.     ld3320_write_reg(0x25, 0x03);
  232.     ld3320_write_reg(0x26, 0xbb);   
  233.     ld3320_write_reg(0x27, 0x01);
  234. }



  235. void ld3320_init_asr()
  236. {
  237.         nLD_Mode=LD_MODE_ASR_RUN;
  238.         ld3320_init_common();

  239.         ld3320_write_reg(0xBD, 0x00);
  240.         ld3320_write_reg(0x17, 0x48);
  241.         delay_ms(10);

  242.         ld3320_write_reg(0x3C, 0x80);   
  243.         ld3320_write_reg(0x3E, 0x07);
  244.         ld3320_write_reg(0x38, 0xff);   
  245.         ld3320_write_reg(0x3A, 0x07);
  246.         
  247.         ld3320_write_reg(0x40, 0);         
  248.         ld3320_write_reg(0x42, 8);
  249.         ld3320_write_reg(0x44, 0);   
  250.         ld3320_write_reg(0x46, 8);
  251.         delay_ms(10);
  252. }

  253. void ld3320_reload_mp3data()
  254. {
  255.         unsigned long nCurMp3Pos;
  256.         u8 val;
  257.         u8 k;

  258.         nCurMp3Pos = nMp3StartPos + nMp3Pos;

  259.         ucStatus = ld3320_read_reg(0x06);
  260.         while ( !(ucStatus&MASK_FIFO_STATUS_AFULL) && (nMp3Pos<nMp3Size) )
  261.         {
  262.                 val=0;
  263.                 for(k=0;k<8;k++)
  264.                 {
  265.                 }
  266.                 ld3320_write_reg(0x01,val);

  267.                 nMp3Pos++;

  268.                 ucStatus = ld3320_read_reg(0x06);
  269.         }
  270. }


  271. void ld3320_reload_mp3data_2()
  272. {
  273.         unsigned long nCurMp3Pos;
  274.         u8 val;
  275.         u8 k;

  276.         nCurMp3Pos = nMp3StartPos + nMp3Pos;


  277.         //读取音乐文件写入
  278.         
  279.         

  280.         ucStatus = ld3320_read_reg(0x06);
  281.         while ( !(ucStatus&MASK_FIFO_STATUS_AFULL) && (nMp3Pos<nMp3Size) )
  282.         {
  283.                 val=0;


  284.                 nMp3Pos++;

  285.                 ucStatus = ld3320_read_reg(0x06);
  286.         }
  287. }




  288. void ld3320_process_init()
  289. {
  290.         u8 nAsrResCount=0;
  291.         
  292.         ucRegVal = ld3320_read_reg(0x2B);
  293.         if(nLD_Mode == LD_MODE_ASR_RUN)
  294.         {
  295.                 // 语音识别产生的中断
  296.                 // (有声音输入,不论识别成功或失败都有中断)
  297.                 ld3320_write_reg(0x29,0) ;
  298.                 ld3320_write_reg(0x02,0) ;
  299.                 if((ucRegVal & 0x10) &&
  300.                         ld3320_read_reg(0xb2)==0x21 &&
  301.                         ld3320_read_reg(0xbf)==0x35)
  302.                 {
  303.                         nAsrResCount = ld3320_read_reg(0xba);
  304.                         if(nAsrResCount>0 && nAsrResCount<=4)
  305.                         {
  306.                                 nAsrStatus=LD_ASR_FOUNDOK;
  307.                         }
  308.                         else
  309.                     {
  310.                                 nAsrStatus=LD_ASR_FOUNDZERO;
  311.                         }        
  312.                 }
  313.                 else
  314.                 {
  315.                         nAsrStatus=LD_ASR_FOUNDZERO;
  316.                 }
  317.                         
  318.                 ld3320_write_reg(0x2b, 0);
  319.             ld3320_write_reg(0x1C,0);
  320.                 return;
  321.         }
  322.         
  323.         // 声音播放产生的中断,有三种:
  324.         // A. 声音数据已全部播放完。
  325.         // B. 声音数据已发送完毕。
  326.         // C. 声音数据暂时将要用完,需要放入新的数据。        
  327.         ucHighInt = ld3320_read_reg(0x29);
  328.         ucLowInt=ld3320_read_reg(0x02);
  329.         ld3320_write_reg(0x29,0) ;
  330.         ld3320_write_reg(0x02,0) ;
  331.     if(ld3320_read_reg(0xBA)&CAUSE_MP3_SONG_END)
  332.     {
  333.         // A. 声音数据已全部播放完。

  334.                 ld3320_write_reg(0x2B,  0);
  335.               ld3320_write_reg(0xBA, 0);        
  336.                 ld3320_write_reg(0xBC,0x0);        
  337.                 bMp3Play=0;                                        // 声音数据全部播放完后,修改bMp3Play的变量
  338.                 ld3320_write_reg(0x08,1);
  339.                 delay_ms(5);
  340.               ld3320_write_reg(0x08,0);
  341.                 ld3320_write_reg(0x33, 0);

  342.                 return ;
  343.      }

  344.          if(nMp3Pos>=nMp3Size)
  345.         {
  346.         // B. 声音数据已发送完毕。

  347.                 ld3320_write_reg(0xBC, 0x01);
  348.                 ld3320_write_reg(0x29, 0x10);
  349. //                bMp3Play=0;                                //        此时,只是主控MCU把所有MP3数据发送到LD3320芯片内,但是还没有把送入的数据全部播放完毕
  350.                 return;        
  351.         }

  352.         // C. 声音数据暂时将要用完,需要放入新的数据。        

  353.         ld3320_reload_mp3data_2();
  354.                
  355.         ld3320_write_reg(0x29,ucHighInt);
  356.         ld3320_write_reg(0x02,ucLowInt) ;
  357. }
  358. void ld3320_play()
  359. {
  360.         nMp3Pos=0;
  361.         bMp3Play=1;

  362.         if (nMp3Pos >=  nMp3Size)
  363.                 return ;

  364.         ld3320_reload_mp3data();

  365.     ld3320_write_reg(0xBA, 0x00);
  366.         ld3320_write_reg(0x17, 0x48);
  367.         ld3320_write_reg(0x33, 0x01);
  368.         ld3320_write_reg(0x29, 0x04);
  369.         
  370.         ld3320_write_reg(0x02, 0x01);
  371.         ld3320_write_reg(0x85, 0x5A);
  372. }

  373. void ld3320_adjust_volume(u8 val)
  374. {
  375.         ucSPVol = val;
  376.         val = ((15-val)&0x0f) << 2;
  377.         ld3320_write_reg(0x8E, val | 0xc3);
  378.         ld3320_write_reg(0x87, 0x78);
  379. }
  380. // Return 1: success.
  381. u8 ld3320_check_asrbusyflag_b2()
  382. {
  383.         u8 j;
  384.         u8 flag = 0;
  385.         for (j=0; j<10; j++)
  386.         {
  387.                 if (ld3320_read_reg(0xb2) == 0x21)
  388.                 {
  389.                         flag = 1;
  390.                         break;
  391.                 }
  392.                 delay_ms(10);               
  393.         }
  394.         return flag;
  395. }

  396. void LD_AsrStart()
  397. {
  398.         ld3320_init_asr();
  399. }

  400. // Return 1: success.
  401. u8 ld3320_asrun()
  402. {
  403.         ld3320_write_reg(0x35, MIC_VOL);
  404.         ld3320_write_reg(0x1C, 0x09);
  405.         ld3320_write_reg(0xBD, 0x20);
  406.         ld3320_write_reg(0x08, 0x01);
  407.         delay_ms( 1 );
  408.         ld3320_write_reg(0x08, 0x00);
  409.         delay_ms( 1 );

  410.         if(ld3320_check_asrbusyflag_b2() == 0)
  411.         {
  412.                 return 0;
  413.         }

  414.         ld3320_write_reg(0xB2, 0xff);        
  415.         ld3320_write_reg(0x37, 0x06);
  416.         delay_ms( 10 );
  417.         ld3320_write_reg(0x1C, 0x0b);
  418.         ld3320_write_reg(0x29, 0x10);
  419.         
  420.         ld3320_write_reg(0xBD, 0x00);
  421.         return 1;
  422. }

  423. // Return 1: success.
  424. //        添加识别关键词语,开发者可以学习"语音识别芯片LD3320高阶秘籍.pdf"中关于垃圾词语吸收错误的用法
  425. u8 ld3320_asr_addFixed()
  426. {
  427.         u8 k, flag;
  428.         u8 nAsrAddLength;
  429.         const char sRecog[24][30] = {"xiao hui hui",
  430.                                                                 "ni you xi fu mei",
  431.                                                                 "jiang ge gu shi",
  432.                                                                 "ni shi bu shi dan teng",
  433.                                                                 "ni ban ben hao duo shao",
  434.                                                                 "jin tian duo shao hao",
  435.                                                                 "jin tian ji hao le",
  436.                                                                 "xian zai ji dian le",
  437.                                                                 "jin nian ji sui le",
  438.                                                                 "ni sheng wa le mei",
  439.                                                                 "da kai ji dian qi yi",
  440.                                                                 "da kai ji dian qi er",
  441.                                                                 "guan bi ji dian qi yi",
  442.                                                                 "guan bi ji dian qi er",
  443.                                                                 "da kai suo you ji dian qi",
  444.                                                                 "guan bi suo you ji dian qi",
  445.                                                                 "tiao gao yin liang",
  446.                                                                 "zeng jia tin liang",
  447.                                                                 "tiao xiao yin liang",
  448.                                                                 "jiang di yin lliang",
  449.                                                                 "tiao gao yu su",
  450.                                                                 "zeng jia yu su",
  451.                                                                 "tiao xiao yu su",
  452.                                                                 "jiang di yu su",
  453.                                                                 };
  454.         const Order pCode[24] = {
  455.                                                         name,
  456.                                                         wife,
  457.                                                         speakStore,
  458.                                                         eggPain,
  459.                                                         visionNum,
  460.                                                         todayDate,
  461.                                                         whyToday,
  462.                                                         whatTime,
  463.                                                         howOld,
  464.                                                         haveChild,
  465.                                                         openRelayOne,
  466.                                                         openRelayTwo,
  467.                                                         closeRelayOne,
  468.                                                         closeRelayTwo,
  469.                                                         openRelay,
  470.                                                         closeRelay,
  471.                                                         upVolume,
  472.                                                         upVolume,
  473.                                                         downVolume,
  474.                                                         downVolume,
  475.                                                         upSpeed,
  476.                                                         upSpeed,
  477.                                                         downSpeed,
  478.                                                         downSpeed,
  479.                                                         };
  480.                
  481.         flag = 1;
  482.         for (k=0; k<24; k++)
  483.         {
  484.                         
  485.                 if(ld3320_check_asrbusyflag_b2() == 0)
  486.                 {
  487.                         flag = 0;
  488.                         break;
  489.                 }
  490.                
  491.                 ld3320_write_reg(0xc1, pCode[k] );
  492.                 ld3320_write_reg(0xc3, 0 );
  493.                 ld3320_write_reg(0x08, 0x04);
  494.                 delay_ms(1);
  495.                 ld3320_write_reg(0x08, 0x00);
  496.                 delay_ms(1);

  497.                 for (nAsrAddLength=0; nAsrAddLength<30; nAsrAddLength++)
  498.                 {
  499.                         if (sRecog[k][nAsrAddLength] == 0)
  500.                                 break;
  501.                         ld3320_write_reg(0x5, sRecog[k][nAsrAddLength]);
  502.                 }
  503.                 ld3320_write_reg(0xb9, nAsrAddLength);
  504.                 ld3320_write_reg(0xb2, 0xff);
  505.                 ld3320_write_reg(0x37, 0x04);
  506.         }
  507.     return flag;
  508. }


  509. u8 ld3320_get_result()
  510. {
  511.         return ld3320_read_reg(0xc5 );
  512. }

  513. /************************************************************************************/
  514. //        RunASR()函数实现了一次完整的ASR语音识别流程
  515. //        LD_AsrStart() 函数实现了ASR初始化
  516. //        LD_AsrAddFixed() 函数实现了添加关键词语到LD3320芯片中
  517. //        LD_AsrRun()        函数启动了一次ASR语音识别流程
  518. //
  519. //        任何一次ASR识别流程,都需要按照这个顺序,从初始化开始进行
  520. /************************************************************************************/

  521. u8 ld3320_run_asr()
  522. {
  523.         u8 i=0;
  524.         u8 asrflag=0;
  525.         for (i=0; i<5; i++)                        //        防止由于硬件原因导致LD3320芯片工作不正常,所以一共尝试5次启动ASR识别流程
  526.         {
  527.                 LD_AsrStart();
  528.                 delay_ms(10);
  529.                 if (ld3320_asr_addFixed()==0)
  530.                 {
  531.                         ld3320_reset();                        //        LD3320芯片内部出现不正常,立即重启LD3320芯片
  532.                         delay_ms(100);                        //        并从初始化开始重新ASR识别流程
  533.                         continue;
  534.                 }
  535.                 delay_ms(300);
  536.                 if (ld3320_asrun() == 0)
  537.                 {
  538.                         ld3320_reset();                        //        LD3320芯片内部出现不正常,立即重启LD3320芯片
  539.                         delay_ms(100);                        //        并从初始化开始重新ASR识别流程
  540.                         continue;
  541.                 }

  542.                 asrflag=1;
  543.                 break;                                        //        ASR流程启动成功,退出当前for循环。开始等待LD3320送出的中断信号
  544.         }

  545.         return asrflag;
  546. }

复制代码

LD3320.h

  1. #ifndef __LD3320_H
  2. #define __LD3320_H
  3. #include "sys.h"

  4. typedef struct
  5. {
  6.     unsigned char  b0:1;
  7.     unsigned char  b1:1;
  8.     unsigned char  b2:1;
  9.     unsigned char  b3:1;
  10.     unsigned char  b4:1;
  11.     unsigned char  b5:1;
  12.     unsigned char  b6:1;
  13.     unsigned char  b7:1;
  14. } BIT8;

  15. extern u8 ld3320Data;
  16. #define     bita0               (((BIT8*) & ld3320Data) -> b0)
  17. #define     bita1               (((BIT8*) & ld3320Data) -> b1)
  18. #define     bita2               (((BIT8*) & ld3320Data) -> b2)
  19. #define     bita3               (((BIT8*) & ld3320Data) -> b3)
  20. #define     bita4               (((BIT8*) & ld3320Data) -> b4)
  21. #define     bita5               (((BIT8*) & ld3320Data) -> b5)
  22. #define     bita6               (((BIT8*) & ld3320Data) -> b6)
  23. #define     bita7               (((BIT8*) & ld3320Data) -> b7)




  24. #define LD3320_A0   PBout(15)
  25. #define LD3320_RD   PBout(14)
  26. #define LD3320_WR   PAout(12)
  27. #define LD3320_CS   PAout(11)
  28. #define LD3320_RST  PBout(10)
  29. #define LD3320_MD   PBout(13)
  30.                
  31. #define LD3320_D0 PBout(5)
  32. #define LD3320_D1 PBout(4)
  33. #define LD3320_D2 PBout(3)
  34. #define LD3320_D3 PAout(15)
  35. #define LD3320_D4 PBout(9)
  36. #define LD3320_D5 PBout(8)
  37. #define LD3320_D6 PBout(7)
  38. #define LD3320_D7 PBout(6)

  39. #define LD3320_D0_R PBin(5)
  40. #define LD3320_D1_R PBin(4)
  41. #define LD3320_D2_R PBin(3)
  42. #define LD3320_D3_R PAin(15)
  43. #define LD3320_D4_R PBin(9)
  44. #define LD3320_D5_R PBin(8)
  45. #define LD3320_D6_R PBin(7)
  46. #define LD3320_D7_R PBin(6)


  47. #define LD3320_DATA_IN()  {GPIOA->CRH&=0X0FFFFFFF;GPIOA->CRH|=(u32)8<<28;GPIOB->CRL&=0X00000FFF;GPIOB->CRL|=0X88888000;GPIOB->CRH&=0XFFFFFF00;GPIOB->CRH|=0X00000088;}
  48. #define LD3320_DATA_OUT() {GPIOA->CRH&=0X0FFFFFFF;GPIOA->CRH|=(u32)3<<28;GPIOB->CRL&=0X00000FFF;GPIOB->CRL|=0X33333000;GPIOB->CRH&=0XFFFFFF00;GPIOB->CRH|=0X00000033;}


  49. #define LD3320_DATA_WRITE(x) {ld3320Data = x;LD3320_D0=bita0;LD3320_D1=bita1;LD3320_D2=bita2;LD3320_D3=bita3;LD3320_D4=bita4;LD3320_D5=bita5;LD3320_D6=bita6;LD3320_D7=bita7;}
  50. #define LD3320_DATA_READ(x)  {bita0=LD3320_D0_R;bita1=LD3320_D1_R;bita2=LD3320_D2_R;bita3=LD3320_D3_R;bita4=LD3320_D4_R;bita5=LD3320_D5_R; bita6=LD3320_D6_R;bita7=LD3320_D7_R;x= ld3320Data;}

  51.         
  52.         
  53. //        以下三个状态定义用来记录程序是在运行ASR识别还是在运行MP3播放
  54. #define LD_MODE_IDLE                0x00
  55. #define LD_MODE_ASR_RUN                0x08
  56. #define LD_MODE_MP3                         0x40


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


  63. #define CLK_IN                       8        /* user need modify this value according to clock in */
  64. #define LD_PLL_11                        (u8)((CLK_IN/2.0)-1)
  65. #define LD_PLL_MP3_19                0x0f
  66. #define LD_PLL_MP3_1B                0x18
  67. #define LD_PLL_MP3_1D           (u8)(((90.0*((LD_PLL_11)+1))/(CLK_IN))-1)

  68. #define LD_PLL_ASR_19                 (u8)(CLK_IN*32.0/(LD_PLL_11+1) - 0.51)
  69. #define LD_PLL_ASR_1B                 0x48
  70. #define LD_PLL_ASR_1D                 0x1f

  71. // LD chip fixed values.
  72. #define        RESUM_OF_MUSIC               0x01
  73. #define        CAUSE_MP3_SONG_END           0x20

  74. #define        MASK_INT_SYNC                                0x10
  75. #define        MASK_INT_FIFO                                0x04
  76. #define               MASK_AFIFO_INT                                0x01
  77. #define        MASK_FIFO_STATUS_AFULL                0x08        
  78.         
  79.         
  80.         
  81. typedef enum
  82. {
  83.         name=1,  //小灰灰
  84.         wife=2,  //你有媳妇没
  85.         speakStore=3,//讲个故事
  86.         eggPain=4,  //你最近是不是蛋疼
  87.         visionNum=5, //你版本号是多少
  88.         todayDate=6,//今天多少号
  89.         whyToday=6, //今天几号了
  90.         whatTime=7,  //现在几点了
  91.         howOld=8,    //今年几岁了
  92.         haveChild=9, //你生娃了没
  93.         openRelayOne=10, //打开继电器一
  94.         openRelayTwo=11,  //打开继电器二
  95.         closeRelayOne=12, //关闭继电器一
  96.         closeRelayTwo=13, //关闭继电器二
  97.         openRelay=14,     //打开所有继电器
  98.         closeRelay=15,    //关闭所有继电器
  99.         upVolume=17,   //调高音量
  100.         downVolume=18, //降低音量
  101.         upSpeed=19,                //提高语速
  102.         downSpeed=20,      //降低语速
  103. }Order;
  104.         
  105.         
  106.         
  107.         
  108.         
  109. extern unsigned long nMp3StartPos;
  110. extern unsigned long nMp3Size;
  111. extern unsigned long nMp3Pos;
  112. extern u8 bMp3Play;                                                        //        用来记录播放MP3的状态
  113. extern u8 nLD_Mode;                //        用来记录当前是在进行ASR识别还是在播放MP3
  114. extern u8 ucRegVal;
  115. extern u8 ucHighInt;
  116. extern u8 ucLowInt;
  117. extern u8 ucStatus;
  118. extern u8 ucSPVol; // MAX=15 MIN=0                //        Speaker喇叭输出的音量
  119. #define MIC_VOL 0x55        
  120.         
  121.                
  122. u8 ld3320_check(void);        
  123. void ld3320_init(void);        
  124. void ld3320_process_init(void);        
  125. void ld3320_reset(void);
  126. void ld3320_init_common(void);
  127. void ld3320_init_mp3(void);
  128. void ld3320_init_asr(void);
  129. void ld3320_reload_mp3data(void);
  130. void ld3320_reload_mp3data_2(void);
  131. void ld3320_play(void);
  132. void ld3320_adjust_volume(u8 val);
  133. u8 ld3320_check_asrbusyflag_b2(void);
  134. void LD_AsrStart(void);
  135. u8 ld3320_asrun(void);
  136. u8 ld3320_asr_addFixed(void);
  137. u8 ld3320_get_result(void);
  138. u8 ld3320_run_asr(void);
  139.         
  140. #endif
复制代码

freq.c

  1. #include "freq.h"


  2. void ld3320_freq_init(void)
  3. {

  4.         GPIO_InitTypeDef  GPIO_InitStructure;

  5.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);         //使能PB,PE端口时钟


  6.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  7.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  8.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  9.         GPIO_Init(GPIOA, &GPIO_InitStructure);        
  10.         GPIO_SetBits(GPIOA,GPIO_Pin_8);
  11.         
  12.         RCC_MCOConfig(RCC_MCO_HSE); //RCC_MCO_NoClock --- 无时钟输出
  13.                                                                 //RCC_MCO_SYSCLK --- 输出系统时钟(SysCLK)
  14.                                                                 //RCC_MCO_HSI --- 输出内部高速8MHz的RC振荡器的时钟(HSI)
  15.                                                                 //RCC_MCO_HSE --- 输出高速外部时钟信号(HSE)
  16.                                                                 //RCC_MCO_PLLCLK_Div2 --- 输出PLL倍频后的二分频时钟(PLLCLK/2)               
  17. }
复制代码

freq.h

  1. #ifndef __FREQ_H
  2. #define __FREQ_H
  3. #include "sys.h"


  4. void ld3320_freq_init(void);        

  5.                                                      
  6. #endif
复制代码

main.c

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "ld3320.h"
  6. #include "freq.h"
  7. #include "malloc.h"        


  8. u8 nAsrStatus=0;        
  9. extern u8 bMp3Play;                                                        //        用来记录播放MP3的状态

  10. u8 voiceSpeed=5,voiceVolume=10;

  11. int main(void)
  12. {        
  13.         u8  nAsrRes;
  14.         u16 i;
  15.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
  16.         uart_init(115200);
  17.         
  18.         delay_init();        
  19.         ld3320_freq_init();
  20.         led_init();        
  21.         mem_init();                                //初始化内存池
  22.         ld3320_init();
  23.         delay_ms(1000);
  24.         ld3320_reset();
  25.         while(ld3320_check())
  26.         {
  27.                 printf("LD3320 Error!!\r\n");
  28.                 turn_r_led();
  29.                 delay_ms(500);
  30.         }        
  31.         nAsrStatus = LD_ASR_NONE;                //        初始状态:没有在作ASR
  32.                
  33.         while(1)
  34.         {        
  35.                 if (bMp3Play!=0)                        //        如果还在播放MP3中,则等待,直到MP3播放完毕 即bMp3Play==0
  36.                         continue;                                //        bMp3Play 是定义的一个全局变量用来记录MP3播放的状态,不是LD3320芯片内部的寄存器
  37.                 switch(nAsrStatus)
  38.                 {
  39.                         case LD_ASR_RUNING:        break;
  40.                         case LD_ASR_ERROR:        break;
  41.                                 
  42.                         case LD_ASR_NONE:
  43.                         {        
  44.                                 nAsrStatus=LD_ASR_RUNING;
  45.                                 if (ld3320_run_asr()==0)        
  46.                                 {
  47.                                         nAsrStatus = LD_ASR_ERROR;
  48.                                 }
  49.                                 
  50.                         }break;
  51.                         case LD_ASR_FOUNDOK:
  52.                         {
  53.                                 nAsrRes = ld3320_get_result();
  54.                                 printf("nAsrRes=%d\r\n",nAsrRes);                                
  55.                                 switch(nAsrRes)
  56.                                 {
  57.                                         case name:
  58.                                         {           
  59.                                                 printf("小灰灰\r\n");        
  60.                                         }break;
  61.                                         case wife:   
  62.                                         {
  63.                                                 printf("你有媳妇没\r\n");
  64.                                         }break;
  65.                                         case speakStore:
  66.                                         {                        
  67.                                                 printf("讲个故事\r\n");
  68.                                         }break;
  69.                                         case eggPain:   
  70.                                         {                                                
  71.                                                 printf("你最近是不是蛋疼\r\n");
  72.                                         }break;
  73.                                         case visionNum:   
  74.                                         {                                                
  75.                                                 printf("你版本号是多少\r\n");
  76.                                         }break;
  77.                                         case todayDate:
  78.                                         {                                       
  79.                                                 printf("今天多少号\r\n");
  80.                                         }break;
  81.                                         case whatTime:  
  82.                                         {                                                
  83.                                                 printf("现在几点了\r\n");                                       
  84.                                         }break;
  85.                                         case howOld:        
  86.                                         {                                                
  87.                                                 printf("今年几岁了\r\n");
  88.                                         }break;
  89.                                         case haveChild:  
  90.                                         {                                       
  91.                                                 printf("你生娃了没\r\n");
  92.                                         }break;
  93.                                         case openRelayOne:
  94.                                         {                                       
  95.                                                 printf("打开继电器一\r\n");
  96.                                         }break;
  97.                                         case openRelayTwo:
  98.                                         {                                                
  99.                                                 printf("打开继电器二\r\n");
  100.                                         }break;
  101.                                         case closeRelayOne:
  102.                                         {                                                
  103.                                                 printf("关闭继电器一\r\n");
  104.                                         }break;
  105.                                         case closeRelayTwo:
  106.                                         {                                                
  107.                                                 printf("关闭继电器二\r\n");
  108.                                         }break;
  109.                                         case openRelay:   
  110.                                         {                                       
  111.                                                 printf("打开所有继电器\r\n");
  112.                                         }break;
  113.                                         case closeRelay:  
  114.                                         {                                                
  115.                                                 printf("关闭所有继电器\r\n");
  116.                                         }break;        
  117.                                         case upVolume:   
  118.                                         {                                                
  119.                                                 printf("调高音量\r\n");
  120.                                         }break;        
  121.                                         case downVolume:
  122.                                         {   
  123.                                                 printf("降低音量\r\n");
  124.                                         }break;        
  125.                                         case upSpeed:
  126.                                         {                                       
  127.                                                 printf("提高语速\r\n");
  128.                                         }break;        
  129.                                         case downSpeed:  
  130.                                         {                                       
  131.                                                 printf("降低语速\r\n");
  132.                                                 
  133.                                         }break;                                       
  134.                                 }
  135.                                 nAsrStatus = LD_ASR_NONE;
  136.                                 
  137.                         }break;
  138.                         case LD_ASR_FOUNDZERO:
  139.                         default:
  140.                         {
  141.                                 nAsrStatus = LD_ASR_NONE;
  142.                                 
  143.                         }break;
  144.                 }
  145.                 delay_us(2);
  146.                 i++;
  147.                 if(i>=60000)
  148.                 {
  149.                         i=0;
  150.                         turn_g_led();
  151.                 }
  152.         }
  153. }


复制代码

收藏 评论0 发布时间:2022-4-24 16:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版