STM32学习笔记—SPI通信

1、SPI简介

 

2、函数配置

1、SPI简介

SPI通信是一种高速的,全双工的同步通信总线,通讯时,只占用四条线:MISO MOSI CS SCLK,其中cs为片选线,sclk为时钟线(一般同步通讯带有时钟线,像uart异步通信的就不带),miso和mosi这个就是主入从出和主出从入的信号线。下面看下spi的工作过程。

 这边在主机和从机都会有一个移位寄存器,spi的数据是如何传输的呢,从图中可知,spi是全双工,那么在我们读取一个字节的时候,也会写一个字节进去,这样就相当于两个移位寄存器的内容进行了交换。一般开始的时候,主机都会向从机写入一个字节来开始spi的传输,所以后面的代码段我们会看见主机向从机写一个0xff作为spi的开始,实际上这个值可以取任何值,都可以作为spi的开始信号。如果我们只进行写操作,那么我们可以忽略读进来的内容,同理,如果我们进行读操作,那么我们就可以随便写一个内容(但是为了麻烦通常都写0xff)。

2、函数配置

这边我们选取的是W25Q128,这边给128除以8,可以看出这个flash可以存储16m的字节。下面我们开始函数的配置。这边选取的stm32f103zet6的spi2作为实验接口。

1、spi2的初始化,初始化spi的话肯定要先初始化gpio口时。这边由硬件连我们去查芯片手册,我们可以得到各个引脚的模式,这边mosi选择的是推挽输出,miso芯片手册上显示的是配置成上拉输入和浮空输入(这边选择配置为推挽输出,也能工作),还有一个sclk的时钟信号输入,这边选择也是推挽输出。初始化gpio后,需要初始化spi2,这边需要注意几个个参数,一个是CPOL和CPHA,这两个参数一个是配置spi空闲时是高电平还是低电平,一个是配置spi通信是是第一个时钟沿还是第二个时钟沿开始数据捕获.这边我们选择空闲时电平为高电平,选择在第二个时钟沿开始数据捕获。还有这边cs引脚选择软件控制,其中的一个参数crc需要大于1,这里选择7,这里的预分频系数由于是初始化,所以选择的频率可以很低,这边选择预分频系数为256,后面开始传输的时候我们再提高spi的频率,我们的片选引脚是我们给定的io控制的,所以我们选择软件控制。

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置 SPI 全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置 SPI 工作模式:设置为主 SPI SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // 8 位帧结构

SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//选择了串行时钟的稳态:时钟悬空高 

SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //数据捕获于第二个时钟沿 

SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS 信号由硬件管理 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //预分频 256 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从 MSB 位开始 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC 值计算的多项式

2、spi的速率设置。这里主要操作的spi2的CR1寄存器,这里主要是判断spi的预分频系数是否是给定的几个数字,如果是的话,就操作CR1寄存器修改spi的速率。

void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler) { assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler)); SPI2->CR1&=0XFFC7; SPI2->CR1|=SPI_BaudRatePrescaler; //设置 SPI2 速度 SPI_Cmd(SPI2,ENABLE); }

3、spi的读写一个字节

在我们使用spi发送和接收数据的时候,一般我们都需要等待spi忙完,这时我们可以去获取spi2的状态,我们发送数据的时候,我们去获取 SPI_I2S_FLAG_TXE这个状态,如果这个状态是0,说明此时spi2处于发送状态,那么就等待发送完成,发送之后,由于spi是发送的同时在接收,紧接著我们获取spi的接收状态 SPI_I2S_FLAG_RXNE,所以这边我们等待spi接收完成,然后返回我们接收的值。这就是一个spi的接收和发送数据的过程。

4、在使用W25QXX的时候,由于我们使用的是软件片选在,在初始化flash时,我们要初始化我们的片选io口。

5、下面说一下W25QXX的读写过程,读操作相对于写操作简单一点。读操作:首先我们拉低片选引脚,然后我们向flash发送读命令,紧接着我们向flash发送我们读取的地址,flash在收到我们的地址之后就会把相应位置的数据发送过来,发送完一个字节之后,地址会自动加一,这样我们通过这一个命令就可以读取flash的全部数据或者指定长度的数据(不受扇区等的限制)。而写操作相对于读操作就相对来说复杂一点,一部分原因是因为向W25QXX写入数据时需要保证我们写入的扇区是擦除过的,另一方面是我们每写完一个扇区(256个字节)的时候,我们必须把地址给清零,否则的话,你这个地址就会作为扇区地址,那样256个字节之后的内容就会写到其他的扇区而不是下一个扇区了。所以我们综上两点,写操作就比读操作麻烦。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32SPI通信中,接收到0xFFFF通常表示SPI接收缓冲区为空。这可能是由于以下几个原因导致的: 1. 通信错误:SPI通信可能存在错误,导致接收到无效数据。这可能是由于SPI时钟配置错误、数据位数设置错误、传输模式不匹配等原因引起的。需要检查SPI配置和通信设置是否正确。 2. 传输长度错误:如果接收到的数据长度超过了实际传输的数据长度,可能会导致接收到无效数据。需要确保发送和接收的数据长度一致。 3. 电气问题:SPI通信可能受到电气干扰或连接问题的影响,导致接收到无效数据。需要检查SPI接口的物理连接是否正确,确保信号线连接良好。 4. 芯片故障:如果以上步骤都没有问题,可能是芯片本身存在故障。需要检查芯片的硬件和软件配置是否正确,并确保芯片正常工作。 综上所述,当STM32SPI通信接收到0xFFFF时,需要仔细检查SPI配置、通信设置、数据长度、物理连接和芯片状态等方面的问题,以确定具体的原因并进行相应的修复。 #### 引用[.reference_title] - *1* *3* [STM32HAL库学习笔记八——SPI通信](https://blog.csdn.net/weixin_44762233/article/details/124514383)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [树莓派(主)与STM32(从)使用SPI通信(持续更新中)](https://blog.csdn.net/FuckerGod/article/details/130563431)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值