硬汉嵌入式论坛

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

[有问必答] 使用SPI读取W25Q64播放wav文件速度跟不上

[复制链接]

33

主题

203

回帖

302

积分

高级会员

积分
302
发表于 2020-1-4 16:23:00 | 显示全部楼层 |阅读模式
STM32F103  SPI速度设置18M,DAC播放16KHz的WAV文件,使用两个512字节缓存来回读写,TIMER读缓存1的时候,SPI写缓存2,然后等待缓存1空。TIMER切换到缓存2,SPI写缓存1。

发现TIMER读完缓存1后,SPI并未将缓存2写满,导致出现问题。

TIMER每秒16K中断,读取512字节耗时512 /16K约为30ms。经过测试,SPI读取512字节粗略耗时不超过20ms。
几经更改程序结构并未解决问题,有没有其他较简单的方法实现此功能?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107031
QQ
发表于 2020-1-4 16:58:58 | 显示全部楼层
SPI读取512字节粗略耗时不超过20ms


20ms读取512字节,那你的SPI Flash读速度才50*512 = 25.6KB/S

这个速度是不是太慢了点。
回复

使用道具 举报

33

主题

203

回帖

302

积分

高级会员

积分
302
 楼主| 发表于 2020-1-6 12:22:08 | 显示全部楼层
eric2013 发表于 2020-1-4 16:58
20ms读取512字节,那你的SPI Flash读速度才50*512 = 25.6KB/S

这个速度是不是太慢了点。

我也比较纳闷。难道是没有抄你的程序?一定是的,我这就去把你的程序抄过来用
回复

使用道具 举报

335

主题

2037

回帖

3047

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3047
发表于 2020-1-6 13:57:48 | 显示全部楼层
先用示波器测量一下spi的时钟,看看对不对。 再者,使用DMA读取方式看看。

有个特点需要注意下,spi flash上电后,需要10ms以后才开始操作它比较保险。 这个是datasheet某地方说的。
回复

使用道具 举报

13

主题

45

回帖

84

积分

初级会员

积分
84
发表于 2020-1-9 08:53:21 | 显示全部楼层
你这怎么搞的,我用FATFS之后SPI读FLASH还能达到2M字节每秒的速度,改FLASH驱动代码吧
回复

使用道具 举报

33

主题

203

回帖

302

积分

高级会员

积分
302
 楼主| 发表于 2020-1-9 17:06:26 | 显示全部楼层
a3748622 发表于 2020-1-9 08:53
你这怎么搞的,我用FATFS之后SPI读FLASH还能达到2M字节每秒的速度,改FLASH驱动代码吧

static void stm32_spi2_init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        SPI_InitTypeDef SPI_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
    //GPIO的时钟已在其他地方使能
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                       
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
        GPIO_SetBits(GPIOC,GPIO_Pin_6);       

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 |GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                        
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);

        SPI_I2S_DeInit(SPI2);
        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;               
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;               
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;               
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;       
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;               
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;               
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;       
        SPI_InitStructure.SPI_CRCPolynomial = 7;       
        SPI_Init(SPI2,&SPI_InitStructure);

        SPI_Cmd(SPI2, ENABLE);
    delay_ms(100);
}
/******************************************************************************/
#define        W25Q64_CS                 PCout(6)                 

/******************************************************************************/
static u8 stm32_spi2_read_write_byte(u8 dat)
{               
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)
    {
    }                          
    SPI_I2S_SendData(SPI2, dat);

    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)
    {
    }
    return SPI_I2S_ReceiveData(SPI2);                            
}
/******************************************************************************/
void w25q64_init(void)
{       
  stm32_spi2_init();                          
  W25Q64_CS = 1;                               

  m_w25q64_id = w25q64_read_id();
}  
/******************************************************************************/
void w25q64_read_num_data(u32 addr, u8 *buf, u16 num)   
{
    u16 i;          
    u8 *db;   
    W25Q64_CS = 0;                                     
    stm32_spi2_read_write_byte(W25Q64_CMD_RD_DATA);      
    stm32_spi2_read_write_byte((u8)((addr) >> 16));  
    stm32_spi2_read_write_byte((u8)((addr) >> 8));   
    stm32_spi2_read_write_byte((u8)addr);   

    db = buf;
    i = num;
    while(i--)
    {
        *db = stm32_spi2_read_write_byte(0xFF);          
        db++;
    }

    W25Q64_CS = 1;                                                   
}  
/******************************************************************************/

没检查出来问题,帮忙看一下。

回复

使用道具 举报

33

主题

203

回帖

302

积分

高级会员

积分
302
 楼主| 发表于 2020-1-9 17:19:58 | 显示全部楼层
a3748622 发表于 2020-1-9 08:53
你这怎么搞的,我用FATFS之后SPI读FLASH还能达到2M字节每秒的速度,改FLASH驱动代码吧

好些年没用过STM32,全忘了。。。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107031
QQ
发表于 2020-1-10 00:59:44 | 显示全部楼层
diiiiiii 发表于 2020-1-9 17:06
static void stm32_spi2_init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;

读写函数要优化:

加快SPI连续读写速度的配置方式
http://www.armbbs.cn/forum.php?m ... 1095&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-15 00:30 , Processed in 0.189612 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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