当前位置: 首页 > news >正文

【STM32-HAL】 SPI通信与Flash数据写入实战

文章目录

  • 1.参考教程
  • 2. 4种时间模式
  • 3. 3个编程接口
    • 3.1 `HAL_StatusTypeDef HAL_SPI_Transmit(...)` :
      • 3.1.1 参数说明
      • 3.1.2 例子
    • 3.2 `HAL_StatusTypeDef HAL_SPI_Receive(...)` :
      • 3.2.1参数说明
      • 3.2.2 例子
    • 3.3 `HAL_StatusTypeDef HAL_SPI_TransmitReceive(...)` :
      • 3.3.1 参数说明
      • 3.3.2 例子
  • 4. spi应用-flash数据写入
    • 4.1 flash数据写入过程
    • 4.2 流程
    • 5. 流程实现
      • 5.1 写使能
      • 5.2 扇区擦除
      • 5.3 页编程
    • 6. 代码实现
  • 5. spi应用-flash数据加载
    • 5.1 流程
    • 5.2 代码实现

1.参考教程

[STM32 HAL库][SPI]外部flash实验
[STM32 HAL库][SPI]外部flash数据存取

2. 4种时间模式

在这里插入图片描述

3. 3个编程接口

3.1 HAL_StatusTypeDef HAL_SPI_Transmit(...)

用于通过 SPI 总线发送数据,返回 HAL_StatusTypeDef 类型状态值 ,作用为“发送”。

HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi,uint8_t *pData,uint16_t Size,uint32_t Timeout)

3.1.1 参数说明

参数名说明
hspi填写 SPI 句柄的指针
pData填写要发送的数据
Size填写要发送的数据的数量,以字节为单位
Timeout超时时间,单位是 ms;HAL_MAX_DELAY 表示无限长的超时时间

3.1.2 例子

在这里插入图片描述

  • 通信场景:主机(单片机)向从机1发送数据 0x5a, 0x33
  • 硬件连接:涉及主机与从机的 MOSI(主机输出从机输入)、MISO(主机输入从机输出 ,从机1此处未动作 )、SCK(时钟 )、NSS(从机选择 ,NSS1 选中从机1 )引脚
  • 代码逻辑
    • 定义发送数据数组 uint8_t dataToSend[] = {0x5a, 0x33};
    • 通过 HAL_GPIO_WritePin 函数拉低引脚选中从机1
    • 调用 HAL_SPI_Transmit 函数发送数据
    • 数据发送后,通过 HAL_GPIO_WritePin 函数拉高引脚取消选中从机1

3.2 HAL_StatusTypeDef HAL_SPI_Receive(...)

用于通过 SPI 总线接收数据,返回 HAL_StatusTypeDef 类型状态值 ,作用为“接收”。

HAL_StatusTypeDef HAL_SPI_Receive(&hspi1, uint8_t *pData, uint16_t Size, uint32_t Timeout)

3.2.1参数说明

参数名说明
参数hspi填写SPI句柄的指针
参数pData填写接收缓冲区
参数Size填写要发送的数据的数量,以字节为单位
参数Timeout超时时间,单位是ms;HAL_MAX_DELAY表示无限长的超时时间

3.2.2 例子

在这里插入图片描述

  1. 功能描述:从从机1接收2个字节的数据
  2. 硬件连接:主机(单片机)与从机1通过MOSI、MISO、SCK、NSS1引脚连接,从机还有从机2、从机3,引脚连接逻辑同从机1
  3. 代码逻辑
    • 定义接收缓冲区 uint8_t dataRcvd[] = {0xff, 0xff};
    • 通过 HAL_GPIO_WritePin(..., GPIO_PIN_RESET); 函数拉低引脚选中从机1
    • 调用 HAL_SPI_Receive(&hspi1, dataRcvd, 2, HAL_MAX_DELAY); 函数,参数含SPI句柄 &hspi1、接收缓冲区 dataRcvd、数据长度 2(字节)、超时时间 HAL_MAX_DELAY(无限超时 )
    • 数据接收后,通过 HAL_GPIO_WritePin(..., GPIO_PIN_SET); 函数拉高引脚取消选中从机1
  4. 时序图:展示NSS1(低电平选中 )、SCK(时钟信号 )、MOSI(发送 0xff0xff 波形 )、MISO(接收 0x1f0x27 波形 )的时序关系 ,呈现SPI接收数据时各信号的变化 。

