秃头老弟 2023-12-20 09:27 采纳率: 0%
浏览 41
已结题

i2S驱动SPH0645

我买了一块SPH0645的数字硅麦,我看手册是24位的,i2s的硅麦,下面是我单片机i2s的配置,采样频率是16Khz,CLK是1MHz,符合手册上给的时钟,通过DMA搬运数据,存放在uint32_t audio_buffer[4]里。采集到数据了,但是不管我制造多大声音,所采集的数据几乎不变,所以我想问问有没有懂得人,驱动过这款硅麦的,看看是否是我i2s配置有问题还是数据解析有问题。下面是我的配置代码

/*i2s的相关配置*/
void i2s_config ( void )
{
    /*引脚初始化*/
    gpio_config();
    
    dma_init_type dma_init_struct;

    i2s_init_type i2s_init_struct;

    crm_periph_clock_enable ( CRM_DMA1_PERIPH_CLOCK, TRUE ); /*使能 DMA1 时钟*/
    dma_reset ( DMA1_CHANNEL2 ); /*复位 DMA1 channel4,使 channel4 处于默认配置*/

    dma_default_para_init ( &dma_init_struct );/*将 DMA 初始化变量置为默认值*/
    dma_init_struct.buffer_size = 4;/*设置 DMA buffer 长度: 和12S 通信数据长度一致*/
    dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;/*数据传输方向:从外设到内存*/
    dma_init_struct.memory_base_addr = ( uint32_t ) audio_buffer;
    dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_WORD;//DMA 内存数据总线宽度 16 位
    dma_init_struct.memory_inc_enable = TRUE;/*内存地址自增: 使能 (每收/发一个数据后,内存地址要加一*/
    dma_init_struct.peripheral_base_addr = ( uint32_t ) 0x4001300C; //外设地址
    dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_WORD;//DMA 外设数据总线宽度 16 位
    dma_init_struct.peripheral_inc_enable = FALSE;/*外设地址自增:关闭(一直是 SPI 数据寄存器,不变)*/
    dma_init_struct.priority = DMA_PRIORITY_HIGH;//优先级:高优先级
    dma_init_struct.loop_mode_enable = TRUE;//循环模式:关闭
    dma_init ( DMA1_CHANNEL2, &dma_init_struct );

    crm_periph_clock_enable ( CRM_SPI1_PERIPH_CLOCK, TRUE );

    i2s_default_para_init ( &i2s_init_struct );

    i2s_init_struct.operation_mode = I2S_MODE_MASTER_RX;//设置i2S为主机接收模式
    i2s_init_struct.audio_protocol = I2S_AUDIO_PROTOCOL_MSB;//设置I2S为飞利浦标准
    i2s_init_struct.audio_sampling_freq = I2S_AUDIO_FREQUENCY_16K;//配置i2s采样率为16K;
    i2s_init_struct.data_channel_format = I2S_DATA_24BIT_CHANNEL_32BIT;//设置i2s帧格式为:数据位数为24bit,声道位数为32bit
    i2s_init_struct.clock_polarity = I2S_CLOCK_POLARITY_LOW;//设置时钟空闲电平为低电平
    i2s_init_struct.mclk_output_enable = FALSE;//使能MCLK时钟输出
    i2s_init ( SPI1, &i2s_init_struct );

    spi_i2s_dma_receiver_enable ( SPI1, TRUE );
    dma_channel_enable ( DMA1_CHANNEL2, TRUE );
    i2s_enable ( SPI1, TRUE );
}
/*采集的数据处理*/
void get_db_value ( void )
{
    //dat32 example: 0000fffb 00004f00
    val24 = (( audio_buffer[0] << 8 ) + ( audio_buffer[1]  ))>>8;


    //24位有符号整型扩展到32if ( val24 & 0x800000 ) //negative
    {
        val32 = 0xff000000 | val24;
    }
    else  //positive
    {
        val32 = val24;
    }

}
  • 写回答

16条回答 默认 最新

  • 叫兽-郭老师 Java领域新星创作者 2023-12-20 09:28
    关注
    获得1.80元问题酬金

    由人工智能和答主提供,可以参考如下,如果回答的不正确,及时评论区回复,我追加回答,谢谢。


    从你的代码来看,你已经正确地配置了I2S和DMA。但是,你提到采集到的数据几乎不变,这可能是由于以下原因:

    1. 采样率设置不正确:根据手册,SPH0645的采样率为16KHz,但是你的代码中设置的采样率为16K。请检查并确保采样率设置正确。

    2. 数据位宽设置不正确:根据手册,SPH0645的数据位宽为24位,但是你的代码中设置的数据位宽为32位。请检查并确保数据位宽设置正确。

    3. 数据处理问题:在get_db_value()函数中,你将24位有符号整数扩展到32位整数。但是,你没有处理负数的情况。当val24的最高位(第24位)为1时,表示这是一个负数。你需要在扩展之前检查这个位,并根据需要设置最高位为1。

    你可以尝试修改get_db_value()函数,如下所示:

    void get_db_value ( void ){
        //dat32 example: 0000fffb 00004f00
        val24 = (( audio_buffer[0] << 8 ) + ( audio_buffer[1]  ))>>8;
        //将24位有符号整型扩展到32位
        if ( val24 & 0x800000 ) //negative
        {
            val32 = 0xff000000 | val24;
        }
        else  //positive
        {
            val32 = val24;
        }
    }
    

    如果问题仍然存在,建议你检查硬件连接和信号完整性,以及使用示波器或其他调试工具验证I2S和DMA传输是否正确。

    评论

报告相同问题?

问题事件

  • 系统已结题 12月28日
  • 创建了问题 12月20日

悬赏问题

  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境
  • ¥30 关于#java#的问题,请各位专家解答!
  • ¥30 vue+element根据数据循环生成多个table,如何实现最后一列 平均分合并
  • ¥20 pcf8563时钟芯片不启振
  • ¥20 pip2.40更新pip2.43时报错
  • ¥15 换yum源但仍然用不了httpd
  • ¥50 C# 使用DEVMOD设置打印机首选项
  • ¥15 麒麟V10 arm安装gdal