W25Q32驱动 基于HAL库的SPI

2024-09-04 00:28
文章标签 驱动 hal spi w25q32

本文主要是介绍W25Q32驱动 基于HAL库的SPI,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

环境

芯片:STM32F103ZET6
库:来自HAL的STM32F1XX.H

原理图

cubeMX配置

W25Q32.h

//
// Created by seven on 2024/9/2.
//#ifndef SPI_W25Q32_H
#define SPI_W25Q32_H
#include "spi.h"/*** 初始化W25Q32闪存芯片*/
void W25Q32_Init(void);/*** 停止W25Q32闪存芯片的操作*/
void w25q32_Stop(void);/*** 读取W25Q32闪存芯片的ID* @param sid 存储制造商ID的指针* @param mid 存储设备ID的指针*/
void W25Q32_ReadId(uint8_t *sid,uint16_t *mid);/*** 等待W25Q32闪存芯片不忙* 原理是发送05h指令,循环读取状态寄存器(8位),直到第0位变为0,表示芯片不忙*/
void Inf_W25Q32_WaitNotBusy(void);/*** 使能W25Q32闪存芯片的写操作*/
void Inf_W25Q32_WriteEnable(void);/*** 禁止W25Q32闪存芯片的写操作*/
void Inf_W25Q32_WriteDisable(void);/*** 擦除W25Q32闪存芯片的指定扇区* @param block 块地址* @param sector 扇区地址*/
void Inf_W25Q32_SectorErase(uint8_t block,uint8_t sector);/*** 向W25Q32闪存芯片的指定页面写入数据* @param block 块地址* @param sector 扇区地址* @param page 页面地址* @param data 写入的数据缓冲区指针* @param len 写入的数据长度*/
void Inf_W25Q32_PageProgram(uint8_t block,uint8_t sector,uint8_t page,uint8_t data[],uint8_t len);/*** 从W25Q32闪存芯片的指定位置读取数据* @param block 块地址* @param sector 扇区地址* @param page 页面地址* @param buff 存储读取数据的缓冲区指针* @param len 读取的数据长度*/
void Inf_W25Q32_ReadData(uint8_t block,uint8_t sector,uint8_t page,uint8_t buff[],uint8_t len);
#endif //SPI_W25Q32_H

W25Q32.c

//
// Created by seven on 2024/9/2.
//#include "W25Q32.h"
void W25Q32_Init(void){MX_SPI1_Init();}
void w25q32_Stop(void){SPI_Stop();
}
void W25Q32_ReadId(uint8_t *sid,uint16_t *mid){// 1. 片选启动SPI_Start();// 2. 发送指令SPI_SwapByte(0x9f);// 3. 接收id// 3.1 首先接收制造商id*sid = SPI_SwapByte(0xff);// 3.2 接收设备id*mid = SPI_SwapByte(0xff) << 8;*mid |= SPI_SwapByte(0xff) << 0;// 4. 片选关闭SPI_Stop();
}// 等待忙状态
// 原理是调用05h指令  可以循环读取8位的状态寄存器  -> 第0位表示忙状态
// 当第0位变为0的时候表示它不忙
void Inf_W25Q32_WaitNotBusy(void){SPI_Start();SPI_SwapByte(0x05);while(SPI_SwapByte(0xff) & 0x01){}SPI_Stop();
}
// 打开写使能
void Inf_W25Q32_WriteEnable(void){SPI_Start();SPI_SwapByte(0x06);SPI_Stop();
}
// 关闭写使能
void Inf_W25Q32_WriteDisable(void){SPI_Start();SPI_SwapByte(0x04);SPI_Stop();
}
// 擦除方法
void Inf_W25Q32_SectorErase(uint8_t block,uint8_t sector){Inf_W25Q32_WaitNotBusy();Inf_W25Q32_WriteEnable();SPI_Start();SPI_SwapByte(0x20);uint32_t address = (block << 16) | (sector << 8);SPI_SwapByte(address >> 16);SPI_SwapByte(address >> 8);SPI_SwapByte(address >> 0);SPI_Stop();Inf_W25Q32_WriteDisable();
}
// 写入数据
void Inf_W25Q32_PageProgram(uint8_t block,uint8_t sector,uint8_t page,uint8_t data[],uint8_t len){Inf_W25Q32_WaitNotBusy();Inf_W25Q32_WriteEnable();SPI_Start();SPI_SwapByte(0x02);uint32_t address = (block << 16) | (sector << 8) | (page << 0);SPI_SwapByte(address >> 16);SPI_SwapByte(address >> 8);SPI_SwapByte(address >> 0);for(int i = 0; i < len; i++){SPI_SwapByte(data[i]);}SPI_Stop();Inf_W25Q32_WriteDisable();}
// 读数据 -> 不需要使能  但需要等待忙状态
void Inf_W25Q32_ReadData(uint8_t block,uint8_t sector,uint8_t page,uint8_t buff[],uint8_t len){Inf_W25Q32_WaitNotBusy();SPI_Start();SPI_SwapByte(0x03);uint32_t address = (block << 16) | (sector << 8) | (page << 0);SPI_SwapByte(address >> 16);SPI_SwapByte(address >> 8);SPI_SwapByte(address >> 0);for(int i = 0; i < len; i++){buff[i] = SPI_SwapByte(0xff);}SPI_Stop();
}

