Stm32通过SPI读写W25QXX

news2024/9/21 20:33:54
  1. Printf的重定向

因为printf是c++中的库函数,要使用printf输出到串口,需要重定向,将printf定向到HAL_UART_Transmit。

新建一个retarget.c文件。

#include "stdio.h"

#include "stm32f1xx_hal.h"

#include "usart.h"

#pragma import(__use_no_semihosting_swi)

#pragma import(__use_no_semihosting)

void _sys_exit(int x) {

    x = x;

}

struct __FILE  {

    int handle;

    /* Whatever you require here. If the only file you are using is */

    /* standard output using printf() for debugging, no file handling */

    /* is required. */

};

/* FILE is typedef’ d in stdio.h. */

FILE __stdout;

void _ttywrch(int ch){};

   

int fputc(int ch, FILE *f)

{

    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);

    return ch;

}

网上找的代码或多或少运行不起来,搞了好久才调通,以上是调通后的代码,几乎只要是调试keil的工程都需要用到。可以保存下来重复使用。

  1. delay微秒

delay是一个延时函数。Stm32的HAL库提供了一个HAL_Delay的函数,但是只能延时毫秒。延时微秒,需要根据stm32的系统时钟计算,网上一大堆,但貌似或多或少有点问题,不能拿来即用。

新建一个delay.c和delay.h的文件。

#include "delay.h"

//仿原子延时,不进入systic中断

void delay_us(uint32_t nus)

