STM32 SPI通信 F407外设控制器 W25Q64

news2024/12/27 11:18:58

SPI介绍

                  SPI:串行外部设备接口 --- 通信接口
                           特点:高速同步串行全双工   --- 40MHz
                           场景:存储器   OLED   无线通信   传感器
         硬件连线:
                         SCL     时钟线     ---------------------   只能由主机提供
                        MOSI   发送线     ----------------------  主机输出从机输入    
                        MISO   接收线     ----------------------  主机输入从机输出
                         CS      片选线     ----------------------  开始/停止信号

SPI通信

                特点:

                         数据位:  8 /16位          //取决于从器件支持
                         MSB 在前/LSB 在前      //取决于从器件支持

           传输过程:

                         1、MCU选中芯片       //拉低片选
                         2、传输数据 
                         3、MCU释放芯片     //拉高片选
                         即 数据帧  :    片选拉低  +  数据位  +  片选拉高

SPI模式

                  SPI有四种标准模式,其主要区别体现:
                                什么时候输出数据,什么时候采样数据

 不同模式由以下两个参数决定:

           时钟极性CPOL:在空闲状态是,SCK的默认电平

           时钟相位CPHA:决定数据在哪个边沿采样 //可以理解为时钟格式

           CPHA = 0      时钟线的第一个跳变沿数据线可以采样

           CPHA = 1      时钟线的第二个跳变沿数据线可以采样

     两位参数可以组成4种模式,常用的是0模式和3模式

           SPI通信传输,双方必须在相同模式

以主机视角:         

        边沿输出数据:即将发送移位寄存器的最高位的数据输出ODR

        边沿采样数据:即将读取IDR数据移到接收移位寄存器的最低位

        以下为模式0的时序图,进行分析

                数据的第一个位bit1在第一个上升沿之前,即SCK在低电平时

                就已经将bit1的数据输出到ODR

                接下来的时序
                   上升沿到来,读取数据
                   下降沿到来,输出数据

SPI外设       

以下为STM32F4系列的SPI资源

图源《野火科技》

SPI数据

SPI发送数据和接收数据的规则:

                   发送一个位数据一定会接收到一位数据

                   接收一个位数据之前一定要发送一位数据     //必须主机主动发送数据

                          所以,发送函数和接收函数要写成一个函数.

       注意:

              要发送有意义的数据,同时会接受到无意义的数据,接收数据不用理会

              要接受有意义的数据,同时需要发送无意义的数据,发送数据随意即可

        

 SPI代码


/***************************************
*函数名            :spi1_init
*函数功能        :spi所用IO口初始化配置函数
*函数参数        :无
*函数返回值    :无
*函数描述        :SCK------PA5  复用输出
                            MOSI-----PA7  复用推挽输出
                            MISO-----PA6  复用输入
****************************************/
void spi1_init(void)
{
    /*IO口配置*/
    //端口时钟使能
    RCC->AHB1ENR |= (1<<0);
    //端口模式配置
    GPIOA->MODER &= ~((3<<10) | (3<<14) | (3<<12));
    GPIOA->MODER |= ((2<<10) | (2<<14) | (2<<12));
    //端口输出类型
    GPIOA->OTYPER &= ~((1<<5) | (1<<7));
    //端口输出速度
    GPIOA->OSPEEDR &= ~((3<<10) | (3<<14));
    GPIOA->OSPEEDR |= ((2<<10) | (2<<14));
    //无上下拉
    GPIOA->PUPDR &= ~((3<<10) | (3<<14) | (3<<12));
    //SPI1与IO口复用关系
    GPIOA->AFR[0] &= ~((0xf<<20) | (0xf<<24) | (0xf<<28));
    GPIOA->AFR[0] |= ((5<<20) | (5<<24) |(5<<28));
    
    /*SPI控制器配置*/
    //SPI1时钟使能
    RCC->APB2ENR |= (1<<12);
    //CR1
    SPI1->CR1 &= ~(1<<15);           //双线单向
    SPI1->CR1 &= ~(1<<11);           //使用8位数据格式
    SPI1->CR1 &= ~(1<<10);           //全双工模式
    SPI1->CR1 |= (1<<9);                //SSM置1 软件片选(NSS)控制 
    SPI1->CR1 |= (1<<8);                //SSI置1 禁止软件从设备,即做主机
    SPI1->CR1 &= ~(1<<7);            //MSB高位先行
    SPI1->CR1 &= ~(7<<3);            //2分频
    SPI1->CR1 |= (1<<2);                //主机模式
    SPI1->CR1 &= ~(1<<1);            //CPOL=0    空闲状态下, SCK保持低电平
    SPI1->CR1 &= ~(1<<0);            //CPHA=0    数据采集从第一个时钟边沿开始采样
    //CR2
    SPI1->CR2 &= ~(1<<4);            //使用Motorrla模式
    
    //使能SPI
    SPI1->CR1 |= (1<<6);
}

