spi 设置stm32 spi 寄存器配置 时钟 极性 何时 变化

查看: 5783|回复: 9
新版 Arduino 1.7.4 IDE 带的 SPI 库使用说明 必应翻
SPI库 简介&&(这个库只支持主设备模式)
串行外设接口(SPI)简介
串行外设接口(SPI)是一种同步串行数据协议使用的微控制器和一个或多个外围设备迅速在短距离通信。它也可以用于两个单片机之间的通信。
一个SPI连接总是有一个主设备(通常是一个微控制器)控制外围设备。
其中有三条数据线与所有的SPI设备连接,常见:
& & & & 1.&&MISO(主入从出) 用于从设备发送数据到主设备的线,
& & & & 2.&&MOSI(主出从入) 用于主设备发送数据到从设备外设的线,
& & & & 3.&&SCK(串行时钟)&&时钟脉冲的同步数据传输线,由主机产生,用于同每一个从设备同步。
4.&&SS(从选择)&&主设备使用单独的 SS 线端口,启用和禁用特定的 SPI 设备。
& & & & 当一个从设备的 SS 端口选择引脚为低电平时,它与主设备通讯。当它被置为高电平时,它忽略主设备。这可以让你有多个SPI设备共享相同的MISO,MOSI,和 SOK时钟线。
& & & & 当为一个新的SPI设备并为他写代码时,需要注意几件事:
& & & & 1. 最重要的是数据在位移寄存器里是高位在先(MSB)还是低位在先(LSB)?这是通过SPI控制setbitorder()功能实现的。
& & & & 2. 时钟空闲时是高电平还是低电平?在时钟脉冲的上升沿或下降沿的取样?这些模式是通过SPIsetdatamode() 功能控制。
& & & & 3. SPI的运行速度是什么?这是通过SPI的setclockdivider()功能控制。
& & & & SPI标准松散,每个器件实现有点不同。这意味着你要特别注意在编写代码时设备的数据表。
一般来说,有四种传送模式。这些模式控制数据转移和输出数据时是在时钟信号的上升沿还是下降沿(称为时钟相位),和时钟在闲置时是高电平还是低电平(称为时钟极性)。这四种模式结合的极性和相位如下表:
& && && && & 模式时钟极性(CPOL)时钟相位(CPHA)
& & & & spi_ mode0&&& & & & & & & &&&0 & & & & & & & & & & & && && & & && &&&0
& & & & spi_ mode1& && & & & & & & &&&0&&& & & & & & & & & & & & & & & &&&1
& & & & spi_ mode2& && & & & & & & &&&1&&& & & & & & & & & & & & & & & &&&0
& & & & spi_ mode3& && & & & & & & &&&1&&& & & & & & & & & & & & & & & &&&1
SPI.setdatamode()功能可以让你设置控制时钟极性和相位模式。
& & & & 每一个SPI设备具有最大允许的SPI总线速度。SPI.setclockdivider()允许你改变时钟的速度,使您的设备工作正常(默认情况)。
& & & & 一旦你的SPI参数设置正确,只需要控制 设备 数据寄存器的功能。这个在您的设备数据表中有说明。
& & & & 更多关于SPI,请到维基百科的页面上查询 SPI。
SPI在不同的Arduino板上的引脚线的定义:
Arduino板MOSI ,MISO, SCK, SS(从设备)SS(主设备)
UNO或Duemilanove 11或12或13或icsp-4 icsp-1 icsp-3 10—
mega1280或mega2560 51或icsp-4&&50或52或53 icsp-1 icsp-3—
列奥纳多icsp-4 icsp-1 icsp-3——
由于icsp-4 icsp-1 icsp-3 - 4,10,52
值得注意的是,MISO,MOSI,和SCK应在可用的物理位置上保持一致;这是有用的,例如,在连接一个盾板时。
关于 avr 单片机上的从设备选择 (SS) 端口
注意从设备选择(SS)端口 是基于AVR板的,所有基于AVR板都有一个SS引脚,当 SPI 库 作为从设备的外部主控时,(由于这个库只支持主模式),该引脚应设置为输出(他表示自己是主设备),否则SPI接口可以自动把自己设置为从设备模式,使库工作。
& & & & 但是,可以使用任何引脚作为选择从机的(SS)端口。例如,Arduino以太网使用引脚4控制SPI接口的板载SD卡和引脚10控制连接到以太网控制器。
适当扩展的 SPI 功能
由于SPI功能的扩展,Arduino的SPI接口工作原理不同于任何其他的Arduino板。SPI库可以 以相同的方法应用于其他Arduino板或使用扩展方法。扩展的方法利用了SAM3x硬件和允许一些有趣的功能,如:
& & & & 自动处理不同的设备配置 (时钟速度、 数据模式等) 所以每个设备可以有它自己的配置被自动选中。
& & & & Arduino& & & & 系列板 有三个预定义的从设备选择(SS)引脚线(引脚pin 4,10,52),相对于不同的Arduino板。
1. begin() 
2. begintransaction() 
3. endtransaction() 
4. setbitorder() 
5. setclockdivider() 
6. setdatamode() 
7. spisettings() 
8. transfer() 
9. usinginterrupt()
函数说明& & http://labs.arduino.org/tiki-index.php?page=SPI.begin
串行外设接口总线或 SPI 总线是同步串行数据连接标准,由摩托罗拉命名,在全双工模式下运行。设备在哪里主设备启动数据帧的主从模式进行通信。带有个人的从设备(芯片选择) 选择线为每个设备使用 pin 允许有多个从属设备。以Begin () 方法启动 SPI 通信。
一& &&&SPI.begin()函数: begin()
用法: SPI.begin(slaveSelectPin)(Arduino Due only)
参数:slaveSelectPin:&&控制从设备的 SS 端口&&适用于(Arduino Due only)
返回;&&没有
二.&&SPI.END()
函数: end()
用法: SPI.end()& && & SPI.end(slaveSelectPin)(Arduino Due only)
参数: slaveSelectPin:  控制从设备的 SS 端口&&适用于(Arduino Due only)
返回: 没有
三& & SPI.BEGINTRANSACTION
函数: beginTransaction()
描述: 初始化使用  SPISettings 定义的 SPI 总线。
用法: SPI.beginTransaction(mySettings);&&根据 mySettings 所选的参数 设置
返回: 没有
四.&&SPI.ENDTRANSACTION
函数: endTransaction()&&
描述: 停止使用 SPI 总线。允许 SPI 总线使用其他库。
用法:SPI.endTransaction()
参数: 没有
返回: 没有
五:SPI.SETBITORDER
函数:setBitOrder()
用法: SPI.setBitOrder(order)& && & SPI.setBitOrder(slaveSelectPin, order)(Arduino Due only)
参数:slaveSelectPin = 从设备端口
& && &Order = 指定数据是以LSB 低位在先 还是 MSB 高位在先
& &&&(order: LSBFIRST or MSBFIRST)
返回:没有
六. SPI.SETCLOCKDIVIDER
函数:setClockDivider()
描述:设置相对于系统时钟的 SPI 时钟分频器。基于 avr 单片机主板上可用的分隔是 2、 4、 8、 16、 32、 64或 128。默认设置为 SPI_CLOCK_DIV4,将 SPI 时钟设置为四分之一系统时钟 (4 兆赫为 16/4  mhz) 的频率。
以Arduino 使用的系统时钟,可以除以从 1 到 255 之间的值。默认值是 21,这将设置时钟至 4 兆赫,像其他 Arduino板。
Arduino 适当扩展的方法,如果您使用 setClockDivider() 函数 指定了Arduino 的 从设备选择 (SS) 端口,时钟设置只适用于连接到指定的 SS pin 的设备。
用法:SPI.setClockDivider(divider)& && &SPI.setClockDivider(slaveSelectPin, divider)(Arduino Due only)
参数:用法 1
divider:&&
SPI_CLOCK_DIV2& &(On AVR boards&&在Avr 单片机主板上)
SPI_CLOCK_DIV4
SPI_CLOCK_DIV8
SPI_CLOCK_DIV16
SPI_CLOCK_DIV32
SPI_CLOCK_DIV64
SPI_CLOCK_DIV128
slaveSelectPin: 从设备 SS pin端口 (Arduino Due only)
divider: 从 1 到 255 之间的数字(Arduino Due only)
七.&&SPI.SETDATAMODE
函数:&&setDataMode()
描述:SPI通讯是以主从模式,在全双工模式下运行,允许有多个从属设备, 主设备以启动数据帧的方式进行通信的。 主设备使用单独的 SS 端口与多个从设备一对一的进行通讯。&&带有自己的从设备 SS (芯片选择) 选择端口 。
SetDataMode() 函数 设置 SPI 通信模式:
SPI_MODE0 (上升沿采样,下降沿置位,SCK闲置时为0),
SPI_MODE1 (上升沿置位,下降沿采样,SCK闲置时为0),
SPI_MODE2 (下降沿采样,上升沿置位,SCK闲置时为1),
SPI_MODE3 (下降沿置位,上升沿采样,SCK闲置时为1)。
SPI_MODE3 是 SPI.begin() 不带任何参数的默认数据模式。对 SPI 线路板 v1 的针脚: SS = 24,MOS I= 25,MISO = 26 和 SCK = 27
用法: SPI.setDataMode(mode)& & & & & & & & SPI.setDataMode(slaveSelectPin, mode)(Arduino Due only)
参数:mode:
slaveSelectPin: 用于选择从设备的主设备 SS 端口, 适用(Arduino Due only)
返回:没有
八&&SPI.SPISETTINGS
函数:SPISettings
描述: 使用新的 SPI 库,每个 SPI 设备可以被配置一次作为一个 SPISettings 对象。
用法:SPISettings mySettting(speed, dataOrder, datamode)
speed:  通讯的速度
dataOrder:MSBFIRST 或 LSBFIRST
datamode:SPI_MODE0、 SPI_MODE1、 SPI_MODE2 或SPI_MODE3
樓主說的 IDE, 應該是 1.6.4 吧.
Super169 发表于
樓主說的 IDE, 應該是 1.6.4 吧.
1.7.4 按 Arduino 的升级提醒,就能直接进入下载页面
没有收到什么升级提示,到官网看看,还是1.6.4
小张 发表于
没有收到什么升级提示,到官网看看,还是1.6.4
我是用 1.7.3 版本时看到的升级提示,下面是链接,不会是假的吧,望验证并回复
http://arduino.org/downloads
arduino 分两家,已经打过官司了,你下的是另一家的。。现在软件的东家是http://www.arduino.cc/,你的是ORG哦
小张 发表于
arduino 分两家,已经打过官司了,你下的是另一家的。。现在软件的东家是http://www.arduino.cc/,你的是OR ...
老顽童孤陋寡闻,想问一下它们之间不相容吗?
楼主你好&&, 我是一个刚刚开始使用arduino due板子的新手 之前也没有接触过相关东西,最近要做一个MPU-9250与arduino板子 利用spi通信的工程,有些问题,可以请楼主指点吗?& &我Q
fengrenaiaiai 发表于
楼主你好&&, 我是一个刚刚开始使用arduino due板子的新手 之前也没有接触过相关东西,最近要做一个MPU-925 ...
你好,请问解决了吗?我也有问题想请教
请教一下楼主usinginterrupt() 这个函数是做什么用的。。中断嘛。。
Powered by以下来自:
SPI协议理解:时钟相位和极性&&
14:21:20|&&分类:&举报字号&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:15871次
排名:千里之外
转载:34篇
(1)(4)(1)(6)(3)(3)(1)(6)(3)(6)(1)(3)查看: 4870|回复: 14
关于stm32的spi总线读取外设寄存器的问题
主题帖子精华
初级会员, 积分 179, 距离下一级还需 21 积分
在线时间0 小时
最近在做一个spi总线的传感器好几天了也没成功了,现在把自己做的内容发上来大家看看那里有错。原子哥我知道你很忙如果没人回答,你一定要帮我。
首先分析从设备技术手册,看出从设备时钟极性为高,第二个下降沿采样,spi频率为1MHz,高位在先(我分析的对么)
dbf7cb9624d0bad5fccd9c15_841.png (0 Bytes, 下载次数: 0)
22:54 上传
1b13e0fa019a4826faf8_561.png (0 Bytes, 下载次数: 0)
22:54 上传
首先我的主频调整成了64MHz那么APB1为32Mhz
然后我对spi口进行如下的配置
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullD& //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
&SPI_InitStructure.SPI_Mode = SPI_Mode_M&&//设置SPI工作模式:设置为主SPI
&SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;&&//设置SPI的数据大小:SPI发送接收8位帧结构
&SPI_InitStructure.SPI_CPOL = SPI_CPOL_H&&//串行同步时钟的空闲状态为高电平有的人说这里主从要相对?
&SPI_InitStructure.SPI_CPHA = SPI_CPHA_2E&//串行同步时钟的第二个跳变沿(上升或下降)数据被采样
&SPI_InitStructure.SPI_NSS = SPI_NSS_S&&//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
&SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;&&//定义波特率预分频的值:波特率预分频值为32
&SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;&//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
&SPI_InitStructure.SPI_CRCPolynomial = 7;&//CRC值计算的多项式CRC有必要要么该是多少呢
&SPI_Init(SPI2, &SPI_InitStructure);& //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
&SPI_Cmd(SPI2, ENABLE); //使能SPI外设
这样做一直没有得到想要的结果问题不知道出在那里,在第二张图上读写寄存器的最高位是读(1)/写(0)位,那么在操作寄存器的时候用或上0x80吗?
另外附上一张电气特性
30da2ccebf_652.png (0 Bytes, 下载次数: 0)
22:54 上传
图上的CS setup time和CS hold time都有最低要求,问题可能是这里么?
这是我全部的疑问,请求高人作答。
主题帖子精华
在线时间144 小时
1、第二个时钟边沿采集数据而不是第二个下降沿采集数据
2、那个Table&7表格的时间值就是决定了你SPI的时钟线CLK的频率多少,一般情况下你取Typical的值就行了,如果没有标出就拿最大值减去最小值取中间那个值,这样比较靠谱很多
3、下面这两句是相对来设置的
SPI_InitStructure.SPI_CPOL&=&SPI_CPOL_H
SPI_InitStructure.SPI_CPHA&=&SPI_CPHA_2E
4、按你给出的时序图来看,和第3点的一样(即你的初始化代码)即可
5、按照表格Table&7&SPI的时钟频率最大是1MHz,但是最好还是低一点比较好点,设置32的SPI分频寄存器即可得到响应的时钟
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
主题帖子精华
初级会员, 积分 179, 距离下一级还需 21 积分
在线时间0 小时
&非常感谢你的回答!但是我还想问一些问题。
sclk不就是spi的时钟频率么?比如现在是1MHz
你说可以改小点但是技术手册上这样的,是不是说只能是100K或者1M呢?
8bb281eacfdfbf6ae84c39_414.png (0 Bytes, 下载次数: 0)
22:54 上传
您说时钟极性是相对设置的,那么我分析从机为时钟极性为高,第二个下降沿采样
那么主设备程序应该写成
SPI_InitStructure.SPI_CPOL&=&SPI_CPOL_L
SPI_InitStructure.SPI_CPHA&=&SPI_CPHA_2E
这样对吗?
还有关于crc的问题您刚才没有回答,我真的不懂
&SPI_InitStructure.SPI_CRCPolynomial = 7;&//CRC值计算的多项式CRC有必要要么该是多少呢从设备没有写crc的内容,我该怎么配置
主题帖子精华
初级会员, 积分 179, 距离下一级还需 21 积分
在线时间0 小时
回复【2楼】Badu_Space:
---------------------------------
麻烦您再帮帮我,我好几天也没弄出来,问题在2楼
主题帖子精华
在线时间397 小时
回复【3楼】蘑菇:
---------------------------------
sclk是应该等于SPI&SCK的频率,也就是SPI最大频率是1Mhz,这个你设置SPI的分频就好了。
你在2楼的贴图,说明你这个器件的工作频率在100Khz~1Mhz之间。
CPOL.CPHA,总共才4种组合,你每个都设置一下,如果还是不行,那就可能不是这里的问题了...
从你楼主位的图片看来,SCK是空闲状态高电平的。
所以CPOL的值就确定了,必须等于1.
你楼主位,CRC的设置,我觉得应该不需要吧,这个CRC功能,我还没遇到用到的地方...
我是开源电子网站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
微信公众平台:正点原子
主题帖子精华
初级会员, 积分 179, 距离下一级还需 21 积分
在线时间0 小时
回复【5楼】正点原子:
---------------------------------
原子老师,昨晚上我调出来了,你说的都对!果然是大师!
但是我遇到这么一个奇怪的问题:
&&要想读出数据,必须用手捏着四条数据线,并且电脑必须是接220V供电(或者一端用手捏数据线,另一只手捏电源线的GND)。是屏蔽的问题还是电磁干扰?得到的数据不太稳定,有错误的数据,在125KHz——1Mhz的速度间测试,125KHz较为稳定,但仍有错误数据。
&&这是为什么?
主题帖子精华
初级会员, 积分 179, 距离下一级还需 21 积分
在线时间0 小时
回复【6楼】蘑菇:
---------------------------------
原子老师,你这么晚还在回复,辛苦了!补充一点,排除了接触不良
主题帖子精华
中级会员, 积分 219, 距离下一级还需 281 积分
在线时间16 小时
SPI没有你说的那么不稳定,你抓个波形吧。看看边沿怎么样。SPI间是不是有接电阻,是否有上拉。线走了多长。
主题帖子精华
在线时间673 小时
距离很远吗?
后面的问题,属于个体差异,别人帮起来有点难。
-----抵制A莫这个烂货!-----
主题帖子精华
初级会员, 积分 179, 距离下一级还需 21 积分
在线时间0 小时
回复【8楼】dixdsqaid:
---------------------------------
谢谢7楼8楼,手头没有示波器,下午去实验室试一试,线不是很长,就是普通的杜邦线
主题帖子精华
初级会员, 积分 179, 距离下一级还需 21 积分
在线时间0 小时
回复【10楼】蘑菇:
---------------------------------
还是不行,数据抖动很大,一会有一会没有,换其他的spi设备试了试,完全没有问题,谁知道怎么回事?电压欠驱动么?
主题帖子精华
初级会员, 积分 86, 距离下一级还需 114 积分
在线时间0 小时
正在学这个,关注下
主题帖子精华
初级会员, 积分 179, 距离下一级还需 21 积分
在线时间0 小时
回复【12楼】yhnu1214:
---------------------------------
是在研究9250么?一起讨论下,不知道能发QQ不:
主题帖子精华
新手上路, 积分 37, 距离下一级还需 13 积分
在线时间0 小时
在学这个&关注一下
主题帖子精华
初级会员, 积分 86, 距离下一级还需 114 积分
在线时间0 小时
回复【13楼】蘑菇:
---------------------------------
我是个才学stm32的菜鸟,你不介意么?
Powered bySPI通讯理解_qbcaj_新浪博客
SPI通讯理解
SPI是串行外设接口(Serial Peripheral Interface)的缩写。
SPI,是一种高速的,全双工,同步的通信总线
硬件接线:
MOSI & &主出从入
MISO & &主入从出
SCLK & &时钟
NSS CS &片选
物理寄存器:
发送缓冲寄存器 & &
移位寄存器 & &
&实际上进行传输的寄存器
接收缓冲寄存器 & &
&虽然都叫一个名字但在物理上是两个存储器
*这里写的上中下是加深理解的,可以把这三个寄存器想象成叠放形式,​移位寄存器把收到的数据掉入接收缓存器;同时发送缓冲器的数据掉入移位寄存器。
软件寄存器及重要的位:
控制寄存器1 & &
控制寄存器2 & & TXEIE RXNEIE
ERRIE(发送缓冲空中断,接收缓冲非空中断,错误中断)
状态寄存器 & &
& BSY TXE RXNE(线忙,发送区空,接受区满)
数据寄存器 & &
&这里注意在软件上是一个名称,但实际有两个寄存器。
CRC多项式寄存器
RX CRC寄存器
TX CRC寄存器
SPI_I2S配置寄存器
SPI_I2S预分频器寄存器
时钟极性CPOL,时钟空闲时候的电平
时钟相位CPHA,假如把时钟的一个脉冲分成360度的话,0度就是脉冲的第一个跳变沿, &
180度就是脉冲的第二个跳变沿。
数据定义:
当SCLK时钟第一个脉冲跳变沿检测MISO或MOSI上的数据,高为1,低为0
当SCLK时钟第二个脉冲跳变沿检测MISO或MOSI上的数据,高为1,低为0
SPI的采用点是一个点,指的是时钟跳变的那个瞬间,对SD进行采样。
(I2C的采用不是点,而是时钟高电平的那段时间,对SD状态进行检测)
SPI没有应答机制。
可以配置成半双工通信;1条时钟线和1条双向数据线;
可以配置成单工通信;
&1条时钟线和1条数据线(只接收或只发送);
注意事项:
在SPI线上,先配置从设备,这样它的SCK引脚就不能发送时钟了,就不会影响SCK了。
从设备配置流程:
数据格式;8位或16位
时钟极性和时钟相位;主从设备要一致
帧格式;高位在前或低位在前
片选控制;硬件控制或软件控制
主从选择;主设备模式或从设备模式
使能开关;使能或禁止
主设备配置流程:
比从设备配置流程多了一个时钟波特率设置
传输流程:
主机和从机各有一个移位寄存器,且二者连接成环。随着时钟脉冲,数据按照从高位到低位的方式依次移出主机寄存器和从机寄存器,并且依次移入从机寄存器和主机寄存器。当寄存器中的内容全部移出时,相当于完成了两个寄存器内容的交换。把数据写入PIC_DR时候,数据自动掉入移位寄存器,然后数据从移位寄存器开始诸位传输。(全部掉进去后,发送寄存器产出一个清空标志TEX,当检测到这个标志就可以传输第二个)接收到的数据会掉入接收缓冲寄存器,并产生一个满了的标志RXNE,当把这个数据读取后,RXNE又自动清除。
博客等级:
博客积分:0
博客访问:384
关注人气:0
荣誉徽章:

我要回帖

更多关于 stm32 spi 寄存器 的文章

 

随机推荐