基于官方HAL库spi额外添加的函数

 在spi.c

/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

内添加下面代码

/*** @brief SPI通信启动函数** 该函数通过将片选(CS)信号置低来启动SPI通信。*/
void SPI_Start(void)
{// 将CS(片选)信号置低,启动SPI通信HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
}/*** @brief SPI通信停止函数** 该函数通过将片选(CS)信号置高来结束SPI通信。*/
void SPI_Stop(void)
{// 将CS(片选)信号置高,结束SPI通信HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
}/*** @brief SPI通信中字节交换函数** 该函数在SPI通信中交换一个字节,并返回接收到的字节。** @param byte 要发送和交换的字节* @return uint8_t 返回从SPI通信接收到的字节*/
uint8_t SPI_SwapByte(uint8_t byte)
{uint8_t rByte = 0;// 通过SPI通信发送字节并接收回应字节HAL_SPI_TransmitReceive(&hspi1, &byte, &rByte, 1, 1000);return rByte;
}

在spi.h的

/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */

内添加下面代码

// 初始化SPI通信
void SPI_Start(void);
// 停止SPI通信
void SPI_Stop(void);
// 数据位交换
// 将输入的8位数据进行位交换,例如0x01交换后变为0x80
uint8_t SPI_SwapByte(uint8_t byte);

这篇关于W25Q32驱动 基于HAL库的SPI的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1134471

相关文章

一文彻底搞懂Java 中的 SPI 是什么

《一文彻底搞懂Java中的SPI是什么》:本文主要介绍Java中的SPI是什么,本篇文章将通过经典题目、实战解析和面试官视角,帮助你从容应对“SPI”相关问题,赢得技术面试的加分项,需要的朋... 目录一、面试主题概述二、高频面试题汇总三、重点题目详解✅ 面试题1:Java 的 SPI 是什么?如何实现一个

Dubbo之SPI机制的实现原理和优势分析

《Dubbo之SPI机制的实现原理和优势分析》:本文主要介绍Dubbo之SPI机制的实现原理和优势,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Dubbo中SPI机制的实现原理和优势JDK 中的 SPI 机制解析Dubbo 中的 SPI 机制解析总结Dubbo中

如何在Ubuntu上安装NVIDIA显卡驱动? Ubuntu安装英伟达显卡驱动教程

《如何在Ubuntu上安装NVIDIA显卡驱动?Ubuntu安装英伟达显卡驱动教程》Windows系统不同,Linux系统通常不会自动安装专有显卡驱动,今天我们就来看看Ubuntu系统安装英伟达显卡... 对于使用NVIDIA显卡的Ubuntu用户来说,正确安装显卡驱动是获得最佳图形性能的关键。与Windo

嵌入式Linux之使用设备树驱动GPIO的实现方式

《嵌入式Linux之使用设备树驱动GPIO的实现方式》:本文主要介绍嵌入式Linux之使用设备树驱动GPIO的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、设备树配置1.1 添加 pinctrl 节点1.2 添加 LED 设备节点二、编写驱动程序2.1

嵌入式Linux驱动中的异步通知机制详解

《嵌入式Linux驱动中的异步通知机制详解》:本文主要介绍嵌入式Linux驱动中的异步通知机制,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、异步通知的核心概念1. 什么是异步通知2. 异步通知的关键组件二、异步通知的实现原理三、代码示例分析1. 设备结构

usb接口驱动异常问题常用解决方案

《usb接口驱动异常问题常用解决方案》当遇到USB接口驱动异常时,可以通过多种方法来解决,其中主要就包括重装USB控制器、禁用USB选择性暂停设置、更新或安装新的主板驱动等... usb接口驱动异常怎么办,USB接口驱动异常是常见问题,通常由驱动损坏、系统更新冲突、硬件故障或电源管理设置导致。以下是常用解决

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

驱动(RK3588S)第七课时:单节点设备树

目录 需求一、设备树的概念1、设备树的后缀名:2、设备树的语法格式3、设备树的属性(重要)4、设备树格式举例 二、设备树所用函数1、如何在内核层种获取设备树节点:2、从设备树上获取 gpio 口的属性3、获取节点上的属性只针对于字符串属性的4、函数读取 np 结点中的 propname 属性的值,并将读取到的 u32 类型的值保存在 out_value 指向的内存中,函数的返回值表示读取到的

STM32CubeMX和HAL库-新建项目

目录 新建项目 选择开发板  MCU图形化配置界面总览 MCU配置 新建项目 新建项目包含选择MCU创建项目、选择开发板新建项目和交叉选择MCU新建项目三部分。 1. 选择MCU创建项目 单击主菜单项File→New Project,或Home视图上的ACCESS TO MCU SELECTOR 按钮,都可以打开的New Project from a MCU/MPU对话框。