硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4595|回复: 6
收起左侧

[有问必答] I2S DMA 读取音频数据失败

[复制链接]

4

主题

17

回帖

4

积分

新手上路

积分
4
发表于 2017-7-4 09:38:07 | 显示全部楼层 |阅读模式
最近我在用 STM32F207VET6 (100pin开发一个项目,主要是用到I2S 接口读取音频数据,但是STM32 I2S DMA始终无法进入接收中断,希望大神能帮忙看下,指导指导。
其中,STM32F207是从机,音频芯片是主机,音频芯片这边有信号输出,其中CLK为1.576MHz,采用频率为48KHz,16位数据长度,I2S标准模式,I2S_OUT有数据输出,示波器上能抓取。
硬件接口如下:
GPIO.jpg

file:///C:/Users/zhajin/AppData/Roaming/Foxmail7/Temp-8520-20170626085730/Attach/Catch(07-04-09-29-44).jpg
代码如下:
  1. #include "AUDIO.h"
  2. #define AUDIO_DAP_REG_OFFSET 0x0100
  3. #define AUDIO_MAX_REG_OFFSET 0x013A
  4. #define CODEC_I2S                      SPI3
  5. #define CODEC_I2S_GPIO_CLOCK           (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC)
  6. #define CODEC_I2S_CLK                  RCC_APB1Periph_SPI3
  7. #define CODEC_I2S_GPIO_AF              GPIO_AF_SPI3
  8. #define CODEC_I2S_WS_PIN               GPIO_Pin_4
  9. #define CODEC_I2S_SCK_PIN              GPIO_Pin_10
  10. #define CODEC_I2S_SD_PIN               GPIO_Pin_12
  11. #define CODEC_I2S_WS_PINSRC            GPIO_PinSource4
  12. #define CODEC_I2S_SCK_PINSRC           GPIO_PinSource10
  13. #define CODEC_I2S_SD_PINSRC            GPIO_PinSource12
  14. #define CODEC_I2S_WS_GPIO              GPIOA
  15. #define CODEC_I2S_GPIO                 GPIOC
  16. #define AUDIO_MAL_DMA_STREAM           DMA1_Stream2
  17. #define AUDIO_MAL_DMA_CHANNEL          DMA_Channel_0
  18. #define I2S_DMA_ENABLE 1//使能DMA接收
  19. /**
  20.   * @brief Initializes IOs used by the Audio Codec (on the control and audio
  21.   *        interfaces).
  22.   * @param  None
  23.   * @retval None
  24.   */
  25. static void AUDIO_GPIO_I2S_Init(void)
  26. {
  27.     GPIO_InitTypeDef GPIO_InitStructure;
  28.     RCC_I2SCLKConfig(RCC_I2S2CLKSource_Ext);
  29.     /* Enable I2S and I2C GPIO clocks */
  30.     RCC_AHB1PeriphClockCmd(CODEC_I2S_GPIO_CLOCK, ENABLE);
  31.     /* CODEC_I2S pins configuration: WS, SCK and SD pins -----------------------------*/
  32.     GPIO_InitStructure.GPIO_Pin = CODEC_I2S_WS_PIN;
  33.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//GPIO_Mode_IN;
  34.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  35.     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  36.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  37.     GPIO_Init(CODEC_I2S_WS_GPIO, &GPIO_InitStructure);
  38.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  39.     GPIO_InitStructure.GPIO_Pin = CODEC_I2S_SD_PIN;
  40.     GPIO_Init(CODEC_I2S_GPIO, &GPIO_InitStructure);
  41.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//GPIO_PuPd_NOPULL;//;
  42.     GPIO_InitStructure.GPIO_Pin = CODEC_I2S_SCK_PIN;
  43.     GPIO_Init(CODEC_I2S_GPIO, &GPIO_InitStructure);
  44.     /* Connect pins to I2S peripheral  */
  45.     GPIO_PinAFConfig(CODEC_I2S_WS_GPIO, CODEC_I2S_WS_PINSRC, CODEC_I2S_GPIO_AF);
  46.     GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_SCK_PINSRC, CODEC_I2S_GPIO_AF);
  47.     GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_SD_PINSRC, CODEC_I2S_GPIO_AF);
  48. }
  49. static void AUDIO_I2S_PRI_Init(uint32_t AudioFreq)
  50. {
  51.     I2S_InitTypeDef I2S_InitStructure;
  52.     /* Enable the CODEC_I2S peripheral clock */
  53.     RCC_APB1PeriphClockCmd(CODEC_I2S_CLK, ENABLE);
  54.     /* CODEC_I2S peripheral configuration */
  55.     SPI_I2S_DeInit(CODEC_I2S);
  56.     I2S_InitStructure.I2S_AudioFreq = AudioFreq;
  57.     I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;//I2S_Standard_Phillips;;
  58.     I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;//I2S_DataFormat_24b;
  59.     I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
  60.     I2S_InitStructure.I2S_Mode = I2S_Mode_SlaveRx;//I2S_Mode_MasterRx;
  61.     I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable; /* 外部晶振直接提供 */
  62.     I2S_Init(CODEC_I2S, &I2S_InitStructure);
  63. #if I2S_DMA_ENABLE
  64. #else
  65.     SPI_I2S_ITConfig(CODEC_I2S, SPI_I2S_IT_RXNE, ENABLE);
  66. #endif
  67.     I2S_Cmd(CODEC_I2S, ENABLE);
  68. }
  69. uint8_t dmaRxBuf[1024];
  70. static void AUDIO_I2S_DMA_Init(void)
  71. {
  72.     NVIC_InitTypeDef   NVIC_InitStructure;
  73. #if I2S_DMA_ENABLE
  74.     DMA_InitTypeDef  DMA_InitStructure;
  75.     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);                         //DMA1时钟使能
  76.     //DMA_Cmd(AUDIO_MAL_DMA_STREAM, DISABLE);
  77.     //DMA_DeInit(AUDIO_MAL_DMA_STREAM);
  78.     DMA_DeInit(AUDIO_MAL_DMA_STREAM);
  79.     while (DMA_GetCmdStatus(AUDIO_MAL_DMA_STREAM) != DISABLE){}//等待DMA1_Stream3可配置
  80.     DMA_ClearITPendingBit(AUDIO_MAL_DMA_STREAM, DMA_IT_FEIF2|DMA_IT_DMEIF2|DMA_IT_TEIF2|DMA_IT_HTIF2|DMA_IT_TCIF2);//清空DMA1_Stream3上所有中断标志
  81.     /* 配置 DMA Stream */
  82.     DMA_InitStructure.DMA_Channel = AUDIO_MAL_DMA_CHANNEL;                              //通道0 SPI2_TX通道
  83.     DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&CODEC_I2S->DR;             //外设地址为:(u32)&SPI2->DR
  84.     DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dmaRxBuf;                 //DMA 存储器0地址
  85.     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;                     //外设到存储器模式
  86.     DMA_InitStructure.DMA_BufferSize = (uint32_t)0xFFFE;                        //数据传输量
  87.     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;            //外设非增量模式
  88.     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                     //存储器增量模式
  89.     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据长度:16位
  90.     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;         //存储器数据长度:16位
  91.     DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//DMA_Mode_Circular;                               // 使用循环模式
  92.     DMA_InitStructure.DMA_Priority = DMA_Priority_High;                         //高优先级
  93.     DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;                      //不使用FIFO模式
  94.     DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
  95.     DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                 //外设突发单次传输
  96.     DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;         //存储器突发单次传输
  97.     DMA_Init(AUDIO_MAL_DMA_STREAM, &DMA_InitStructure);                         //初始化DMA Stream
  98.     //DMA_DoubleBufferModeConfig(AUDIO_MAL_DMA_STREAM,(u32)buf1, DMA_Memory_0); //双缓冲模式配置
  99.     //DMA_DoubleBufferModeCmd(AUDIO_MAL_DMA_STREAM,ENABLE);                     //双缓冲模式开启
  100.     DMA_ITConfig(AUDIO_MAL_DMA_STREAM, DMA_IT_TC, ENABLE);  //SPI_I2S_IT_RXNE   //开启传输完成中断
  101.     SPI_I2S_DMACmd(CODEC_I2S, SPI_I2S_DMAReq_Rx, ENABLE);
  102. #endif
  103.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  104. #if I2S_DMA_ENABLE
  105.     NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream2_IRQn;
  106. #else
  107.     NVIC_InitStructure.NVIC_IRQChannel = SPI3_IRQn;
  108. #endif
  109.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;                //抢占优先级0
  110.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;                       //子优先级0
  111.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                             //使能外部中断通道
  112.     NVIC_Init(&NVIC_InitStructure);                                             //配置
  113. }
  114. #if I2S_DMA_ENABLE
  115. void DMA1_Stream2_IRQHandler(void)
  116. {
  117.     if(DMA_GetITStatus(AUDIO_MAL_DMA_STREAM, DMA_IT_TCIF2) == SET)              //DMA1_Stream2,传输完成标志
  118.     {
  119.         DMA_ClearITPendingBit(AUDIO_MAL_DMA_STREAM, DMA_IT_TCIF2);
  120.     }
  121. }
  122. #else
  123. void SPI3_IRQHandler(void)
  124. {
  125.     if(SPI_GetITStatus(CODEC_I2S, SPI_I2S_IT_RXNE) == SET)              //DMA1_Stream2,传输完成标志
  126.     {
  127.         SPI_ClearITPendingBit(CODEC_I2S, SPI_I2S_IT_RXNE);
  128.     }
  129. }
  130. #endif
  131. s32 AUDIO_Interface_Init(void)
  132. {
  133.     AUDIO_GPIO_I2C_Init();
  134.     AUDIO_GPIO_I2S_Init();
  135.     AUDIO_I2S_PRI_Init(I2S_AudioFreq_48k);
  136.     AUDIO_I2S_DMA_Init();
  137.     return 0;
  138. }
  139. s32 AUDIO_Init(void)
  140. {
  141.     AUDIO_Interface_Init();
  142.     return 0;
  143. }
