硬汉嵌入式论坛

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

请教下,关于sai采样率设置 ??

[复制链接]

610

主题

3063

回帖

4913

积分

至尊会员

积分
4913
发表于 2018-1-2 23:02:27 | 显示全部楼层 |阅读模式
本帖最后由 hpdell 于 2018-1-3 09:36 编辑

现在想把 sai 的采样时钟改成 i2s 的,出现了采样率快慢的情况,如果全部都使用 sai 的时钟源,貌似比较正常,
但是使用 i2s 的时钟源,出现了不同的采样率的快慢不一致的情况,出现这样的情况,除了目前程序设置的外,还需要设置哪些 ???????


typedef struct
{
        uint32_t Fs;
        uint16_t PLLI2S_N;    /* 范围可以取192--432 */
        uint16_t PLLI2S_Q;    /* 范围可以取2--15    */
        uint8_t  PLLI2S_DivQ; /* 范围可以取1--32    */
        uint8_t  MCKDIV;      /* 范围可以取0--15    */
}PLLI2SPSC_T;

const PLLI2SPSC_T g_tPLLI2SPSC[]=
{
        //参数范围192-432   2-15       1-32           
  /* Fs  PLLI2S_N,  PLLI2S_Q  PLLI2S_DivQ  MCKDIV */
        {8000 ,  256,       5,         25,          0},  /* MCLK = 2.048MHz,   实际采样率 = 8000KHz    */
        {16000,  213,       2,         26,          0},         /* MCLK = 4.096153MHz,实际采样率 = 16000.6KHz */
        {32000,  213,       2,         13,          0},         /* MCLK = 8.192307MHz,实际采样率 = 32001KHz   */
        {48000,  258,       3,         7,           0},         /* MCLK = 12.28571MHz, 实际采样率 = 47991KHz   */
        {96000,  344,       2,         7,           0},  /* MCLK = 24.57142MHz, 实际采样率 = 95982KHz   */
        {192000, 393,       2,         4,           0},  /* MCLK = 49.125MHz,   实际采样率 = 191894KHz  */
        
        {11020,  429,       2,         19,          2},  /* MCLK = 2.822368MHz, 实际采样率 = 11.024KHz */
        {22050,  429,       2,         19,          1},  /* MCLK = 5.644737MHz, 实际采样率 = 22.049KHz */
        {44100,  429,       2,         19,          0},  /* MCLK = 11.28947MHz, 实际采样率 = 44.099KHz */
};