/***************************************
*函数名            :spi1_byte
*函数功能        :spi1收发一字节函数
*函数参数        :u8 data
*函数返回值    :u8
*函数描述        :0,0模式
****************************************/
u8 spi1_byte(u8 data)
{
    u8 val;
    //等待之前的数据发送完成
    while(!(SPI1->SR & (1<<1)));
    //把要发送的数据给数据寄存器
    SPI1->DR = data;
    //等待接收数据完成
    while(!(SPI1->SR & (1<<0)));
    //把数据寄存器的值给到一个变量
    val = SPI1->DR;
    
    return val;
}
 

W25Q64介绍               

                W25Q64是一款Flash类型存储芯片.
                内存大小64Mbit ==8Mbyte
                通信接口是标准SPI, 支持 (0,0)   和   (1,1) 模式    MSB
                手动擦除数据(写数据前要擦除空间)
                不允许跨页写

存储结构:
                存储空间是8M字节
                内存区域划分:  块   扇区   页
                块  :一共有128块,每块有16扇区 
                扇区:一个扇区有16页
                页  :一页有256byte

写入地址: 
               十六进制:   0~0x7F F F FF 范围
               ​​​​​ 某块某扇区某页某个字节
                 XX          X             X            XX
    如写入  0x12 3 4 56   即18号块的3号扇区的4号页的86号字节

W25Q64框图

W25Q64指令

                        0x06        写使能

                        0x05        读控制及状态寄存器

                        0x01        写控制及状态寄存器

                        0x02        页写操作

                        0x03        连续读数据操作
                        0x20        扇区擦除

                        0xD8        块区擦除

                        0xC7        芯片擦除

            

W25Q64页写

                      根据以上指令结合W25Q64手册说明,即可封装相应的函数
                      以下为对W25Q64的页写函数
                      其中写使能和等待写周期完成函数的如何编写可以通过手册查看


/***************************************
*函数名            :w25q64_page_write
*函数功能        :页写功能
*函数参数        :u32 inner_addr        要写入的起始地址
                            u16 len                        写入数据的长度
                            u8 *data                    要写人数据的首地址
*函数返回值    :无
*函数描述        :0x02
****************************************/
void w25q64_page_write(u32 inner_addr,u16 len,u8 *data)
{
    write_enable();                //写使能
    
    //片选拉低
    W25Q64_CS_L;
    
    spi1_byte(0x02);                //发送指令
    
    //发送地址
    spi1_byte((u8)(inner_addr>>16));
    spi1_byte((u8)(inner_addr>>8));
    spi1_byte((u8)(inner_addr));
    
    //循环发送数据
    while(len)
    {
        spi1_byte(*data);
        data++;
        len--;
    }

    //片选拉高
    W25Q64_CS_H;
    
    //等待写入完成
    wait_busy();            //等待BUSY位清零
    
}

       通过页写函数,还可以封装成自由连续写函数
       其算法和前篇《STM32 IIC通信 开漏模式 & AT24C02》 AT24C02连续写函数相同

              

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

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