复制代码
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2017-7-4 09:42:12 | 显示全部楼层
F207做从机?  没弄过,我们F429的SAI音频接口 外接WM8978,我有弄过,SAI配合DMA双缓冲,音乐播放器的例子:https://forum.anfulai.cn/forum.p ... 687&fpage=3
回复

使用道具 举报

4

主题

17

回帖

4

积分

新手上路

积分
4
 楼主| 发表于 2017-7-4 11:43:33 | 显示全部楼层

回 eric2013 的帖子

eric2013:F207做从机?  没弄过,我们F429的SAI音频接口 外接WM8978,我有弄过,SAI配合DMA双缓冲,音乐播放器的例子:https://forum.anfulai.cn/forum.p ... 687&fpage=3 (2017-07-04 09:42) 
嗯嗯 这个例子我看过的 我的方式正好与这个相反 我是采集音频数据 你这边是播放音频数据
回复

使用道具 举报

4

主题

17

回帖

4

积分

新手上路

积分
4
 楼主| 发表于 2017-7-4 11:43:56 | 显示全部楼层

回 eric2013 的帖子

eric2013:
F207做从机?  没弄过,我们F429的SAI音频接口 外接WM8978,我有弄过,SAI配合DMA双缓冲,音乐播放器的例子:https://forum.anfulai.cn/forum.p ... 687&fpage=3
嗯嗯 这个例子我看过的 我的方式正好与这个相反 我是采集音频数据 你这边是播放音频数据
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2017-7-4 11:46:28 | 显示全部楼层

回 ygcldrz 的帖子

ygcldrz:嗯嗯 这个例子我看过的 我的方式正好与这个相反 我是采集音频数据 你这边是播放音频数据 (2017-07-04 11:43) 
参考录音机的例子。
回复

使用道具 举报

4

主题

17

回帖

4

积分

新手上路

积分
4
 楼主| 发表于 2017-7-4 12:06:44 | 显示全部楼层

回 eric2013 的帖子

eric2013:参考录音机的例子。 (2017-07-04 11:46) 
   好的 我看下 非常感谢
回复

使用道具 举报

4

主题

17

回帖

4

积分

新手上路

积分
4
 楼主| 发表于 2017-7-4 13:36:00 | 显示全部楼层

回 eric2013 的帖子

eric2013:参考录音机的例子。 (2017-07-04 11:46) 
   好的 我看下 非常感谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-17 06:49 , Processed in 0.041820 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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