W25Q32驱动 基于HAL库的SPI

news2024/9/20 12:33:00

环境

芯片: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);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2102310.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

P7492 [传智杯 #3 决赛] 序列

*原题链接* 一道类似势能线段树的题&#xff0c;区间按位或上k&#xff0c;不满足区间可合并的性质&#xff0c;只能暴力的单点修改。 但是考虑按位或的性质&#xff0c;一个数或上另一个数&#xff0c;只会变大或不变&#xff0c;如果我们能找到一个方法&#xff0c;能够判定…

Gitlab-ce upgrade 16.0.1 to 17.3.1【Gitlab-ce 16.0.1 升级 17.3.1】

文章目录 背景gitlab-ce 16.0.1 升级 17.3.1 失败gitlab-ce 16.0.1 升级 16.11.8 失败gitlab-ce 16.0.1 升级 16.7.9 失败gitlab-ce 16.0.1 升级 16.3.8 成功gitlab-ce 16.3.8 升级 16.11.8 失败gitlab-ce 16.3.8 升级 16.7.9 成功gitlab-ce 16.7.8 升级 16.11.8 成功gitlab-ce…

牛客(数字统计)

[NOIP2010]数字统计 题目题解(77)讨论(41)排行面经 new 时间限制&#xff1a;1秒 空间限制&#xff1a;128M 知识点NOIP复赛字符串 校招时部分企业笔试将禁止编程题跳出页面&#xff0c;为提前适应&#xff0c;练习时请使用在线自测&#xff0c;而非本地IDE。 描述 请统计…

【Day08】

目录 MySQL-多表查询-概述 MySQL-多表查询-内连接 MySQL-多表查询-外连接 MySQL-多表查询-[标量、列]子查询 MySQL-多表查询-[行、表]子查询 MySQL-多表查询-案例 MySQL-事务-介绍与操作 MySQL-事务-四大特性 MySQL-索引-介绍 MySQL-索引-结构 MySQL-索引-操作语法 …

【Qt】消息对话框 QMessageBox

消息对话框 QMessageBox QMessageBox 用于显示一个消息给用户&#xff0c;&#xff0c;并且让用户进行一个简单的选择。 消息对话框是应⽤程序中最常⽤的界⾯元素。消息对话框主要⽤于为⽤⼾提⽰重要信息&#xff0c;强制⽤⼾进⾏选择操作。 例子&#xff1a;创建一个消息对话…

【Datawhale X 李宏毅苹果书 AI夏令营】《深度学习详解》Task3 打卡

文章目录 前言学习目标一、优化策略二、模型偏差三、优化问题三、过拟合增加训练集给模型一些限制 四、交叉验证五、不匹配总结 前言 本文是【Datawhale X 李宏毅苹果书 AI夏令营】的Task3学习笔记打卡。 学习目标 李宏毅老师对应视频课程&#xff1a;https://www.bilibili.…

JMeter 安装使用

JMeter 安装使用 a.安装 下载链接:Apache JMeter - Download Apache JMeter 环境变量 打开 cmd 输入 jmeter&#xff0c;即可启动 b.使用 http请求接口 300 个线程设置 1 s 的预热时间 右键 start

B端:工作台页面放什么?不知道,这里告诉你10个常见内容。

工作台是B端系统的核心页面&#xff0c;也是最常用的页面&#xff0c;该页面的上通常放哪些内容了&#xff0c;是中说纷纭&#xff0c;本文把常放内容给大家列举下。 B端工作台页面是专门为企业用户设计的工作台&#xff0c;通常需要包含一些与企业工作相关的功能和信息。以下…

传知代码-让机器感受你的情绪!(论文复现)

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 让计算机理解你的情绪&#xff01; 随着近年来社交媒体的快速增长&#xff0c;社交媒体上的用户生成内容&#xff08;例如视频&#xff09;的量大幅增加。不同模态的自动情感分析有利于人机交互&#xff0c;并吸…

跟我一起学FPGA (二) 语法讲解

本章讲解 1 、Verilog 概述和基础知识&#xff1b; 2 、Verilog 程序框架和高级知识点&#xff1b; 3 、Verilog 编程规范。 1.Verilog 概述和基础知识 Verilog 是一种硬件描述语言&#xff0c;以文本形式来描述数字系统硬件的结构和行为的语言&#xff0c;用它可以表示逻辑电…

Vivado2018.3版本_将bit文件转化为bin文件

Vivado2018.3版本_将bit文件转化为bin文件 1、配置转换文件 2、下载到flash中

用 count(*)哪个存储引擎会更快?

InnoDB 引擎执行 count 函数的时候&#xff0c;需要通过遍历的方式来统计记录个数&#xff0c;而 MyISAM 引擎执行 count 函数只需要 0(1 )复杂度&#xff0c;这是因为每张 MyISAM 的数据表都有一个 meta 信息有存储了row_count值&#xff0c;由表级锁保证一致性&#xff0c;所…

[数据集][目标检测]鲜花检测数据集VOC+YOLO格式25215张106类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;25215 标注数量(xml文件个数)&#xff1a;25215 标注数量(txt文件个数)&#xff1a;25215 标…

给P人一点小小震撼!铁威马UI全新设计!更友好更美观~

开学了&#xff0c;小马居然发现有学校竟然玩起了新花样&#xff0c;通过MBTI来分宿舍&#xff0c;这脑洞大开的创意简直让人直呼内行&#xff01; 你是P人还是J人&#xff1f; 在MBTI人格分类中&#xff0c;J人喜欢条理清晰的计划&#xff0c;而P人则倾向于随性所欲。 想象…

第十五届北京青年相声节宣传片发布

第十五届北京青年相声节宣传片&#xff0c;围绕相声演员的四个基本功&#xff1a;说、学、逗、唱&#xff0c;搭建四个生活场景&#xff0c;编创四个微短故事&#xff0c;演绎四组人物关系&#xff0c;向大众普及“相声就在我们身边”的深刻内涵。

如何轻松的步入编程的第一课?相信你就是那个伟大的天才!

第一次编程&#xff0c;会让初学者感到既兴奋又有些紧张。以下是一些建议 明确学习目标&#xff1a;首先&#xff0c;思考你为什么想学编程。是为了职业发展、兴趣爱好、还是仅仅想了解新技术&#xff1f;明确的目标能帮你保持学习的动力。选择合适的编程语言&#xff1a;对于…

【持续更新】Solid Explorer premium2.8.48.200291文件管理器最新免费高级解锁版

Solid Explorer文件管理器高级版解锁&#xff0c;拥有诸多增强功能和额外特性&#xff0c;使其区别于标准版。 ▨ 解锁版主要特点 • 解锁高级功能&#xff1a;无限制地访问所有高级功能 • 无广告体验&#xff1a;享受无任何烦人广告的流畅用户界面 • 增强安全性&#xff1a…

软件性能测试重要性简析,好用的性能测试工具有哪些?

软件性能测试是软件开发和维护过程中一个至关重要的环节。通过性能测试&#xff0c;企业能够评估软件在不同负载下的表现&#xff0c;预测其在真实环境中的表现&#xff0c;以确保用户能获得优秀的使用体验。 软件性能测试可以被定义为一种评估软件系统的快速性、响应性、稳定…

【ShuQiHere】重新定义Linux桌面生态:Gnome-Pie与Touché的双剑合璧

【ShuQiHere】 从期待到失望的初体验 当我第一次拿到Logitech Master 3S鼠标时&#xff0c;心中的兴奋感油然而生。它精致的做工、独特的造型&#xff0c;以及舒适的握感&#xff0c;让我感觉它不仅是一款鼠标&#xff0c;更是一件工艺品。再加上令人期待的自定义手势功能&am…

RR隔离级别下还有幻读吗

文章目录 1 背景2 验证2.1 验证准备2.1.1 环境信息2.1.2 数据准备 2.2 当前读场景验证2.2.1 前言2.2.2 场景验证2.2.3 小结 2.3.快照读场景验证2.3.1 前言2.3.2 场景验证2.3.3 小结 3 分析4 总结 1 背景 InnoDB默认的事务隔离级别是REPEATABLE-READ&#xff0c;它为了解决该隔离…