OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6014|回复: 2

使用F4+INMP441硅麦(I2S接口)录音,并存储到SD卡中,发现录音文件数据缺失

[复制链接]
回帖奖励 1 金钱 回复本帖可获得 1 金钱奖励! 每人限 1 次(中奖概率 50%)

3

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
112
金钱
112
注册时间
2021-6-15
在线时间
19 小时
发表于 2022-11-7 16:16:40 | 显示全部楼层 |阅读模式
使用F4+INMP441硅麦(I2S接口)录音,并存储到SD卡中,发现录音文件数据缺失,比如录音三分钟,但录音文件只有两分四十几秒,因为数据缺失,听起来是倍速的感觉。
SD卡时钟速度差不多最大了,24MHz(最大不超过25MHz),并且是四线传输,cubemx生成的代码。

经过测试,发现是f_write函数写入速度过慢,导致数据写入期间一些数据没有采集到。
测试方法:只读取音频数据,不写入SD卡,即注释掉f_write函数,发现读取到的数据量符合理论计算;读取数据并写入SD卡,就会出现数据缺失的情况;
但是对比正点原子例程VS1053录音实验,使用的是同样的方法,但是为什么不存在这个问题,求解!!!!!!!

我的代码:
//通过I2S读取音频数据并存储
void RS_I2SData(void)
{
        uint16_t i;
        uint16_t w[4];
        uint16_t rxbuf[256];
       
        New_Pathname();
        HAL_GPIO_WritePin(GPIOB, LED1_Pin, GPIO_PIN_RESET);
       
        while(!dmastopflag)
        {
                while(start_left()!=1);
                for(i=0;i<256;i++)
                {
                        I2S_Receive(&hi2s1,w,4); //接收4个uint16_t,即一个左右声道数据
                        rxbuf[i]=w[0];
//                        rxbuf[2*i+1]=w[0];
                }
                f_write(&SDFile,rxbuf,512,&numRwr);
                sectorsize++;
        }
        Write_WaveHeader(sectorsize);
        f_close(&SDFile);
        printf("sectorsize = %d\r\n",sectorsize);
        sectorsize=0;
        printf("录音完成\r\n\r\n");
        HAL_GPIO_WritePin(GPIOB, LED1_Pin, GPIO_PIN_SET);
}



正点原子VS1053录音实验:
//读取数据                          
                        if(rec_sta==0X80)//已经在录音了
                        {
                          w=VS_RD_Reg(SPI_HDAT1);       
                                if((w>=256)&&(w<896))
                                {
                                         idx=0;                                            
                                  while(idx<512)         //一次读取512字节
                                        {         
                                                 w=VS_RD_Reg(SPI_HDAT0);                                               
                                                 recbuf[idx++]=w&0XFF;
                                                recbuf[idx++]=w>>8;
                                        }                           
                                         res=f_write(f_rec,recbuf,512,&bw);//写入文件
                                        if(res)
                                        {
                                                printf("err:%d\r\n",res);
                                                printf("bw:%d\r\n",bw);
                                                break;//写入出错.          
                                        }
                                        sectorsize++;//扇区数增加1,约为32ms         
                                }                       
                        }

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8462
金钱
8462
注册时间
2020-5-11
在线时间
3904 小时
发表于 2022-11-8 12:19:05 | 显示全部楼层
问题在于 f_write耗时较长导致I2S_Receive获取的数据有缺失?就像ADC采集波形一样,一段时间不采就漏掉了?
建议将读取数据程序放入定时中断,读取的数据放入一个FIFO(循环队列),主循环读取FIFO然后写入SD。
VS1053估计内部自带FIFO。
专治疑难杂症
回复 支持 反对

使用道具 举报

3

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
112
金钱
112
注册时间
2021-6-15
在线时间
19 小时
 楼主| 发表于 2022-11-10 15:46:54 | 显示全部楼层
LcwSwust 发表于 2022-11-8 12:19
问题在于 f_write耗时较长导致I2S_Receive获取的数据有缺失?就像ADC采集波形一样,一段时间不采就漏掉了? ...

感谢回帖,您的建议已收到,我会尝试看看效果,非常感谢
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-24 23:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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