STM32 SPI介绍

发布者:Amybaby最新更新时间:2016-08-02 来源: eefocus关键字:STM32  SPI介绍 手机看文章 扫描二维码
随时随地手机看文章
SPI特征

3线全双工同步传输

         带货不带第三根双向数据线的双线单工同步传输

         8或16位传输帧格式选择

         主或从操作

         8个模式波特率分频系数

         从模式频率

         主模式和从模式的快速通信:最大SPI速度达到了18MHz

         主模式和从模式均可以由软件或硬件进行NSS管理:主/从操作模式的动态改变

可编程的时钟极性和相位

可编程的数据顺序

可触发中断的专用发送和接受标志

SPI总线忙状态标志

支持可靠通信的硬件CRC

 

通常SPI通过4个管脚与外部器件相连

         MISO:主设备输入/从设备输出管脚,该管脚在从模式下发送数据,在主模式下接收数据

         MOSI:主设备输出/从设置输入管脚,该管脚在主模式下发送数据,在从模式下接受数据

         SCK:串口时钟,作为主设备的输出,从设置的输入

         NSS:从设置选择,这是一个可选的管脚,用来选择主/从设置,他的功能是用来作为片选管脚,让主设备可以单独的与特定从设备通讯,避免数据线上的冲突,从设备的NSS管脚可以由主设备当做一个标准的IO来驱动,一旦被使能SSOE位,NSS管脚也可以作为输出管脚,并在SPI设置为主模式时拉低,此时所有NSS管脚连接到主设备NSS管脚的SPI设备,会检测到低电平,如果他们被设置NSS硬件模式,就会自动进入从设备状态

 

 

 

时钟信号的相位和极性

SPI_CR寄存器的CPOL和CPHA位,能够组合成四种可能的时序关系,CPOL(时钟极性)位控制在没有数据传输时时钟的空闲状态电平,此位对主模式和从设备下的设备都有效,如果CPOL被清0,SCK引脚在空闲状态保持低电平;如果CPOL被置1,SCK引脚在空闲状态保持高电平

如果CPHA时钟相位位被置1,SCK时钟的第二个边沿(CPOL位为0时就是下降沿,CPOL位为1时就是上升沿),进行数据位的采样,数据在第二个时钟边沿被锁存

CPOL时钟极性和CPHA时钟相位的组合选择数据捕捉的时钟边沿

 

 

 

SPI从模式

在从配置里,SCK引脚用于接收到主设备来的串行时钟,SPI_CR1寄存器的BR的设置不影响数据传输速率

配置步骤

1、  配置DFF位以定义数据帧格式为8位或16位

2、  选择CPOL和CPHA位来定义数据传输和串行时钟之间的相位关系,为保证正确的数据传输,从设备和主设备的CPOL和CPHA位必须配置成相同的方式

3、  帧格式(MSB在前还是LSB在前取决于SPI_CR1寄存器中的LSBFIRST位)必须和主设备相同

4、  硬件模式下,在完整的数据帧发送过程中,NSS引脚必须为低电平,软件模式下,设这SPI_CR1寄存器中的SSM位并清除SSI位

5、  清除MSTR位,设置SPE位,使响应引脚工作于SPI模式下

在这个配置里,MOSI引脚是数据输入,MISO引脚是数据输出

        

数据发送过程

数据字被并行地写入发送缓冲器

当从设备接收到时钟信号,并且在MOSI引脚上出现第一个数据位时,发送过程开始,第一个位被发送出去,余下的位(对于9位数据帧格式,还有7位;对于16位数据帧格式,还有15位)被装进移位寄存器,当发送缓冲器中的数据传输到移位寄存器时,SPI_SR寄存器里的TXE标志被设置,如果设置了SPI_CR2寄存器上的TXEIE位,将会产生中断

 

数据接收过程

对于接收方,当数据接收完成时

         移位寄存器中的数据传送到接受缓冲器,SPI_SR寄存器中的RXNE标志被设置

         如果设置了SPI_CR2寄存器的RXEIE位,则产生中断

在最后一个采样时钟边沿后,RXNE位被置1,移位寄存器中接收到的数据字节被传送到接受缓冲器,当读SPI_DR寄存器时,SPI设备返回这个值。读SPI_DR寄存器是,RXNE位被清除。

 

SPI主模式

在主配置时,串行时钟在SCK脚产生

配置步骤

1、  通过SPI_CR1寄存器的BR位定义串行时钟波特率

2、  选择CPOL和CPHA位,定义数据传输和串行时钟的相位关系

3、  设置DRR位来定义8位或16位数据帧格式

4、  配置SPI_CR1寄存器的LSBFIRST位定义帧格式

5、  如果NSS引脚需要工作在输入模式,硬件模式中在整个数据帧传输器件应把NSS脚连接到高电平;在软件模式中,需设置SPI_CR1寄存器的SSM和SSI位,如果NSS引脚工作在输出模式,则只需设置SSOE位

