查看: 6284|回复: 8

[原创] 【LPC54114双核任务三】双核之初识音频--2#HWVAD触发之DMA传输#

[复制链接]
  • TA的每日心情

    2021-1-28 20:09
  • 签到天数: 317 天

    [LV.8]以坛为家I

    61

    主题

    1582

    帖子

    6

    金牌会员

    Rank: 6Rank: 6

    积分
    8030
    最后登录
    2022-5-12
    发表于 2017-7-4 21:12:06 | 显示全部楼层 |阅读模式
    本帖最后由 小马哥-1650185 于 2017-7-4 23:02 编辑

          通过上一贴【LPC54114双核任务三】双核之初识音频--1#DMIC&HWVAD之中断触发#,相信同学们基本上明白了DMIC&HWVAD 的工作机理,总结为两句话:
    1.hwvad:硬件触发hwvad 事件中断,能够过滤虚假中断。

    2.dmic: 将 数字麦克的PDM数据转换成PCM,送给cpu,或者dma,或者i2s总线。



    那么本帖就来综合下HWVAD和DMIC(DMA模式),大概思路是这样的:


    通过HWVAD 检测外部声音,震动等信号,触发HWVAD事件,定义一个标志位flg置位,并且LED5闪烁;然后在主循环中检测这个标志位flg,若flg置位,开始接受dma数据, DMA的接收完成标志置位后打印接受的数据信息。然后等待下一次hwvad触发。。。

    还是先来看下效果吧:
    红框中的信息是初始化信息,下面的是外部条件触发hwvad事件后,dma接收dmic 传回的数据信息。

    11.png


    --------------------------------------------------------------------------

    下面是代码解析时间。。。

    本帖子的测试实在sdk demo中的dmic_dma的基础上修改完成的。



    相信研究过的同学们都知道万利的板子核官方sdk的资源分配是有却别的,特别是外设GPIO的复用功能。所以我们首先要配置 需要用到的外设。


    PIO1_15PDM0_CLK
    PIO1_16                                          PDM0_DATA


    1. const uint32_t port1_pin15_config = (
    2.     IOCON_PIO_FUNC1 |                                        /* Pin is configured as PDM0_CLK */
    3.     IOCON_PIO_MODE_PULLUP |                                  /* Selects pull-up function */
    4.     IOCON_PIO_INV_DI |                                       /* Input function is not inverted */
    5.     IOCON_PIO_DIGITAL_EN |                                   /* Enables digital function */
    6.     IOCON_PIO_INPFILT_OFF |                                  /* Input filter disabled */
    7.     IOCON_PIO_OPENDRAIN_DI                                   /* Open drain is disabled */
    8.   );
    9.   IOCON_PinMuxSet(IOCON, PORT1_IDX, 15, port1_pin15_config); /* PORT0 PIN31 (coords: 13) is configured as PDM0_CLK */
    10.   const uint32_t port1_pin16_config = (
    11.     IOCON_PIO_FUNC1 |                                        /* Pin is configured as PDM0_DATA */
    12.     IOCON_PIO_MODE_PULLUP |                                  /* Selects pull-up function */
    13.     IOCON_PIO_INV_DI |                                       /* Input function is not inverted */
    14.     IOCON_PIO_DIGITAL_EN |                                   /* Enables digital function */
    15.     IOCON_PIO_INPFILT_OFF |                                  /* Input filter disabled */
    16.     IOCON_PIO_OPENDRAIN_DI                                   /* Open drain is disabled */
    17.   );
    18.   IOCON_PinMuxSet(IOCON, PORT1_IDX, 16, port1_pin16_config); /* PORT1 PIN0 (coords: 14) is configured as PDM0_DATA */
    19.         
    复制代码


    然后为了测试实验效果,在配置一个LED的gpio,下马哥配置的是led5,随便配的,这里就不说了。


    下面就是代码流程了了,demo都有据地的配置,就不贴出来了。(不懂的上个帖子有详细解释,去看看。。。)
    1.配置DMIC
    2.配置DMIC的DMA0模式
    3.配置HWVAD(dmic_dma工程中小马哥新增的)
    4.DMA0回调函数
    5.HWVAD回调函数
    6.主循环等待hwvad事件触发


    这里重点看下MDA相关的配置,先看下配置内容。。。

    1. <blockquote><blockquote>/** Peripheral DMA0 base address */
    复制代码

    重点看下这个函数

    1. <div>/*!</div><div> * @brief Receives data using DMA.</div><div> *</div><div> * This function receives data using DMA. This is a non-blocking function, which returns</div><div> * right away. When all data is received, the receive callback function is called.</div><div> *</div><div> * @param base USART peripheral base address.</div><div> * @param handle Pointer to usart_dma_handle_t structure.</div><div> * @param xfer DMIC DMA transfer structure. See #dmic_transfer_t.</div><div> * @param dmic_channel DMIC channel </div><div> * @retval kStatus_Success</div><div> */</div><div>status_t DMIC_TransferReceiveDMA(DMIC_Type *base,</div><div>                                 dmic_dma_handle_t *handle,</div><div>                                 dmic_transfer_t *xfer,</div><div>                                 uint32_t dmic_channel);</div>
    复制代码

    通过这个函数来接收dma数据 传递给 结构体dmic_transfer_t receiveXfer,通过指针又传递给g_rxBuffer[BUFFER_LENGTH]这个数组,然后我们就饿可以打印看到这个数组的数据了,不同的声音大小打印出来的数据是不一样的哦。。。。。




    HWVAD 回调函数,主要完成dma传输完成标志位
    1. void DMIC_UserCallback(DMIC_Type *base, dmic_dma_handle_t *handle, status_t status, void *userData)
    2. {
    3.     userData = userData;
    4.     if (status == kStatus_DMIC_Idle)
    5.     {
    6.         g_Transfer_Done = true;

    7.     }
    8. }
    复制代码


    HWVAD回调函数
    led5闪烁,标志位dmic_hwvad_ok 置位

    1. void DMIC0_HWVAD_Callback(void)
    2. {
    3.     volatile int i;

    4.     GPIO_TogglePinsOutput(GPIO, 0, 1 << 29);
    5.     /* reset hwvad internal interrupt */
    6.     DMIC_CtrlClrIntrHwvad(DMIC0, true);
    7.     /* wait for HWVAD to settle */
    8.   
    9.     for (i = 0; i <= 500U; i++)
    10.     {
    11.     }
    12.     /*HWVAD Normal operation */
    13.     DMIC_CtrlClrIntrHwvad(DMIC0, false);
    14. dmic_hwvad_ok = true;

    15.     GPIO_TogglePinsOutput(GPIO, 0, 1 << 29);
    16.                
    17.                
    18. }
    复制代码


    在主函数中,检测标志位。

    1. if(dmic_hwvad_ok == true)
    2.                         {
    3.                                 dmic_hwvad_ok= false;
    4.                                 DMIC_TransferReceiveDMA(DMIC0, &g_dmicDmaHandle, &receiveXfer, APP_DMIC_CHANNEL);
    5.                                 
    6.                                 if(g_Transfer_Done == true)
    7.                                 {
    8.                                         g_Transfer_Done = false;
    9.                                         PRINTF("Transfer completed\r\n");
    10.                                         PRINTF("打印DMIC通过DMA传给CPU的数据 \r\n");
    11.                                                 for (i = 0; i < BUFFER_LENGTH; i++)
    12.                                                 {
    13.                                                         PRINTF("%5d , ", g_rxBuffer[i]);
    14.                                                         if(((i!=0)&&((i+1)%8 == 0)) ||(i ==BUFFER_LENGTH-1 )) PRINTF("\r\n");
    15.                                                 }
    16.                                                 PRINTF("\r\n--------------------小马哥出品----------------------\r\n");
    17.                                 }
    18.                         }
    复制代码

    接收完成后打印数据,为了明显比较,通过对比初始化时打印的g_rxBuffer数据(都是0),发现,每次触发hwvad,g_rxBuffer的数据都是变化的。。。



    音量大小对数据的影响
    55.png

    突发奇想,又测试了下微弱声音和强烈轻音,对DMA数据的影响,看数据可以发现:
    声音比较小的时候,数据也是很小的(看红框以外的数据)
    声音比较大的时候,数据很大的哦,(看红框内的数据,都在60000以上。。。)







    到此,本帖的研究测试已经结束了。。。。













    好好
    回复

    使用道具 举报

  • TA的每日心情

    2021-1-28 20:09
  • 签到天数: 317 天

    [LV.8]以坛为家I

    61

    主题

    1582

    帖子

    6

    金牌会员

    Rank: 6Rank: 6

    积分
    8030
    最后登录
    2022-5-12
     楼主| 发表于 2017-7-4 21:58:47 | 显示全部楼层
    持续更新中
    好好
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2018-7-12 20:45
  • 签到天数: 75 天

    [LV.6]常住居民II

    7

    主题

    213

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    441
    最后登录
    2018-10-25
    发表于 2017-7-4 23:20:11 | 显示全部楼层
    学习了   
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2017-11-20 11:31
  • 签到天数: 123 天

    [LV.7]常住居民III

    1

    主题

    313

    帖子

    0

    高级会员

    Rank: 4

    积分
    893
    最后登录
    2018-7-13
    发表于 2017-7-5 08:05:24 | 显示全部楼层
    DMA可以设置为循环模式吗?
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2018-7-3 23:04
  • 签到天数: 50 天

    [LV.5]常住居民I

    0

    主题

    87

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    284
    最后登录
    2018-7-3
    发表于 2017-7-5 11:04:06 | 显示全部楼层
    数据时麦克产生的pdm数据,经dmic转换的pcm数据么
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2018-7-21 17:51
  • 签到天数: 65 天

    [LV.6]常住居民II

    0

    主题

    123

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    448
    最后登录
    2018-8-5
    发表于 2017-7-6 09:09:14 | 显示全部楼层
    fscl_MQX 发表于 2017-7-5 11:04
    数据时麦克产生的pdm数据,经dmic转换的pcm数据么

    应该是这么个理儿
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2018-2-7 18:18
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    13

    主题

    126

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    1628
    最后登录
    2021-7-13
    发表于 2017-7-30 08:31:43 | 显示全部楼层
    g_rxBuffer[i]是16位的整数数组,而DMIC的FIFO是32位的?这是为什么?数据不会丢失???
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2020-6-16 09:38
  • 签到天数: 589 天

    [LV.9]以坛为家II

    3

    主题

    1039

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    2387
    最后登录
    2020-6-16
    发表于 2018-4-13 20:46:26 | 显示全部楼层
    要是有项目源代码就好了
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    1

    主题

    18

    帖子

    0

    注册会员

    Rank: 2

    积分
    99
    最后登录
    2018-7-9
    发表于 2018-5-29 14:33:31 | 显示全部楼层
    pythonworld 发表于 2017-7-30 08:31
    g_rxBuffer是16位的整数数组,而DMIC的FIFO是32位的?这是为什么?数据不会丢失??? ...

    16位的整数是有正负的,我也是昨天才被人指点到。此外可以看LPC54114的数据手册,上面有PDM转换为PCM的过程解释。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-28 02:00 , Processed in 0.147137 second(s), 28 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表