u8 SAIA_SampleRate_Set(u32 AudioFreq)
{   
  u8 i=0;
  RCC_PeriphCLKInitTypeDef RCCSAI1_Sture;  

  uint8_t freqindex = 0xFF;

        /* 这里采用列表的形式配置PLLI2S的时钟供SAI时钟使用 */
        for(i = 0; i < (sizeof(g_tPLLI2SPSC)/sizeof(g_tPLLI2SPSC[0])); i++)
        {
                if(AudioFreq == g_tPLLI2SPSC.Fs)
                {
      freqindex = i;
                        break;
                }      
        }  

  HAL_RCCEx_GetPeriphCLKConfig(&RCCSAI1_Sture);

  if(freqindex != 0xff)
  {
    #if  0   // 使用sai   如果使用这个 SAI 作为时钟,貌似基本没有什么问题
        /* Configure PLLSAI prescalers */

        RCCSAI1_Sture.PeriphClockSelection = RCC_PERIPHCLK_SAI1;          //外设时钟源选择
        RCCSAI1_Sture.Sai1ClockSelection   = RCC_SAI1CLKSOURCE_PLLSAI;    // 选择 sai 作为 sai的时钟源
        RCCSAI1_Sture.PLLSAI.PLLSAIP       = RCC_PLLP_DIV2;
        RCCSAI1_Sture.PLLSAI.PLLSAIN       = (u32)g_tPLLI2SPSC.PLLI2S_N;
        RCCSAI1_Sture.PLLSAI.PLLSAIQ       = (u32)g_tPLLI2SPSC.PLLI2S_Q;  
        RCCSAI1_Sture.PLLSAIDivQ           = g_tPLLI2SPSC.PLLI2S_DivQ;  

    #else   // 使用 i2s 作为时钟源 ,使用不同的采样率时,出现了播放速度快慢的情况,具体如下: ??????

        if( (AudioFreq == AUDIO_FREQUENCY_44K)
            || (AudioFreq == AUDIO_FREQUENCY_11K)
            )
        {
          /* Configure PLLSAI prescalers */

          RCCSAI1_Sture.PeriphClockSelection = RCC_PERIPHCLK_SAI1;  // 采样率为44K时,需要选择这个时钟源
          RCCSAI1_Sture.Sai1ClockSelection   = RCC_SAI1CLKSOURCE_PLLI2S;        // 选择 i2s 作为 sai的时钟源
          RCCSAI1_Sture.PLLI2S.PLLI2SP       = RCC_PLLP_DIV2;
        RCCSAI1_Sture.PLLI2S.PLLI2SN       = g_tPLLI2SPSC.PLLI2S_N;
        RCCSAI1_Sture.PLLI2S.PLLI2SR       = g_tPLLI2SPSC.PLLI2S_Q;  
        RCCSAI1_Sture.PLLI2SDivQ           = g_tPLLI2SPSC.PLLI2S_DivQ;

        }
        else if((AudioFreq == AUDIO_FREQUENCY_48K)
                || (AudioFreq == AUDIO_FREQUENCY_96K)
                || (AudioFreq == AUDIO_FREQUENCY_22K)
                  || (AudioFreq == AUDIO_FREQUENCY_16K)
                    || (AudioFreq == AUDIO_FREQUENCY_8K)
                      )
        {
          /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_22K, AUDIO_FREQUENCY_48K), AUDIO_FREQUENCY_96K */

          RCCSAI1_Sture.PeriphClockSelection = RCC_PERIPHCLK_I2S;   // 采样率为48K/96K/22K时,需要选择这个时钟源,而且这个时钟源,貌似只有48K/96K的采样率是非常好的,
                                                                                                        // 其他的采样率速度都貌似有点快 ????????? 我这样设置,是不是还有其他地方需要更改啊 ???

          RCCSAI1_Sture.Sai1ClockSelection   = RCC_SAI1CLKSOURCE_PLLI2S;        // 选择 i2s 作为 sai的时钟源
          RCCSAI1_Sture.PLLI2S.PLLI2SP       = RCC_PLLP_DIV2;
        RCCSAI1_Sture.PLLI2S.PLLI2SN       = g_tPLLI2SPSC.PLLI2S_N;
        RCCSAI1_Sture.PLLI2S.PLLI2SR       = g_tPLLI2SPSC.PLLI2S_Q;  
        RCCSAI1_Sture.PLLI2SDivQ           = g_tPLLI2SPSC.PLLI2S_DivQ;         
        }
    #endif

    HAL_RCCEx_PeriphCLKConfig(&RCCSAI1_Sture);
  }


          /* 等待就绪 */
HAL_Delay(5);

  return 0;
}
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107122
QQ
发表于 2018-1-3 00:13:00 | 显示全部楼层
是不是你的这个HAL库的问题,我们V6板子没问题,一直是这么用的。示波器把几个注意的时钟控制输出测试下,看看是不是配置的问题。
回复

使用道具 举报

610

主题

3063

回帖

4913

积分

至尊会员

积分
4913
 楼主| 发表于 2018-1-3 09:18:10 | 显示全部楼层
本帖最后由 hpdell 于 2018-1-3 19:36 编辑
eric2013 发表于 2018-1-3 00:13
是不是你的这个HAL库的问题,我们V6板子没问题,一直是这么用的。示波器把几个注意的时钟控制输出测试下, ...

貌似这样设置就对了
    RCCSAI1_Sture.PeriphClockSelection = RCC_PERIPHCLK_SAI1;        //外设时钟源选择
    RCCSAI1_Sture.Sai1ClockSelection   = RCC_SAI1CLKSOURCE_PLLI2S;  // 选择 i2s 作为 sai的时钟源   

    RCCSAI1_Sture.PLLI2S.PLLI2SP       = 0;  // RCC_PLLP_DIV2;  // 适用于 SPDIFRX 时钟的 PLLI2S 分频系数 (PLLI2S division factor for SPDIFRX clock)
                                             //所以此处设置为0即可
    RCCSAI1_Sture.PLLI2S.PLLI2SN       = g_tPLLI2SPSC.PLLI2S_N;
    RCCSAI1_Sture.PLLI2S.PLLI2SQ       = g_tPLLI2SPSC.PLLI2S_Q;
//    RCCSAI1_Sture.PLLI2S.PLLI2SR       = 4;   // 固定为 4,此项可以不用设置
    RCCSAI1_Sture.PLLI2SDivQ           = g_tPLLI2SPSC.PLLI2S_DivQ;

    HAL_RCCEx_PeriphCLKConfig(&RCCSAI1_Sture);

回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-19 08:09 , Processed in 0.151343 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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