6、  必须设置MSTR和SPE位

 

在这个配置中,MOSI脚是数据输出,而MISO脚是数据输入。

 

 

数据发送过程

当一字节写进发送缓冲器时,发送过程开始。

在发送第一个数据位时,数据字被并行地(通过内部总线)传入以为寄存器,而后串行地溢出到MOSI脚上;MSB在线还是LSB在线,取决于SPI_CR1寄存器中的LSBFIRST位,数据从发送缓冲器传输到移位寄存器时TXE标志将被置位,如果设置SPI_CR1寄存器中的TXEIE位,将产生中断

 

数据接收过程

         对于接收器来说,当数据传输完成时

                   移位寄存器里的数据传送到接收缓冲器,并且RXNE标志被置位

                   如果SPI_CR2寄存器中的RXEIE位被置位,则产生中断。

         在最后采样时钟沿,RXNE位被设置,在移位寄存器中接收到的数据字被传送到接受缓冲器,读SPI_DR寄存器时,SPIU设备返回接受到的数据字,读SPI_DR寄存器将清除RXNE位。

         一旦传输开始,如果下一个将发送的数据被放进了发送缓冲器,就可以为之一个连续的传输流,在试图写发送缓冲器之前,需确认TXE标志应该是1
 

SPI_InitTypeDef  SPI_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);

 
 SPI_Cmd(SPI2, DISABLE);            //必须先禁能,才能改变MODE
   SPI_InitStructure.SPI_Direction =SPI_Direction_2Lines_FullDuplex;  //两线全双工
   SPI_InitStructure.SPI_Mode =SPI_Mode_Master;       //主
   SPI_InitStructure.SPI_DataSize =SPI_DataSize_8b;      //8位
   SPI_InitStructure.SPI_CPOL =SPI_CPOL_High;        //CPOL=1时钟悬空高
   SPI_InitStructure.SPI_CPHA =SPI_CPHA_1Edge;       //CPHA=1 数据捕获第2个
   SPI_InitStructure.SPI_NSS =SPI_NSS_Soft;        //软件NSS
   SPI_InitStructure.SPI_BaudRatePrescaler =SPI_BaudRatePrescaler_2;  //2分频
   SPI_InitStructure.SPI_FirstBit =SPI_FirstBit_MSB;      //高位在前
   SPI_InitStructure.SPI_CRCPolynomial =7;        //CRC7
   
 SPI_Init(SPI2,&SPI_InitStructure);
 SPI_Cmd(SPI2, ENABLE);

//spi的配置结束了可以使用了。

 

也可用 函数SPI_StructInit 把SPI_InitStruct中的每一个参数按缺省值填入

STM32 SPI(二) - liyunfengxiaozhe - 小哲

 

STM32 SPI(二) - liyunfengxiaozhe - 小哲

 

 

_____________________________________________________________________________________

 

发送缓冲器空闲标志(TXE)【3.0 SPI_I2S_FLAG_TXE】
此标志为’1’时表明发送缓冲器为空,可以写下一个待发送的数据进入缓冲器中。当写入SPI_DR时,TXE标志被清除。
接收缓冲器非空(RXNE)【3.0 SPI_I2S_FLAG_RXNE】
此标志为’1’时表明在接收缓冲器中包含有效的接收数据。读SPI数据寄存器可以清除此标志。

 

注意在2.0的库中函数

SPI_SendData         SPI_ReceiveData         SPI_GetFlagStatus       等在3.0的库中 变为

SPI_I2S_SendData  SPI_I2S_ReceiveData  SPI_I2S_GetFlagStatus

 

写一个发送/接受函数

 

static u8 SPIByte(u8 byte)

{
 
 while((SPI2->SR &SPI_I2S_FLAG_TXE)==RESET);
 //while((SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE))==RESET);
  
 SPI2->DR = byte;
 //SPI_I2S_SendData(SPI2,byte);
 
 while((SPI2->SR &SPI_I2S_FLAG_RXNE)==RESET);

//while((SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE))==RESET);
 return(SPI2->DR);

 

 //returnSPI_I2S_ReceiveData(SPI2);读寄存器用硬件清除标志位。
 //SPI_I2S_ClearFlag(SPI2,SPI_I2S_FLAG_RXNE) ;直接软件清除标志位。
}

关键字:STM32  SPI介绍 引用地址:STM32 SPI介绍

上一篇:STM32 DMA理解
下一篇:STM32 EXIT

推荐阅读最新更新时间:2024-03-16 15:02