3.3 HAL_StatusTypeDef HAL_SPI_TransmitReceive(...)

用于通过 SPI 总线同时进行发送和接收数据操作,返回 HAL_StatusTypeDef 类型状态值 ,作用为“发送同时接收”。

HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)

发送数据的同时接收数据

3.3.1 参数说明

参数名说明
参数hspi填写SPI句柄的指针
参数pTxData填写要发送的数据
参数pRxData填写接收数据缓冲区
参数Size发送数据的数量=接收数据的数量,以字节为单位
参数Timeout超时时间,单位是ms

3.3.2 例子

在这里插入图片描述

  1. 功能描述:发送 {0x5a, 0x33} ,同时接收 2 个字节数据
  2. 硬件连接:主机(单片机)与从机 1 通过 MOSI(主机输出从机输入 )、MISO(主机输入从机输出 )、SCK(时钟 )、NSS1(从机选择 )引脚连接,从机还有从机 2、从机 3 ,引脚连接逻辑同从机 1
  3. 代码逻辑
    • 定义发送数据数组 uint8_t txData[] = {0x5a, 0x33};
    • 定义接收缓冲区 uint8_t rxData[2];
    • 通过 HAL_GPIO_WritePin(..., GPIO_PIN_RESET); 函数拉低引脚选中从机 1
    • 调用 HAL_SPI_TransmitReceive(&hspi1, txData, rxData, 2, HAL_MAX_DELAY); 函数,参数含 SPI 句柄 &hspi1、发送数据数组 txData、接收缓冲区 rxData、数据长度 2(字节)、超时时间 HAL_MAX_DELAY(无限超时 )
    • 数据收发后,通过 HAL_GPIO_WritePin(..., GPIO_PIN_SET); 函数拉高引脚取消选中从机 1
  4. 时序图:展示 NSS1(低电平选中 )、SCK(时钟信号 )、MOSI(发送 0x5a0x33 波形 )、MISO(接收 0x1f0x27 波形 )的时序关系 ,呈现 SPI 同时收发数据时各信号的变化 。

4. spi应用-flash数据写入

4.1 flash数据写入过程

在这里插入图片描述

4.2 流程

在这里插入图片描述

5. 流程实现

5.1 写使能

抽水机的写使能是发送0x06
在这里插入图片描述

5.2 扇区擦除

扇区擦除的指令码是0x20,所以首先发送0x20,后面接着24位的扇区首地址

在这里插入图片描述

5.3 页编程

页编程指令码是0x02,后面跟着24位地址(往哪里写地址就发谁的地址),再后面是发要写入的数据,一次性可以写多个数据
在这里插入图片描述

6. 代码实现

