SPI通信的总结_第1页
SPI通信的总结_第2页
SPI通信的总结_第3页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、STM32-SPI通信的总结库函数操作本文主要由7项内容介绍SPI并会在最后附上测试源码供参考:1. SPI 的通信协议2. SPI通信初始化以STM32为从机,LPC1114为主机介绍3. SPI 的读写函数4. SPI 的中断配置5. SPI 的 SMA 操作6. 测试源码7. 易出现的问题及原因和解决方法一、SPI 的通信协议SPI Serial Peripheral Interfac是一种串行同步通讯协议, 由一个主 设备和一个或多个从设备组成,主设备启动一个与从设备的同步通讯, 从而完成数据的交换。SPI接口一般由4根线组成,CS片选信号有的 单片机上也称为NSS, SCLK时钟信号

2、线,MISO数据线主机输入从 机输出, MOSI 数据线主机输出从机输入 , CS 决定了唯一的与主设 备通信的从设备,如没有 CS 信号,那么只能存在一个从设备,主设备通 过产生移位时钟信号来发起通讯。通讯时主机的数据由 MISO 输入,由 MOSI 输出,输入的数据在时钟的上升或下降沿被采样,输出数据在紧 接着的下降或上升沿被发出具体由 SPI的时钟相位和极性的设置而决定二、以STM32为例介绍SPI通信1. STM32f103带有3个SPI模块其特性如下:2221 SPI 特征 3线全双工冋步棲输帯或不帯第二根双向数按线的职线鴨工同步性输 8或16位传输帧格式选提主或从操种支持多主模式

3、8个丄模式波特率预分频系数最大为fpcix/2从摸戒频最大为fpcLx/2主橈式和从模式的快連通缶:摄大SPI速度到达18MHz 卜:模式和从模式卜均可以由牧件或硬什进行NSS管理I /从操作摸式的动态改变可编程的吋钟极性和相位可编程的数据顺斥MSB在刑或LSB在前可触竝中凝的专用笈送和接收标蛊 SPIS线忙状态様志龙持可靠通陆的硬fICRC2 SPI初始化初始化SPI主要是对SPI要使用到的引脚以及SPI通信协议中时钟相位和极性进行设置,其实STM32的工程师已经帮我们做好了这写工作,调用库函数,根据自己的需要来修改其中的参量来完成自己的配置即可,主要的配置是如下几项:引脚的配置SPI1 的

4、 SCLK, MISO ,MOSI 分别是 PA5, PA6, PA7 弓I脚,这几个弓I 脚的模式都配置成 GPIO_Mode_AF_PP复用推挽输出关于 GPIO 的8种工作模式如不清楚请自己百度,在此不解释,如果是单主单 从,CS引脚可以不配置,都设置成软件模式即可。/* Configure SPI1 pins: SCK, MISO and MOSI */GP10_InitStructure= GPI0_Pn_5 IGPI0_Pin_6 IGPIO_Pin_7;GPIo2IrLitstructure-GPIOZMode = G PI O_Mo de_AF_P P?GPIOInitS七匸口