STM32编译出现 Error[Li005]: no definition for "assert_param"
如果出现这个错误,请增加预编译内容: USE_STDPERIPH_DRIVER 如图
[单片机]
<font color='red'>STM32</font>编译出现 Error[Li005]: no definition for
STM32的ADC用法你都知道吗?
AD采样在电路中是一种比较常见的功能,可以用于电池电压检测、传感器值读取、信号采集等。STM32的ADC,由于引入了DMA,以及多种触发源,功能自然强大,用法也多种多样。这里简单说下单通道情况下,AD采样的几种用法。 1、AD单次转换+软件启动 最基本的用法,通过程序启动AD,AD采集一次,我们就去读一次。这种情况,建议开启AD转换完成中断,在中断中读出AD值并做处理。 这种方式的优点是配置简单,缺点么,太T么简单~ 初始化的时候,启动一次。然后在主循环里,每隔一秒启动一次。 在中断回调函数里,进行相关处理: 电脑输出如下: 2、连续转换+软件启动 在方法1的基础上做调整,从单次转换,变成连续转换。也就是说,只需要
[单片机]
<font color='red'>STM32</font>的ADC用法你都知道吗?
stm32初始化三个串口
serial.c #include serial.h int fputc(int ch,FILE *p) //在使用printf时系统自动条用此函数 { USART_SendData(USART2,(u8)ch); while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET); return ch; } /******************************************************************************* * 函 数 名 : serial_in
[单片机]
STM32的Remap
STM32中有很多内置外设的输入输出引脚都具有重映射(remap)的功能,本文对一些在使用引脚重映射时所遇到的有关问题加以说明。我们知道每个内置外设都有若干个输入输出引脚,一般这些引脚的输出脚位都是固定不变的,为了让设计工程师可以更好地安排引脚的走向和功能,在STM32中引入了外设引脚重映射的概念,即一个外设的引脚除了具有默认的脚位外,还可以通过设置重映射寄存器的方式,把这个外设的引脚映射到其它的脚位。 例如,USART3_TX的默认引出脚是PB10,USART3_RX的默认引出脚是PB11;但经过重映射后,可以变更USART3_TX的引出脚为PD8,变更USART3_RX的引出脚为PD9。 同时,STM32还只可以将一个功
[单片机]
STM32SPI读写函数
//SPIx 读写一个字节 //TxData:要写入的字节 //返回值:读取到的字节 u8 SPIx_ReadWriteByte(u8 TxData) { while((SPI1- SR&(1 1))==0); SPI1- DR=TxData; //发送一个byte while((SPI1- SR&(1 0))==0); returnSPI1- DR; //返回收到的数据 } 对于这
[单片机]
通过STM32 UART及DMA修改TIMER占空比示例
现在有人谈到这样一个需求,他使用STM32F429芯片做开发,其中用到TIM2做3路PWM输出。另外有个上位机跟STM32的UART接口相连,上位机可能不定期地需要通过UART接口给STM32发送新的占空比参数,而且每次都发送3个输出通道的比较参数。如何快捷地实现这个功能呢?要求收到数据后尽快修改3个比较通道的参数。 STM32F429的TIM2是32位定时器,3个通道的CCR寄存器也是32位的。那么上位机每次发3个通道的参数对应12字节的数据。 显然,整体上功能不算复杂。我们可以先通过UART收到12字节数据,稍加整理后手动将数据逐字写到3个CCR寄存器来改变PWM输出。说实在的,这个方案的实现过程还是很清晰的,相信也是
[单片机]
通过<font color='red'>STM32</font> UART及DMA修改TIMER占空比示例
关于stm32串口不定长数据接收(hal库)的若干问题
使用串口空闲中断和DMA配合时出现的问题: 问题1.串口接收一旦溢出就会丢数据。 例如串口接收满了,稍等几秒再启动新的DMA接收函数HAL_UART_Receive_DMA时,就丢失数据了,而且是再也收不到串口数据。如果接满后马上启动就没这个问题。 看官方示例代码,停止DMA接收后似乎要DeInit后重新初始化Init和启动DMA接收 解答: 当接收DMA关闭后,此时串口还是激活的,若此时串口来数据,无法触发DMA传输,此时产生上溢错误(ORE),由于串口数据寄存器里的数据不能及时转移走,后面来的数据就进不来。一旦出现这种错误后,就不会再触发DMA请求,即使再开启DMA也不行。要恢复正常的话就只有Deinit后再重
[单片机]
关于<font color='red'>stm32</font>串口不定长数据接收(hal库)的若干问题
STM32如何高效接收串口数据?
硬件:stm32f103cbt6 软件:STM32F10x_StdPeriph_Lib_V3.5.0 DMA,直接内存存取,可以用它的双手释放CPU的灵魂,所以,本文通过USART3进行串口收发,接受使用DMA的方式,无需CPU进行干预,当接受完成之后,数据可以直接从内存的缓冲区读取,从而减少了CPU的压力。 具体的代码实现如下: usart_driver.h 封装了接口,数据接收回调函数类型,基本数据结构等; usart_driver.c 函数原型实现,中断服务函数实现等; 拷贝这两个文件即可,可以根据目录下的参考用例,进行初始化。 头文件usart_driver.h已经声明了外部函数可能用到的接口; USART3_DR的地
[单片机]
<font color='red'>STM32</font>如何高效接收串口数据?
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved