硬汉嵌入式论坛

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

SPI驱动W25Q中代码的问题

[复制链接]

1

主题

4

回帖

7

积分

新手上路

积分
7
发表于 2022-11-11 16:33:03 | 显示全部楼层 |阅读模式
sf_ReadID() 函数
{
        g_spiLen = 0;
        g_spiTxBuf[0] = (CMD_RDID);                                /* 发送读ID命令 */
        g_spiLen = 4;
        bsp_spiTransfer();       
        id1 = g_spiRxBuf[1];                                        /* 读ID的第1个字节 */
        id2 = g_spiRxBuf[2];                                        /* 读ID的第2个字节 */
        id3 = g_spiRxBuf[3];                                        /* 读ID的第3个字节 */
}
sf_EraseChip() 函数
{       
        g_spiLen = 0;
        g_spiTxBuf[g_spiLen++] = CMD_BE;                                /* 发送整片擦除命令 */
        bsp_spiTransfer();
        sf_SetCS(1);                                                                        /* 禁能片选 */
}

        两个函数 g_spiLen = 0; 为啥要先设置为0? 发命令 ReadID中是g_spiTxBuf[0], EraseChip中确是g_spiTxBuf[g_spiLen++],有啥区别?
       传输完成后 第1个字节难道不是在g_spiRxBuf[0]中吗? 而id1 = g_spiRxBuf[1]?

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106840
QQ
发表于 2022-11-12 09:56:32 | 显示全部楼层
1、bsp_spiTransfer(); 里面要用g_spiLen
2、这个是SPI全双工,发送命令CMD_RDID,也是有返回数据的,只是我们用不到这个,但是你DMA操作要把空间给出来。
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2022-11-12 09:58:55 | 显示全部楼层
自己回复下,请大佬们看看理解的是否正确
读取ID,返回的数据0位全部是HIGH,所以ID信息的第一个字节在g_spiRxBuf[1]中,如图:但是先将g_spiLen 赋值0 还是不明白,直接赋值4不就可以了吗


356565.PNG
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2022-11-12 10:02:39 | 显示全部楼层
首先,感谢硬汉哥的回复。
读ID信息时,发0x9F加24位地址,返回的ID信息是第1个字节高,后3个字节是ID信息了
只是不明白为啥要先g_spiLen = 0,直接给g_spiLen = 4,不可以吗
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106840
QQ
发表于 2022-11-12 10:17:46 | 显示全部楼层
就是只兔子 发表于 2022-11-12 10:02
首先,感谢硬汉哥的回复。
读ID信息时,发0x9F加24位地址,返回的ID信息是第1个字节高,后3个字节是ID信息 ...

g_spiLen怎么玩都行,无需纠结,DMA操作的时候别设置错了就行。
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2022-11-12 10:30:01 | 显示全部楼层
eric2013 发表于 2022-11-12 10:17
g_spiLen怎么玩都行,无需纠结,DMA操作的时候别设置错了就行。

明白了,多谢
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2022-11-12 10:49:07 | 显示全部楼层
当看了sf_WriteEnable、sf_EraseChip、sf_EraseSector函数  整体考虑了一下,明白g_spiLen = 0的含义了。
整体是为了保证各个函数的一致性,发送写使能、擦除等命令时,先将传输数据长度(g_spiLen )设为0,然后将传输数据数组的第0位写入命令的同时,令g_spiLen++;
这样调用bsp_spiTransfer()函数时,发送的数据就是命令,数据长度g_spiLen变为了1,也就是只是发1个字节的命令;
而由于sf_ReadID() 需要4个字节(1个字节命令+3个字节的地址),所以先将 g_spiLen = 0,就没用自加了,直接赋值给了4( g_spiLen = 0)
这个语句也可以改为:
g_spiLen = 0;
g_spiTxBuf[g_spiLen++] =  (CMD_RDID);
g_spiTxBuf[g_spiLen++] =  0x00;
g_spiTxBuf[g_spiLen++] =  0x00;
g_spiTxBuf[g_spiLen++] =  0x00;
bsp_spiTransfer();
也就是发4个字节的数据(g_spiLen++了四次),一个字节的命令+三个字节的地址。

硬汉哥的函数通用性真好,需要多看几个函数就明白了,多谢
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-7 04:13 , Processed in 0.173761 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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