5、cture.GPIOSpeed = GPIO_Speed_50MHz;GPIo2Init(GPIOAr &GPIO TnitStructureT;/*Configure I/O for Flash Chip selectGPIO_InitStructu.re. GPIO_Pin = GPIO_Pin_4 ;GPIOInitStr 口匚 tuie= GP10_Mode_AF_PP ; /7 片选GPIO_Init (GPIOAr &GPIO_InitStructu.re);通信参数的设置SPI_In it Structure. SPI_Directicn = S P I_D i rec t i

6、on_2 Line s_Ful lDupl ex;/全双工通 f言SPI_IrtitStructure. SPI_Mode = S P I_Mo d e_S 1 a ve;/做从机SPI_Iri itstructure-spi_DataSi ze = SPI_DataSizE_&b; /SfflSMInitStructure.SPI CPOL = SEX CPOL High; 77空闲时刻为高电平 SPllnitStructure.SPICPHA = SPrcPHA2Edge; /数据住芻2个跳边沿被采集 / S PII nit S tr uctur e. S P INSS = SPI_NSS

7、_Soft; “C!吕引廊为软件横我SPI_lnitStructurekSPI_SaudRatePrescaler = SPI_BaudRatePrescaler 8;8分频SPII nit Structure b SPl2FirStBit = SPl_FirstBLtJiSB;先传高字节SPI_InitStructure.SPI_CRCPolyn0mial = 7; SPIInit (SPI1, iSPI_liiitSt工ucture);1. SPI_Direction_2Lines_FullDuplex把 SPI 设置成全双工通信;2. 在SPI_Mode里设置你的模式主机或者从机,3.

8、SPI_DataSize是来设置数据传输的帧格式的 SPI_DataSize_8l是指8位数据帧格式,也可以设置为 SPI_DataSize_16即卩16位帧格式4. SPI_CPOL和SPI_CPHA是两个很重要的参数,是设置SPI通信时钟的极性和相位的,一共有四种模式CPOLCPOHmode 000mode 101mode 210mode 311在库函数中 CPOL 有两个值 SPI_CPOL_High( =1)和 SPI_CPOL_Low ( =0).CPHA 有两个值 SPI_CPHA_1Edge (=0)禾口 SPI_CPHA_2Edge (=1)CPOL表示时钟在空闲状态的极性是高

9、电平还是低电平,而CPHA那么表示数据是在什么时刻被采样的,手册中如下:& 1CPOL:时钟极性0:空闲状态时,SCK保持低也、佗1:它闲状态时.SCK保持高电平注意=当通信正在进行的時候,不能修改该也 注意:Ps模式下不梗用.位0CPHA:时钟相位0:数据采样从第个时钟边沿开始:1:散据采样从第二个时种边沿开始匚注意;当通信正在进行的肘候,不能條改该位. 注意:Fs模式卜不使用.我的程序中主、从机的这两位设置的相同都是设置成 1,即空闲时时钟是高 电平,数据再第二个时钟沿被采样,实验显示数据收发都正常。(要特别注意极性和相位的设置否那么,数据传输会出现错位的现象) 一般主从机的这两个位要设置

10、的一样,但是网上也有人说不能设置成一样 的,在后文中我对主从机极性和相位的配置的 16种情况都做了测试,结果 见下文。下列图很好的描述了 4种模式下的时序状况射1引用网友的一句话:“ SPI主模块和与之通信的外设备时钟相位和极性应该一致。个人理解这句话有2层意思:其一,主设备SPI时钟和极性的配置应该由外设的从设备来决定;其二,二者的配置应该保持一致,即主 设备的SDO同从设备的SDO配置一致,主设备的 SDI同从设备的SDI配置一致。因为主从设备 是在SCLK的控制下,同时发送和接收数据,并通过2个双向移位存放器来交换数据 。5. SPI_BaudRatePrescaler波特率的设置这在主

11、机模式中,这一位的设置直接决定了通信的传输速率,而从机的设置不会影响数据传输的速率,手册中有这样一句话:2 SPI从模式在从配置里.SCK引脚用于接收到从主设备来的串厅吋钟。SPLCR1寄耕屮酮2:0的世押不 影响数据传输速率*6. SPI_FirstBit这一位是设置首先传输的高字节还是低字节SPI_FirstBit_MSB是先传输高字节,SPI_FirstBit_LSB是先传输低字节注意在初始化函数里还有两项重要的内容就是在初始化之前先使能SPI的时钟和在初始化配置完成后使能 SPI。/* Enable SPI1 and GPIO clocks */rcc_apb2Periph匚:Lock

12、and(RrxrTkPBZPmriphEPi::!. | rcc_apb2pariph_GpIoa7 enable);初始化配置/* Enable SPI1 */ SPI_Cmd (SPI1/ ENABLE) ;|三、SPI的读写函数SPI有一个16位的数据存放器SPI_DR,它对应两个缓冲区,1个发送缓冲 区,1个接收缓冲区,当在控制存放器里 SPI_CR1里对DFF位设置数据帧 格式为8位时,发送和接收只用到SPI_DR7:0这8位,15-8位被强制为0, 帧格式设置成16位时全用。读写过程在手册中是这样描述的:数据发送过程数拥字被并行地肓入发送缓冲器。当从设备收到时钟信号.井且在MOSI

13、引脚匕出现第一个数据位时,发送过程开始*第 个位被 发送出上.余下的位(对于8位数据帧格式,还冇了位;对于16位数据帧格式,还冇15位)被装进 移位存放器。勺发迖缓肝器川的数掘传输到移位存放器时.SPI SP奇存黯里的TXE标志被设 置。如果设置了API-CR2存放器上的TXEIE位,将会产牛中断。数对于接收方.肖数据接收完成时;移位存放器中的数据传送到接收缓冲器、SPI_SR存放器屮的RXNE标盅被设蜀。如果设置了SPI_CR2存放器中的RXEIE位,那么产生中断。在最后一个采样时钟边沿后.RXNEfW被置T榕位存放器中接收到的数据字节被传送到接收缓 冲器*当读SPI_DR存放器吋,SPI设

14、备返回这个值。读SPI.DR存放器吋,RX忖Efd波去除。简而言之,发送时,可以通过检测SPI_SR中的TXE位,当数据存放器里有数据时,TXE位是0,当数据全部从数据存放器的发送缓冲区传输到移位存放器时TXE位被置1,这时候可以再往数据存放器里写入数据。可以通过while (SPI_l2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) = RESET来 检测。SPI_l2S_GetFlagStatus(SPI1S PI_I2S_FLAG_TXE 是库函数可以检测 SPI 的一些状态 位。接收时可以通过检测SPI_SR中的RXNE位,当数据存放器里有数据时,RXN

15、E 位是0,当数据全部从数据存放器的接收缓冲区传输到移位存放器时 RXNE 位被置1,这时候可以从数据存放器里读出数据。可以通过源程序如while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) = RESET来;检测。下,SPI读写一个字节,读写一体/SPI1的读写a3 SPl_ccnniuniCflition_sendByte (uS byt& - /* Loop while DR register in not emplty */while (SPI_l2S_GetFlagStatus(SPI1, SPII2S FLAGTXE) = RES

16、ET); /* Send byte through, the SPI1 peripheral */SPI_l2S_SendData(SPI17 byte);/* Wait to receive a byte */Whil& (SPI_l2S_G&tFlagEtatlls (SPIlj, SPI_I2S_FLAG_RXNE) = FLESET); Return the byt? rsad from the SPI bus */return SPI I2S ReceiveData(SPI1);当能成功发送和接收一个字节时,发送数组数据就变的简单了,只需要一个for循环,和指针变量的递增即可。以下仅

17、为参考:有一点特别注意,从机数据传输时要依赖主机的时钟,所以主机在接收从机发送的数据时要往从机发送哑巴字节,这个字节可以自己定义0xff,0xfe等什么字节都可以读写分开的函数:/*Description:spil 通信发送数据 */void SPI_Ecah_Buffer_Se nd(u8* pBuffer, u16 NumByteToRead)for(int i = 0; i NumByteToRead; i+)SPI_Co nmun ication_Se ndByte(*pBuffer);pBuffer+;/* Description:spil通信接收收据 */void SPI_Buff

18、er_Receive(u8* pBuffer, u16 NumByteToRead)while (NumByteToRead-) /* while there is data to be read */* Read a byte from the FLASH */*pBuffer = SPI_Conmunication_SendByte (Dummy_Byte);/* Point to the next location where the byte read will be saved */pBuffer+;读写一体的函数/*Description:spi1 通信发送接收读写数据 */voi

19、d SPI_Ecah_Buffer_Send(u8* str , u8* pBuffer, u16 NumByteToRead)for(int i = 0; i TXE为1时,会向对应的 DMA通道发出 请求,DMA通道会发出应答信号,SPI收到应答信号后撤销请求信号,DMA 撤销应答信号,并把内存值装入 SPI_DR的发送缓区,SPI的传送开始。DMA的初始化void DMATXInit (void)DMA_DInit (DMAl_Channel3);DMA initstructiire,DMAPeriphsralBasaAddfDMADMADMADMADMADMADMADMA_InitSt

20、ructure DMA DMA_In i tSt ruet口r吕 DMA DMA_mitstructure. DMA.DMA I nit (DMAl Channels r A DMA InitStructure);RCC_AHBPeriphclockQnd (RCC_AHEPeriph_DMAl r ENABLE) f DMA_Ini tT ypeD f DMA_I nitSt rue tuz:总;Init Structure DMA. InitStruct匕吕DMA Init s t rue ture DMA InitStructure DMA InitStr口匕匕口工色.DMA Ini t

21、 S t ructu re DMA InitSt met Lire, DMAJu32)SPll_DR_Addr;MetoryB as-eAddr = (u32 DMATx;DIFi =DIR_?eriphera 1 DST; / (DMATxSPI i_DR_AddrBuffersize = EpiTXEise; 发送数据的个数Periphery line = DMA_PeripheralInc_Disable; 外说地址奇存器不变 Memjorylnc = DMA_Main0ryInc Enable; 和内存地址奇存器递增 PeripheralDataSi ze = DKA_Peripher

22、alDataSize_Byte; 夕卜设数捋竞 度为日位 MemoryDataSise = DMA_ ?etlphralDataSize Eytm;Mode = DHA_Mocie_yonnal; 工作衽正世缓存樓式下Pr i arity = DMA_P r ir i ty_H i gh;M2M = EMA M2M Disable;禁止口皿矗内存到 内存的传输DMA_ITConf ig (DMAl_Channel3T DWA_IT_TCR EM ABLE) ;/7 幵启 DMA传締左成申断CUf ED31aCOUJiter DMA GetCur?DcLta.Coiiiiiter (DMA1 C

23、hannel3);DMA_Cmd! (DMAl_Chann137 ENABLE );DMA_PeripheralBaseAdd是值外设数据的地址,用 SPI1故DMA外设地址对应的是 SPI1_DR_Addr,DMA_MemoryBaseAddr是内存地址,它的值可以使,你要发送的数据所存 放的数组的名,因为数组名代表的是数组数据存放的首地址,在SPI-DMA的发送中可以理解为把 DMATX数组里的数据传送到SPI1_DR_AddrDMA_DIR 是指数据传输的方向,其值发送时其值为DMA_DIR_PeripheralDST 即外 设是目 的地,方向是 DMATX SPI1_DR_Addr,在

24、接受收时其值为DMA_DIR_PeripheralSRC,即外设是数据的来源,传输 方向是 SPI1_DR_Addr 用户指定的数据存储数组。DMA_BufferSize用来设置传输数据的个数,在STM32的DMA中其值的范 围是 065536.DMA_Mode指DMA的传输模式 DMA_Mode_Normal为正常工作模式DMA_Mode_Circular是循环工作模式,这里对循环模式的解释我认为有位 网友解释的很不错如下:“循环的意思是指DMA的传输数量计数器会重置初值,由于DMA每传一 个数据,传输数量计数器减一,只有在传输数量计数器的值不为零时,才 会响应请求。在循环模式下,当传输计数

25、器的值减为0后,会重新装载;而内存(缓存)地址那么不管循环非循环模式,都会在每次传输完成后重置 为基地址。所以,如果我们把DMA设置会正常模式,那么在下次传输前, 只需对DMA的传输数量计数器重新写入就行。循环模式一般用于数据更 新,比方ADC采用需要不停更新数据。在初始化完成之后要开启DMA的中断,在我的程序中开启的是DMA传 输完成中断。DMA_ITConfig (DMAl_Channel3 , DMA_ZT_TCz ENABLE); 开启 DMA传输完成中断 CurrDataCou.ntEr = DMAGetCurrDataCounter (DMA1 ChanneL3);DMA_Cmd.

26、(DMAl_Channe 137 ENABLE) ;/使自玄DMA1 通薩 13DMA传输有3个中断标志位,常用的是传输完成的中断。如下:9.3.6 中断可以在DIVIA传输过半、传输完成和传输错误时产生屮断。为应用f 器的不同位来翻开这些中断表39 DMA中断请求中斷事件爭件标盘位便能控制位传输过半HTIFHTIE传输立成TCIFTCIE传输错逞TEIFTEIE这样在传输完设定的数据个数之后就会触发传输完成的中断,用户可以再 中断效劳函数中,进行相应的操作, 有一点特别注意,就是要及时去除中 断标志位,为下次能够正常触发中断做准备 。void DMAl_Channel2_IRQHandler (void) /当 传输芫SpiRXSiEe个字节 一 一 _SpiCommOn = 1; /SP工通信标志位RXCurrDataCounter = DMA_GetCurrDataCounter (DMA1 Channel2; DMA ClearlTPendingBit (Dr4Ai_IT_TC2) ;/Y青除中断标志位在我的中断效劳函数中有一个标志位 SpiCommo n被置1后再中断之外进行 其他的处理,同时调用DMA_ClearlTPe ndi ngBit(DMA1T_TC2)来及时去除 中断标志。在进行DMA的数据传输时要先禁能DMA的通道,重置传输数据个数的值, 数据的

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论