OpenEdv-开源电子网

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

B站新版32开发视频SD卡应用中时钟源是不是写错了?

[复制链接]

16

主题

426

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2671
金钱
2671
注册时间
2018-11-8
在线时间
430 小时
发表于 2023-10-7 10:07:18 | 显示全部楼层 |阅读模式
1金钱
视频说SDIO_CLK来自于PLL独立输出的48MHz参考手册则说等于HCLK 这是怎么回事?
看了一下 只有USB是采用的PLL 1.5分频的48MHz时钟 这里是不是搞混了啊???
QQ图片20231007100000.png
QQ图片20231007095955.png

最佳答案

查看完整内容[请看2#楼]

F1的SDIO_CLK是HCLK是没有问题的,而F4的SDIO_CLK是来源于PLL48CLK,视频中对SDIOCLK描述的应该是F4的情况,并没有涉及到F1的SDIOCLK描述。非常抱歉,这是我们的问题。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

73

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1298
金钱
1298
注册时间
2019-1-1
在线时间
173 小时
发表于 2023-10-7 10:07:19 | 显示全部楼层
F1的SDIO_CLK是HCLK是没有问题的,而F4的SDIO_CLK是来源于PLL48CLK,视频中对SDIOCLK描述的应该是F4的情况,并没有涉及到F1的SDIOCLK描述。非常抱歉,这是我们的问题。
回复

使用道具 举报

16

主题

426

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2671
金钱
2671
注册时间
2018-11-8
在线时间
430 小时
 楼主| 发表于 2023-10-7 10:13:16 | 显示全部楼层
还有新版例程里

/**
* @brief       SDMMC 时钟设置
* @param       clkdiv : 时钟分频系数
*   @note      CK时钟 =  SDIOCLK / [2 * clkdiv]; (SDIOCLK 钟一般为72Mhz)
* @retval      无
*/
static void sdmmc_clock_set(uint16_t clkdiv)
{
    uint32_t tmpreg = SDIO->CLKCR;
    tmpreg &= 0XFFFFFF00;
    tmpreg |= clkdiv;
    SDIO->CLKCR = tmpreg;
}


SDIO_CK 不是等于 SDIOCLK / [2 + clkdiv]吗 怎么变成2 * clkdiv了?
初始化传入的参数也是90

/* 用户配置区
* SDIO时钟计算公式: SDIO_CK 时钟 = SDIOCLK / [2 * clkdiv]; 其中, SDIOCLK 一般为72Mhz
* 如果出现驱动错误, 请尝试将 SDIO_TRANSFER_CLK_DIV 频率降低
*/
#define SDIO_INIT_CLK_DIV        90         /* SDIO初始化频率, 72M / (90 * 2)=400Khz, 最大400Kh */
#define SDIO_TRANSFER_CLK_DIV    3          /* SDIO传输频率,该值太小可能会导致读写文件出错 */

这里是不是有问题???

↓↓↓这是旧版例程里.h的分频系数 感觉这个才是对的

//用户配置区                          
//SDIO时钟计算公式:SDIO_CK时钟=SDIOCLK/[clkdiv+2];其中,SDIOCLK一般为72Mhz
//使用DMA模式的时候,传输速率可以到24Mhz,不过如果你的卡不是高速卡,可能也会出错
//出错就请降低时钟,使用查询模式的话,推荐SDIO_TRANSFER_CLK_DIV设置为3或者更大
#define SDIO_INIT_CLK_DIV        0xB2                 //SDIO初始化频率,最大400Kh  
#define SDIO_TRANSFER_CLK_DIV    0x04                //SDIO传输频率,该值太小可能会导致读写文件出错
回复

使用道具 举报

16

主题

426

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2671
金钱
2671
注册时间
2018-11-8
在线时间
430 小时
 楼主| 发表于 2023-10-7 15:30:09 | 显示全部楼层
又发现一处错误 F103新旧版寄存器例程里都有

sdio_sdcard.c文件第268行

static SD_Error sdmmc_power_on(void)函数中有这么一句判断
{
      /* 略 */
        if (response &= SD_HIGH_CAPACITY)
        {
            CardType = HIGH_CAPACITY_SD_CARD;
        }
    else    /* MMC卡 */
    {
      /* 略 */

}

判断条件应该是response & SD_HIGH_CAPACITY
虽然不改 大概率也能判断正确…… 看介绍 这里应该只有这一位生效
回复

使用道具 举报

16

主题

426

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2671
金钱
2671
注册时间
2018-11-8
在线时间
430 小时
 楼主| 发表于 2023-10-8 11:26:13 | 显示全部楼层
又有新问题了…… stm32f1xx_ll_sdmmc.c 第1364行 关于响应3的SDIO_STA寄存器
这里只做了超时判断 if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))

但是我实测时发现 这里其实会提示CRC错误 前一个循环是应为CRC跳出的 而后面判断把这个当做OK处理了 这是怎么回事???

/**
  * @brief  Checks for error conditions for R3 (OCR) response.
  * @param  hsd: SD handle
  * @retval SD Card error state
  */
static uint32_t SDMMC_GetCmdResp3(SDIO_TypeDef *SDIOx)
{
  uint32_t sta_reg;
  /* 8 is the number of required instructions cycles for the below loop statement.
  The SDIO_CMDTIMEOUT is expressed in ms */
  register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
  
  do
  {
    if (count-- == 0U)
    {
      return SDMMC_ERROR_TIMEOUT;
    }
    sta_reg = SDIOx->STA;
  }while(((sta_reg & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) == 0U) ||
         ((sta_reg & SDIO_FLAG_CMDACT) != 0U ));
   
  if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
  {
    __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
   
    return SDMMC_ERROR_CMD_RSP_TIMEOUT;
  }
  else
  {  
    /* Clear all the static flags */
    __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_CMD_FLAGS);
  }
  
  return SDMMC_ERROR_NONE;
}
回复

使用道具 举报

58

主题

6291

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11406
金钱
11406
注册时间
2014-4-1
在线时间
1282 小时
发表于 2023-10-8 12:05:56 | 显示全部楼层


几年前用原子的例程学 SD 存储,没遇到啥问题。


回复

使用道具 举报

16

主题

426

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2671
金钱
2671
注册时间
2018-11-8
在线时间
430 小时
 楼主| 发表于 2023-10-8 12:17:24 | 显示全部楼层
xuande 发表于 2023-10-8 12:05
几年前用原子的例程学 SD 存储,没遇到啥问题。

例程肯定是没问题的 旧版程序和新版程序我也都看了
上面的问题都不是那种致命错误 都属于那种写得不对但是恰巧也能运行的那种
比如时钟按48MHz分频和按72MHz分频 只要分完满足要求 他就能跑 但实际上时钟频率到底是多少其实根本不知道
回复

使用道具 举报

16

主题

426

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2671
金钱
2671
注册时间
2018-11-8
在线时间
430 小时
 楼主| 发表于 2023-10-16 17:00:59 | 显示全部楼层
顶一下 原子哥好像好久没出现了
回复

使用道具 举报

1

主题

73

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1298
金钱
1298
注册时间
2019-1-1
在线时间
173 小时
发表于 2023-10-20 10:37:50 | 显示全部楼层
babyrabbit 发表于 2023-10-7 10:13
还有新版例程里

/**

这里的话,SDIO_CK的计算式子为 SDIOCLK / [2 + clkdiv],而SDIO_INIT_CLK_DIV这个宏也是有问题的
好好生活,快乐工作
回复

使用道具 举报

1

主题

73

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1298
金钱
1298
注册时间
2019-1-1
在线时间
173 小时
发表于 2023-10-20 10:50:13 | 显示全部楼层
babyrabbit 发表于 2023-10-7 15:30
又发现一处错误 F103新旧版寄存器例程里都有

sdio_sdcard.c文件第268行

response &= SD_HIGH_CAPACITY 相当于 response = response & SD_HIGH_CAPACITY,最终我们就是判断这个条件是否为真,response非0即1,这里应该是没有问题的
好好生活,快乐工作
回复

使用道具 举报

1

主题

73

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1298
金钱
1298
注册时间
2019-1-1
在线时间
173 小时
发表于 2023-10-20 11:14:02 | 显示全部楼层
babyrabbit 发表于 2023-10-8 11:26
又有新问题了…… stm32f1xx_ll_sdmmc.c 第1364行 关于响应3的SDIO_STA寄存器
这里只做了超时判断 if(__SD ...

这个在使用上,暂时没有发现有问题,这是st写的,对于这个检测R3响应的流程可以看一下我们寄存器版本代码的sdmmc_cmd_resp3_error去琢磨一下
好好生活,快乐工作
回复

使用道具 举报

1

主题

73

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1298
金钱
1298
注册时间
2019-1-1
在线时间
173 小时
发表于 2023-10-20 11:15:35 | 显示全部楼层
非常感谢提出我们程序的BUG,我们会纠正这些bug
好好生活,快乐工作
回复

使用道具 举报

16

主题

426

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2671
金钱
2671
注册时间
2018-11-8
在线时间
430 小时
 楼主| 发表于 2023-10-21 11:20:23 | 显示全部楼层
thebetterman 发表于 2023-10-20 11:14
这个在使用上,暂时没有发现有问题,这是st写的,对于这个检测R3响应的流程可以看一下我们寄存器版本代码 ...

/**
* @brief       检查R3响应的错误状态
* @param       无
* @retval      0, 正常;  其他, 错误代码(详见SD_Error定义);
*/
static SD_Error sdmmc_cmd_resp3_error(void)
{
    uint32_t status;
    uint32_t timeout = SDMMC_CMD1TIMEOUT;

    while (timeout--)
    {
        status = SDIO->STA;

        if (status & ((1 << 0) | (1 << 2) | (1 << 6)))
        {
            break;  /* CRC错误/命令响应超时/已经收到响应(CRC校验成功) */
        }
    }

    if ((timeout == 0) || (status & (1 << 2)))  /* 响应超时 */
    {
        SDIO->ICR |= 1 << 2;    /* 清除命令响应超时标志 */
        return SD_CMD_RSP_TIMEOUT;
    }

    SDIO->ICR = 0X1FE00FFF;     /* 清除标记 */
    return SD_OK;
}

寄存器版是参考库文件改的吧 内容是一样的……
在R3响应里 status一共做了3个判断 CRC错误、命令超时、命令正确
但是在下一步准备返回状态时 只会返回命令超时这一种错误状态,CRC错误也被归为SD_OK了我也是偶然间发现的问题  在写这里时 我是直接复制了R2响应的内容 但是跑到这里卡住了
下图是用寄存器例程测试, 直接在R3响应这里打了个断电全速跑到这里 实际上status是0x01, 如果按照ST的程序 忽视这个错误继续执行后面可以正常运行
但就是 不太理解为啥R2就要判断CRC R3就不判断

R3.png
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-23 19:54

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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