在线时间543 小时
UID1650185
注册时间2017-4-19
NXP金币470
TA的每日心情 | 怒 2021-1-28 20:09 |
---|
签到天数: 317 天 [LV.8]以坛为家I
金牌会员
- 积分
- 8030
- 最后登录
- 2022-5-12
|
本帖最后由 小马哥-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 传回的数据信息。
--------------------------------------------------------------------------
下面是代码解析时间。。。
本帖子的测试实在sdk demo中的dmic_dma的基础上修改完成的。
相信研究过的同学们都知道万利的板子核官方sdk的资源分配是有却别的,特别是外设GPIO的复用功能。所以我们首先要配置 需要用到的外设。
- const uint32_t port1_pin15_config = (
- IOCON_PIO_FUNC1 | /* Pin is configured as PDM0_CLK */
- IOCON_PIO_MODE_PULLUP | /* Selects pull-up function */
- IOCON_PIO_INV_DI | /* Input function is not inverted */
- IOCON_PIO_DIGITAL_EN | /* Enables digital function */
- IOCON_PIO_INPFILT_OFF | /* Input filter disabled */
- IOCON_PIO_OPENDRAIN_DI /* Open drain is disabled */
- );
- IOCON_PinMuxSet(IOCON, PORT1_IDX, 15, port1_pin15_config); /* PORT0 PIN31 (coords: 13) is configured as PDM0_CLK */
- const uint32_t port1_pin16_config = (
- IOCON_PIO_FUNC1 | /* Pin is configured as PDM0_DATA */
- IOCON_PIO_MODE_PULLUP | /* Selects pull-up function */
- IOCON_PIO_INV_DI | /* Input function is not inverted */
- IOCON_PIO_DIGITAL_EN | /* Enables digital function */
- IOCON_PIO_INPFILT_OFF | /* Input filter disabled */
- IOCON_PIO_OPENDRAIN_DI /* Open drain is disabled */
- );
- IOCON_PinMuxSet(IOCON, PORT1_IDX, 16, port1_pin16_config); /* PORT1 PIN0 (coords: 14) is configured as PDM0_DATA */
-
复制代码
然后为了测试实验效果,在配置一个LED的gpio,下马哥配置的是led5,随便配的,这里就不说了。
下面就是代码流程了了,demo都有据地的配置,就不贴出来了。(不懂的上个帖子有详细解释,去看看。。。)
1.配置DMIC
2.配置DMIC的DMA0模式
3.配置HWVAD(dmic_dma工程中小马哥新增的)
4.DMA0回调函数
5.HWVAD回调函数
6.主循环等待hwvad事件触发
这里重点看下MDA相关的配置,先看下配置内容。。。
- <blockquote><blockquote>/** Peripheral DMA0 base address */
复制代码
重点看下这个函数
- <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传输完成标志位
- void DMIC_UserCallback(DMIC_Type *base, dmic_dma_handle_t *handle, status_t status, void *userData)
- {
- userData = userData;
- if (status == kStatus_DMIC_Idle)
- {
- g_Transfer_Done = true;
- }
- }
复制代码
HWVAD回调函数
led5闪烁,标志位dmic_hwvad_ok 置位
- void DMIC0_HWVAD_Callback(void)
- {
- volatile int i;
- GPIO_TogglePinsOutput(GPIO, 0, 1 << 29);
- /* reset hwvad internal interrupt */
- DMIC_CtrlClrIntrHwvad(DMIC0, true);
- /* wait for HWVAD to settle */
-
- for (i = 0; i <= 500U; i++)
- {
- }
- /*HWVAD Normal operation */
- DMIC_CtrlClrIntrHwvad(DMIC0, false);
- dmic_hwvad_ok = true;
- GPIO_TogglePinsOutput(GPIO, 0, 1 << 29);
-
-
- }
复制代码
在主函数中,检测标志位。
- if(dmic_hwvad_ok == true)
- {
- dmic_hwvad_ok= false;
- DMIC_TransferReceiveDMA(DMIC0, &g_dmicDmaHandle, &receiveXfer, APP_DMIC_CHANNEL);
-
- if(g_Transfer_Done == true)
- {
- g_Transfer_Done = false;
- PRINTF("Transfer completed\r\n");
- PRINTF("打印DMIC通过DMA传给CPU的数据 \r\n");
- for (i = 0; i < BUFFER_LENGTH; i++)
- {
- PRINTF("%5d , ", g_rxBuffer[i]);
- if(((i!=0)&&((i+1)%8 == 0)) ||(i ==BUFFER_LENGTH-1 )) PRINTF("\r\n");
- }
- PRINTF("\r\n--------------------小马哥出品----------------------\r\n");
- }
- }
复制代码
接收完成后打印数据,为了明显比较,通过对比初始化时打印的g_rxBuffer数据(都是0),发现,每次触发hwvad,g_rxBuffer的数据都是变化的。。。
音量大小对数据的影响
突发奇想,又测试了下微弱声音和强烈轻音,对DMA数据的影响,看数据可以发现:
声音比较小的时候,数据也是很小的(看红框以外的数据)
声音比较大的时候,数据很大的哦,(看红框内的数据,都在60000以上。。。)
到此,本帖的研究测试已经结束了。。。。
|
|