相关文章

docker安装elasticsearch(es)+kibana

目录 docker安装elasticsearch 一.准备工作 1.打开docker目录 2.创建elasticsearch目录 3.打开elasticsearch目录 4.拉取elasticsearch镜像 5.检查镜像 二.挂载目录 1.创建数据挂载目录 2.创建配置挂载目录 3.创建插件挂载目录 4.权限授权 三.编辑配置 1.打开con…

优先算法1--双指针

“一念既出&#xff0c;万山无阻。”加油陌生人&#xff01; 目录 1.双指针--移动零 2.双指针-复写零 ok&#xff0c;首先在学习之前&#xff0c;为了方便大家后面的学习&#xff0c;我们这里需要补充一个知识点&#xff0c;我这里所谓的指针&#xff0c;不是之前学习的带有…

RISC-V笔记——语法依赖

1. 前言 Memory consistency model定义了使用Shared memory(共享内存)执行多线程(Multithread)程序所允许的行为规范。RISC-V使用的内存模型是RVWMO(RISC-V Weak Memory Ordering)&#xff0c;该模型旨在为架构师提供更高的灵活性&#xff0c;以构建高性能可拓展的设计&#x…

51单片机的土壤湿度检测控制系统【proteus仿真+程序+报告+原理图+演示视频】

1、主要功能 该系统由AT89C51/STC89C52单片机LCD1602显示模块土壤湿度传感器继电器按键、蜂鸣器、LED等模块构成。适用于智能浇花浇水系统、花卉灌溉系统等相似项目。 可实现功能: 1、LCD1602实时显示土壤湿度 2、土壤湿度传感器&#xff08;滑动变阻器模拟&#xff09;采集…

鸿蒙--商品列表

这里主要利用的是 List 组件 相关概念 Scroll:可滚动的容器组件,当子组件的布局尺寸超过父组件的视口时,内容可以滚动。List:列表包

gitlab保护分支设置

版本&#xff1a;gitlab10.2.2 一旦设置master分支被保护&#xff0c;除了管理员之外的任何用户都无法直接向master提交代码&#xff0c;只要提交代码就会报错 # git push -u origin master Total 0 (delta 0), reused 0 (delta 0) remote: GitLab: You are not allowed to pu…

前端优化,解决页面加载慢

问题&#xff1a;vue项目使用vite打包后&#xff0c;部署在nginx服务器上&#xff0c;页面上访问时很慢&#xff0c;发现有个js文件很大导致加载很慢 先说结论&#xff1a; 方式时间未优化前21s开启压缩&#xff08;6级&#xff09;6s去掉大依赖&#xff08;flowable&#xf…

【CTF-SHOW】 web入门 web11-域名隐藏信息 【详-域名】

这道题的主要思路是通过DNS查询&#xff08;或利用题目中所给的网址直接查询&#xff09;指定域名解析以获得txt记录 1.什么是域名&#xff1f; 域名&#xff08;Domain Name&#xff09; 是互联网上用来标识网站或网络服务的名字&#xff0c;它是一个人类易于记忆和使用的地…

InfluxDB快速掌握

文章目录 1、InfluxDB简介2、InfluxDB数据结构3、InfluxDB存储架构4、InfluxDB基本操作1_数据库操作2_数据表操作3_数据保存策略4_数据查询操作 5、存储引擎6、总结 1、InfluxDB简介 时序数据库是近几年一个特殊的概念&#xff0c;与传统的Mysql关系型数据库相比&#xff0c;它…

算法:560.和为k的子数组

题目 链接:leetcode链接 思路分析&#xff08;前缀和&#xff09; 注意&#xff1a;我们前面讲过滑动窗口可以处理子数组、子串等问题&#xff0c; 但是在这道题目里面注意数据范围 -1000 < nums[i] < 1000 nums[i]可正可负&#xff0c;区间的和没有单调性&#xff0c;使…