{

 uint32_t temp;

 SysTick->LOAD = 9*nus;

 SysTick->VAL=0X00;//清空计数器

 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源

 do

 {

  temp=SysTick->CTRL;//读取当前倒计数值

 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达

     SysTick->CTRL=0x00; //关闭计数器

    SysTick->VAL =0X00; //清空计数器

}

void delay_ms(uint16_t nms)

{

 uint32_t temp;

 SysTick->LOAD = 9000*nms;

 SysTick->VAL=0X00;//清空计数器

 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源

 do

 {

  temp=SysTick->CTRL;//读取当前倒计数值

 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达

    SysTick->CTRL=0x00; //关闭计数器

    SysTick->VAL =0X00; //清空计数器

}

#include "stm32f1xx_hal.h"

或者直接#include main.h,规范一点

void delay_us(uint32_t nus);

之后,在main.c中引用delay.h就可以调用delay_us函数。

  1. 遇到的问题

1.编译报错

w25qxx.c(69): error:  #20: identifier "SPI_I2S_FLAG_TXE" is undefined

解:SPI_I2S_FLAG_TXE这个寄存器没有定义。网上使用的都是这个寄存器,但是在spi的库函数里找不到这个。看了半天,找到一个SPI_FLAG_TXE,改成这个就可以了。可能是时间长了,库函数里的变量名改了。

2. .\spi.axf: Error: L6218E: Undefined symbol SPI_I2S_GetFlagStatus (referred from w25qxx.o).

解:原理如上个问题,修改为

HAL_SPI_GetState(&hspi2) == HAL_SPI_STATE_BUSY_TX

3. STM32关于我遇到的HardFault_Handler的处理_warning:hardfault handler-CSDN博客

调了一个下午,发现是内存泄漏,数组访问越界的问题,也是醉了。

4. 软件SPI和硬件SPI的区别

软件SPI:用IO模拟SPI时序,这个模拟过程全部是CPU在负责执行,为了其稳定的存取数据,你可能会插入软件延时,这个时间在读取数据量不大的情况下并不明显,但是基本上你在读取过程中,其他非中断非异常程序是无法得到执行。

硬件SPI:首先这个数据存道储的过程是不需要CPU参与得,程序中配置好SPI的访问时序,开启中断,CPU就可以在中断函数中搬移数据,省下了软件模拟IO得存取时间。

仔细研究就会发现,CPU在进行SPI中断服务程序还版是需要耽误时间得,这个过程在大数据量传输中还是很耗时,ARM中Cortex-M3内核得处理器在硬件SPI上加入了DMA,这个DMA直接从SPI的数据寄存器,软件配置好DMA之后,基本上整个传输都不要权CPU参与,软件设计得好的话,整个数据传输都不要CPU参与。

W25Qxx------------(硬件SPI)_硬件spi和软件spi区别-CSDN博客

5.W25QXX上的端口容易接反。

D0--------MISO---------PA6--------PB15

D1--------MOSI---------PA7--------PB14

6.SPI1和SPI2的区别

SPI2需要复用引脚,重映射。Cubemx里面生成代码会配置好,如果用标准库去写,需要自己配置重映射。

7.硬SPI和软SPI的区别

硬SPI可以不用配置CS/NSS管脚,软SPI就是自己重新配置CS管脚,使其达到控制片选的功能,硬SPI利用终断或DMA传输数据,还没试过。

8.SPI中参数配置

hspi1.Instance = SPI1;

  hspi1.Init.Mode = SPI_MODE_MASTER;

  hspi1.Init.Direction = SPI_DIRECTION_2LINES;

  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;

  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;

  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;

  hspi1.Init.NSS = SPI_NSS_SOFT;

  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;

  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

  hspi1.Init.CRCPolynomial = 10;

SPI_POLARITY_LOW--------对应上文的CLK极性0.

SPI_PHASE_1EDGE---------对应上文的CLK相位0

所以SPI工作在模式1(总共4个模式,上升沿采集数据,下降沿发送数据)

SPI_NSS_SOFT----------软SPI

SPI_BAUDRATEPRESCALER_128-----------128分频,在cubemx配置里面会显示对应多少赫兹

  1. 调试成功,纪念一下

完成

STM32CubeMX学习笔记(10)——SPI接口使用(读写SPI Flash W25Q64)_stm32cubemx配置spi-CSDN博客

  1. 继续封装SPI收发数据成W25Q64收发数据

网上代码一般比较标准,按照教程来操作即可,无需太多改动。已经标准化的东西,拿来用用,理解一下原理就好,加深印象。

7、单片机与W25Q128(FLASH)的通讯(SPI)实验(STM32F407)_f407 w25q-CSDN博客

6.GPIO的8种模式理解

开漏输出(open drain)与推挽输出(push pull)学习详解及某个踩到的坑分享-CSDN博客

STM32CUBEMX配置教程(三)通用GPIO配置_stm32cubemx怎么设置gpio精准输出-CSDN博客

STM32的GPIO端口配置八种模式的理解_stm32的gpio的配置模式有哪几种-CSDN博客

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

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

相关文章

创意无限,尽在掌握:热门视频剪辑软件一览

我们记录生活、分享故事、传播信息用视频的频率越来越高了。而这些视频往往都是通过剪辑之后才能展示出当前的效果。那这次我们就来探索剪辑视频的时候都会用到什么工具吧。 1.福昕视频剪辑 连接直达>>https://www.pdf365.cn/foxit-clip/ 这是一款专为追求高效与创意…

Pytorch 张量运算函数(补充)

mean() mean()函数是进行张量均值计算的函数,常用参数可以设置参数dim来进行对应维度的均值计算 以下是使用一个二维张量进行演示的例子 import numpy as np import torch device torch.device(mps if torch.backends.mps.is_available() else cpu) print(device ) data1 …

【数据管理】数据治理

目录 1、相关概念 2、数据治理和管理职责语境关系图 3、业务驱动因素 4、目标和原则 5、 数据治理和数据管理的关系 6、数据治理组织 7、数据管理职能 8、数据制度 9、数据资产估值 1、相关概念 1&#xff09;战略(Stategy)&#xff1a;定义、交流和驱动数据战略和数…

[数据集][目标检测]电力场景输电线异物检测数据集VOC+YOLO格式2060张1类别

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

电脑丢失dll文件一键修复之dll确实损坏影响电脑运行

在使用电脑过程中&#xff0c;DLL文件丢失或损坏是一个常见的问题&#xff0c;它可能导致程序无法正常运行&#xff0c;甚至影响整个系统的稳定性。本文将详细介绍如何一键修复丢失的DLL文件&#xff0c;探讨常见的DLL丢失报错原因&#xff0c;并提供详细的修复步骤和预防措施。…

sklearn回归树

说明&#xff1a;内容来自菜菜的sklearn机器学习和ai生成 回归树 调用对象的参数 class sklearn.tree.DecisionTreeRegressor (criterion’mse’, splitter’best’, max_depthNone, min_samples_split2, min_samples_leaf1, min_weight_fraction_leaf0.0, max_featuresNone…

大数据基础:数仓架构演变

文章目录 数仓架构演变 一、传统离线大数据架构 二、​​​​​​Lambda架构 三、Kappa架构 四、​​​​​​​​​​​​​​混合架构 五、湖仓一体架构 六、流批一体架构 数仓架构演变 20世纪70年代&#xff0c;MIT(麻省理工)的研究员致力于研究一种优化的技术架构&…

Linux shell编程学习笔记75:sed命令——沧海横流任我行(下)

0 前言 在 Linux shell编程学习笔记73&#xff1a;sed命令——沧海横流任我行&#xff08;上&#xff09;-CSDN博客文章浏览阅读684次&#xff0c;点赞32次&#xff0c;收藏24次。在大数据时代&#xff0c;我们要面对大量数据&#xff0c;有时需要对数据进行替换、删除、新增、…

OpenCV几何图像变换(9)仿射变换函数warpAffine()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 函数是应用一个仿射变换到图像上。 warpAffine 函数使用指定的矩阵对源图像进行仿射变换&#xff1a; dst ( x , y ) src ( M 11 x M 12 y M…

Elasticsearch:使用 ELSER 进行语义搜索 - sparse_vector

Elastic Learned Sparse EncodeR&#xff08;或 ELSER&#xff09;是由 Elastic 训练的 NLP 模型&#xff0c;可让你使用稀疏向量表示执行语义搜索。语义搜索不是根据搜索词进行文字匹配&#xff0c;而是根据搜索查询的意图和上下文含义检索结果。 本教程中的说明向你展示了如…

[医疗 AI ] 3D TransUNet:通过 Vision Transformer 推进医学图像分割

[医疗 AI ] 3D TransUNet&#xff1a;通过 Vision Transformer 推进医学图像分割’ 论文地址 - https://arxiv.org/pdf/2310.07781 0. 摘要 医学图像分割在推进医疗保健系统的疾病诊断和治疗计划中起着至关重要的作用。U 形架构&#xff0c;俗称 U-Net&#xff0c;已被证明在…

提高实时多媒体传输效率的三大方法

实时多媒体数据传输面临的挑战 实时多媒体数据的传输具有数据量巨大、对时延和时延抖动高度敏感及能容忍丢分组的特点。然而&#xff0c;当今互联网的网络层协议提供的仅是一种“尽最大努力服务”&#xff0c;对分组的端到端时延、时延抖动和分组丢失率等指标不做任何承诺。这…

MySQL的延迟复制

目录 1 MySQL 延迟复制介绍 1.1 延迟复制语法&#xff1a; 1.2 延迟复制可用于多种用途&#xff1a; 1.3 延迟复制的有关的参数 1.4 延迟复制的操作 2 MySQL 延迟复制 实操 2.1 实验环境 2.2 对 SLAVE --MySQL-3 进行延迟复制操作 2.3 停止相关进程的原因 2.4 实验测试 2.5 动…

Variomes:支持基因组变异筛选的高召回率搜索引擎

《Bioinformatics》2022 Variomes&#xff1a; https://candy.hesge.ch/Variomes Source code&#xff1a; https://github.com/variomes/sibtm-variomes SynVar&#xff1a; https://goldorak.hesge.ch/synvar 文章摘要&#xff08;Abstract&#xff09; 动机&#xff08;Mot…

读软件开发安全之道:概念、设计与实施07密码学(上)

1. 加密工具 1.1. 加密工具之所以没有得到充分使用&#xff0c;就是因为人们往往认为密码学是一个准入门槛极高的专业领域 1.2. 如今的加密学大部分都源自纯数学&#xff0c;所以只要能够正确使用&#xff0c;加密学确实行之有效 1.2.1. 不代表这些算法本身确实无法破解&…

机器学习 | 基于wine数据集的KMeans聚类和PCA降维案例

KMeans聚类&#xff1a;K均值聚类是一种无监督的学习算法&#xff0c;它试图根据数据的相似性对数据进行聚类。无监督学习意味着不需要预测结果&#xff0c;算法只是试图在数据中找到模式。在k均值聚类中&#xff0c;我们指定希望将数据分组到的聚类数。该算法将每个观察随机分…

四大消息队列:Kafka、ActiveMQ、RabbitMQ、RocketMQ对比

四大消息队列&#xff1a;Kafka、ActiveMQ、RabbitMQ、RocketMQ对比 1. 社区活跃度2. 持久化消息3. 技术实现4. 高并发性能5. RabbitMQ与Kafka对比 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在软件开发中&#xff0c;消息队列&#xf…

【Redis】Redis数据结构——Hash 哈希

哈希 命令hsethgethexistshdelhkeyshvalshgetallhmgethlenhsetnxhincrbyhincrbyfloat命令小结 内部编码使用场景缓存⽅式对⽐ ⼏乎所有的主流编程语⾔都提供了哈希&#xff08;hash&#xff09;类型&#xff0c;它们的叫法可能是哈希、字典、关联数组、映射。在 Redis 中&#…

Python furl库:一键搞定复杂URL操作

更多Python学习内容&#xff1a;ipengtao.com 在Web开发和数据处理的过程中&#xff0c;URL的解析、修改和构建是不可避免的操作。然而&#xff0c;直接操作URL字符串不仅繁琐&#xff0c;而且容易出错。Python的furl库提供了一种简单且强大的方法来处理URL&#xff0c;使得URL…

简易的 Websocket + 心跳机制 + 尝试重连

文章目录 演示大纲基础 WebSocket前端: 添加心跳机制前端: 尝试重新连接历史代码 还没有写完&#xff0c;bug 是有的&#xff0c;我在想解决办法了… 演示 大纲 基础的 webSocket 连接前后端&#xff1a;添加心跳机制后端无心跳反应&#xff0c;前端尝试重新连接设置重新连接…