OpenEdv-开源电子网

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

关于SPI读写函数SPI2_ReadWriteByte

[复制链接]

87

主题

331

帖子

0

精华

高级会员

Rank: 4

积分
906
金钱
906
注册时间
2016-3-26
在线时间
116 小时
发表于 2016-5-29 18:02:07 | 显示全部楼层 |阅读模式
本帖最后由 zhoujianwen 于 2016-5-29 18:15 编辑

        SPI2_ReadWriteByte(0x90);//·¢Ëí¶áè¡IDÃüáî            
        SPI2_ReadWriteByte(0x00);            
        SPI2_ReadWriteByte(0x00);            
        SPI2_ReadWriteByte(0x00);                                    
        Temp|=SPI2_ReadWriteByte(0xFF)<<8;  
        Temp|=SPI2_ReadWriteByte(0xFF);        


我想知道一般情况下发送这个0x00和0xff是什么意思?


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

使用道具 举报

2

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
62
金钱
62
注册时间
2019-5-31
在线时间
18 小时
发表于 2020-2-16 23:21:47 | 显示全部楼层
首先回答为什么发0x00:
####这个是跟0x90这个指令有关的,查阅w25Qxx数据手册可以看到0x90这个指令后面必须跟6个地址位,时序图中标
为6个0x00,所以说发0x00这个主要看你用的指令有没有相关要求。你可以理解为发0x00就是0x90指令的一种固定格式。
####首先要说的是0xff这个也是一个指令,该指令主要用于退出SPI的QPI模式,也就是说只有你开启了QPI模式,0xff指令
才有用,否则它就是一个没意义的数据。在你这个问题的背景下,0xff是没意义的,那为什么要发这个没意义的数据呢?
这就跟SPI协议的数据收发规则有关了,这段代码的目标是要获取芯片的ID,所以我们在下发获取芯片ID指令后,必须
去接受从设备(也就是芯片)发送回来的信息,而SPI协议的主设备和从设备用的是同一时钟,因此要想获取从设备发送
过来的数据,我们主设备必须先打声招呼,也就是先发送一个没意义的数据到从设备,给它一个暗示,而为了不产生意外的
影响,这里才选择发送0xff这个数据。
那么问题来了 Temp|=SPI2_ReadWriteByte(0xFF)<<8;Temp|=SPI2_ReadWriteByte(0xFF);   为什么要发两次0xff呢?
查看w25Qxx数据手册的0x90指令时序图我们不难发现,在我们发送0x90指令结束后,下一个时钟脉冲里,从设备(芯片)
就开始发送我们需要的ID信息了,而这个信息是16位的,但我们调用的函数返回值却只有8位,故而定义了一个16位的Temp
临时变量接受ID信息,刚刚说了我们调用的函数只能返回8位数据,所以我们要分两次获取ID信息,所以第一次借助移位运算
先把第一部分的ID信息移动到Temp的高8位,第二次再接受ID信息剩下的8位,这样一来我们想要的ID信息就完美地存放到Temp
变量里边了。至于移位运算符,这个是C语言的知识,关键就是运算符优先级。
回复 支持 3 反对 0

使用道具 举报

36

主题

162

帖子

0

精华

高级会员

Rank: 4

积分
943
金钱
943
注册时间
2015-11-24
在线时间
162 小时
发表于 2016-5-30 14:14:20 | 显示全部楼层
你可以看下SPI的协议详情,SPI协议实现的传输是移位寄存器,读写都是移位寄存器操作的,看懂了协议就明白这个0x00,0xff是啥意思了
回复 支持 反对

使用道具 举报

87

主题

331

帖子

0

精华

高级会员

Rank: 4

积分
906
金钱
906
注册时间
2016-3-26
在线时间
116 小时
 楼主| 发表于 2016-5-30 15:40:10 | 显示全部楼层
gangzilife 发表于 2016-5-30 14:14
你可以看下SPI的协议详情,SPI协议实现的传输是移位寄存器,读写都是移位寄存器操作的,看懂了协议就明白这 ...

我知道协议,就是发一些FLASH无关的指令,然后返回FLASH里面保存的数据,但是SPI协议要求接收数据之前必须先发送数据,所以就发0x00或者是0xff,也可以说是采样信号。我就是不懂什么哪个属于无关指令,是不是跟CPOL和CPHA有关?
回复 支持 反对

使用道具 举报

2

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
62
金钱
62
注册时间
2019-5-31
在线时间
18 小时
发表于 2020-2-16 23:21:01 | 显示全部楼层
首先回答为什么发0x00:
####这个是跟0x90这个指令有关的,查阅w25Qxx数据手册可以看到0x90这个指令后面必须跟6个地址位,时序图中标
为6个0x00,所以说发0x00这个主要看你用的指令有没有相关要求。你可以理解为发0x00就是0x90指令的一种固定格式。
####首先要说的是0xff这个也是一个指令,该指令主要用于退出SPI的QPI模式,也就是说只有你开启了QPI模式,0xff指令
才有用,否则它就是一个没意义的数据。在你这个问题的背景下,0xff是没意义的,那为什么要发这个没意义的数据呢?
这就跟SPI协议的数据收发规则有关了,这段代码的目标是要获取芯片的ID,所以我们在下发获取芯片ID指令后,必须
去接受从设备(也就是芯片)发送回来的信息,而SPI协议的主设备和从设备用的是同一时钟,因此要想获取从设备发送
过来的数据,我们主设备必须先打声招呼,也就是先发送一个没意义的数据到从设备,给它一个暗示,而为了不产生意外的
影响,这里才选择发送0xff这个数据。
那么问题来了 Temp|=SPI2_ReadWriteByte(0xFF)<<8;Temp|=SPI2_ReadWriteByte(0xFF);   为什么要发两次0xff呢?
查看w25Qxx数据手册的0x90指令时序图我们不难发现,在我们发送0x90指令结束后,下一个时钟脉冲里,从设备(芯片)
就开始发送我们需要的ID信息了,而这个信息是16位的,但我们调用的函数返回值却只有8位,故而定义了一个16位的Temp
临时变量接受ID信息,刚刚说了我们调用的函数只能返回8位数据,所以我们要分两次获取ID信息,所以第一次借助移位运算
先把第一部分的ID信息移动到Temp的高8位,第二次再接受ID信息剩下的8位,这样一来我们想要的ID信息就完美地存放到Temp
变量里边了。至于移位运算符,这个是C语言的知识,关键就是运算符优先级。
回复 支持 反对

使用道具 举报

10

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
188
金钱
188
注册时间
2020-3-13
在线时间
56 小时
发表于 2020-4-23 22:10:21 | 显示全部楼层
慕雪 发表于 2020-2-16 23:21
首先回答为什么发0x00:
####这个是跟0x90这个指令有关的,查阅w25Qxx数据手册可以看到0x90这个指令后面必 ...

大哥 我懂了!!!谢谢你
回复 支持 反对

使用道具 举报

2

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
55
金钱
55
注册时间
2021-1-19
在线时间
8 小时
发表于 2021-8-23 16:14:10 | 显示全部楼层
明白了
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-27 02:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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