Python案例 |地图绘制及分级着色

1、分级着色地图 分级着色地图常用于可视化地理数据&#xff0c;比如人口密度、经济数据、气候变化等。其原理是使用颜色或阴影的渐变来表示不同区域(如国家、省份、城市等)中的数据差异。例如&#xff0c;地图上的每个区域根据其代表的数值被着色&#xff0c;通常数值越大&am…

React Leaflet + React Pixi:双倍的快乐,我全都要

一篇实用性的文章&#xff0c;记录一下最近在自娱自乐使用 Leaflet 和 PixiJS 的过程中整的一个有意思的活&#xff0c;帮助我们使用 React 声明式的语法在 Leaflet 的图层上使用 PixiJS 绘图。 如果你对这些库和它们的用途都已有所了解&#xff0c;只想直接看代码的话&#xf…

今日指数项目day8实战权限管理功能(下)

3.4 权限添加按钮 1&#xff09;原型效果 2&#xff09;接口说明 功能描述&#xff1a; 权限添加按钮 服务路径&#xff1a; /api/permission 服务方法&#xff1a;Post请求参数格式: {"type":"1", //菜单等级 0 顶级目录 1.目录 2 菜单 3 按钮"t…

牛筋面,一口就爱上的神仙美食

宝子们&#x1f44b;&#xff0c;今天我一定要给大家种草一款超级好吃的美食 —— 食家巷牛筋面&#x1f60b;。&#x1f380;牛筋面真的是一种神奇的存在✨。它的口感 Q 弹有嚼劲&#xff0c;就像在你的嘴巴里跳舞一样&#x1f483;。每一根面条都裹满了浓郁的酱汁&#xff0c…

原生mybatis框架引入mybatisplus,调用接口时找不到原生Mapper自带的默认方法

1.yaml配置文件和Mapper注解基本上可以不用关注&#xff0c;因为mybatis能用就证明这俩多半是没有问题的 2.再看看是不是映射出了问题&#xff0c;像Namespace的空间包名和Mapper没有对上之类的 这个框架的问题是出在配置mybatis的config文件当中&#xff0c;原本的config文件用…

Unity 从零开始搭建一套简单易用的UGUI小框架 扩展与优化篇(完结)

一个通用的UGUI小框架就算是写完了&#xff0c;下面是一步步的思考与优化过程 Unity 从零开始搭建一套简单易用的UGUI小框架 基础分析篇-CSDN博客 Unity 从零开始搭建一套简单易用的UGUI小框架 功能撰写与优化篇-CSDN博客 从使用者的角度来整理一下可能会发出的疑问 0. Panel…

【微服务】springboot远程docker进行debug调试使用详解

目录 一、前言 二、线上问题常用解决方案 2.1 微服务线上运行中常见的问题 2.2 微服务线上问题解决方案 2.3 远程debug概述 2.3.1 远程debug原理 2.3.2 远程debug优势 三、实验环境准备 3.1 搭建springboot工程 3.1.1 工程结构 3.1.2 引入基础依赖 3.1.3 添加配置文…

YOLO11改进 | 注意力机制| 对小目标友好的BiFormer【CVPR2023】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 本文介绍了一种新颖的动态稀疏注意力机制…

C++,STL 029(24.10.13)

内容 一道练习题。 &#xff08;涉及string&#xff0c;vector&#xff0c;deque&#xff0c;sort&#xff09; 题目&#xff08;大致&#xff09; 有五名选手ABCDE&#xff0c;10个评委分别对每一个选手打分&#xff0c;去除最高分和最低分&#xff0c;取平均分。 思路&…

bat脚本banenr

飞出个未来班得 echo off echo .-. echo ( ) echo - echo J L echo ^| ^| echo J L echo ^| ^| echo J L echo …