static void SaveLEDState(uint8_t ledState)
{// #1. 写使能uint8_t writeEnableCmd[] = {0x06};HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);HAL_SPI_Transmit(&hspi1, writeEnableCmd, 1, HAL_MAX_DELAY);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);// #2. 扇区擦除uint8_t sectorErase[] = {0x20, 0x00, 0x00, 0x00};HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);HAL_SPI_Transmit(&hspi1, sectorErase, 4, HAL_MAX_DELAY);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);HAL_Delay(100);// #3. 写使能HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);HAL_SPI_Transmit(&hspi1, writeEnableCmd, 1, HAL_MAX_DELAY);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);// #4. 页编程uint8_t pageProgCmd[5];//要发送5个字节pageProgCmd[0] = 0x02; //页编程指令码是0x02pageProgCmd[1] = 0x00; //地址pageProgCmd[2] = 0x00; //地址pageProgCmd[3] = 0x00; //地址pageProgCmd[4] = ledState; //要发送的数据HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); HAL_SPI_Transmit(&hspi1, pageProgCmd, 5, HAL_MAX_DELAY);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); HAL_Delay(10); }

在主函数写上 SaveLEDState( ledState);就可以保存灯的状态数据。

5. spi应用-flash数据加载

5.1 流程

读取数据的指令码是0x03,先发0x03,后面跟24位地址,再往后从总线上读取数据。
首先声明数组,用于存放要发送的数据。先发送读取命令,然后接收数据。最后返回读取的数据。
在这里插入图片描述

5.2 代码实现

// 函数:读取LED状态(从Flash等存储设备)
// 功能:通过SPI总线发送读命令,接收并返回存储的LED状态数据
static uint8_t LoadLEDState(void)
{// 读命令及地址:0x03为读数据指令,后三个0x00为起始地址uint8_t readDataCmd[] = {0x03, 0x00, 0x00, 0x00}; uint8_t ledState; // 用于存储读取到的LED状态数据// 选通从设备:拉低GPIOA_PIN_4(SPI从设备片选信号)HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // 通过SPI发送读命令:向从设备发送读数据指令及地址,长度4字节,无限超时等待HAL_SPI_Transmit(&hspi1, readDataCmd, 4, HAL_MAX_DELAY); // 通过SPI接收数据:从从设备接收1字节数据(LED状态),存入ledState,无限超时等待HAL_SPI_Receive(&hspi1, &ledState, 1, HAL_MAX_DELAY); // 取消选通:拉高GPIOA_PIN_4,释放从设备片选HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); return ledState; // 返回读取到的LED状态
}
http://www.dtcms.com/a/306482.html

相关文章:

  • Elasticsearch(ES)基础语法(笔记)(持续更新)
  • MySQL索引和事务笔记
  • 如何通过项目管理系统提升交付率
  • Kafka 重复消费与 API 幂等消费解决方案
  • IO复用实现并发服务器
  • 【PZ7020-StarLite 入门级开发板】——FPGA 开发的理想起点,入门与工业场景的双重优选
  • 【工具】jsDelivr CDN完全指南:免费高速的开源项目CDN服务
  • Apache Ignite 与 Spring Boot 集成
  • Linux 进程管理与计划任务设置
  • 【Dv3admin】ORM数据库无法查询的问题
  • 如何修改VM虚拟机中的ip
  • opengauss数据库安装及测试
  • 【C语言】深度剖析指针(二):指针与数组,字符,函数的深度关联
  • SpringBoot中ResponseEntity的使用详解
  • .NET报表控件ActiveReports发布v19.0——正式兼容 .NET 9
  • 动态爱心视觉特效合集(含 WebGL 与粒子动画)
  • 传输层协议UDP与TCP
  • 微算法科技MLGO突破性的监督量子分类器:纠缠辅助训练算法为量子机器学习开辟新天地
  • G9打卡——ACGAN
  • ​​咖啡艺术的数字觉醒:Deepoc具身智能如何重塑咖啡机器人的“风味直觉”
  • Android基础(二)了解Android项目
  • Android补全计划 TextView设置文字不同字体和颜色
  • SAP-ABAP:SAP ABAP OpenSQL JOIN 操作权威指南高效关联多表数据
  • android-PMS-开机流程
  • 配置国内镜像源加速Python包安装
  • 第2章 cmd命令基础:常用基础命令(3)
  • xxljob-快速上手
  • 真 万人互动MMO游戏技术公開測試
  • 推扫式和凝视型高光谱相机分别采用哪些分光方式?
  • AutoSAR(MCAL) --- ADC