STM32 SPI 收发数据 ---规则 + 问题解析

2023-05-16

规则:

1) 
高速同步串行口。3~4线接口(CS ,CLK ,MOSI,MISO),收发独立、可同步进行。
2)SPI分为主从模式,主模式提供时钟和片选选择信号.
3) 模式控制:CPOL用来控制时钟信号(clk)在空闲时候的状态;CPHA用来控制采样时刻时CLK的边缘动作。
CPOL CPHA 模式:
0 0 CLK空闲时为低电平,CLK上升沿采样数据。
0 1 CLK空闲为低电平,CLK下降沿采样数据。
1 0 CLK空闲时为高电平,CLK上升沿采样数据。
1 1 CLK空闲时为高电平,CLK下降沿采样数据。


1)SPI配置(3.01库):
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //双工模式
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //SPI主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8bit数据
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //CLK空闲时为高电平 
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //CLK上升沿采样,因为上升沿是第二个边沿动作,所以也可以理解为第二个边沿采样
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //片选用软件控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; //SPI频率
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前
SPI_InitStructure.SPI_CRCPolynomial = 7; //crc7,stm32spi带硬件ecc
SPI_Init(SPI1, &SPI_InitStructure);


2)CS信号:
主模式下要为从设备提供片选信号,值得注意的是STM32的主频相当较高,要提防数据没有完全发送前拉高CS信号。 


3)SPI读写:(非中断模式)
a)写一个字节:
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
//确保发生前Buffer为空,也就是说上一次已经发生完成
SPI_I2S_SendData(SPI1, Data); //往寄存器中写入一个字节
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
//等待接受到一个字节数据,为什么要这么做?加这一句的原因是为了确保这个字节已经发送出去,因为发生和接受是并行同步进行,那就是说你发生出去一个字节意味着你收到一个字节。所以这样判断完全没有问题,再说必要性,如果你不加这句你就会容易犯过早拉高CS信号的错误,你想想如果在SPI_I2S_SendData(SPI1, Data)后面立即拉高CS是什么后果。
SPI_I2S_ReceiveData(SPI1); //都会接收到的数据,看起来没什么必要,但以用stm32的经验推荐这样做,也许会有意想不到的收获。


SPI_Writebyte(u8 data)
{
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, Data); 
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); 
SPI_I2S_ReceiveData(SPI1); 
}


b)读一个字节:


读的时候要注意一个问题,因为从模式是没法提供时钟的,所以主模式下必须要在接收的同时提供时钟。办法就是发送一个字节来实现,因为还是上面说的,发送一个字节就意味着收到一个字节,代码和写完全一样,只要把读出来的字节保存即可。


u8 SPI_Readbyte(u8 data)
{ 
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, Data);    //发送与应用不相关的数据,为后续的读数据提供时钟信号
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); 
return SPI_I2S_ReceiveData(SPI1); 
}


总结:上面的程序是最求稳定而设定的,如果你对速度有要求,你可以做相应的精简,比如读写直接对寄存器进行操作,另外配置SPI前要对从模式的模式了解清楚,包括从设备支持的时钟范围和模式(CPOL,CPHA状态)。

以上出自:STM32 SPI使用知识


问题及解析:

1、全双工模式下,发送一个8位的数据,接收到的数据是什么? 

 经实验观察,没看出什么联系。当然,这里所说的是发送无用的数据,而非 某些特定环境 说:发送一个数据(命令),应该能够接收到什么.....


2、接收数据时,示波器观察到MISO引脚 不是方波,下降沿特别圆滑,看着像是电容放电的节奏。

那阵子貌似在弄 ADS1256这款A/D片子,遇到这么个情况。  最后定位为 :

SPI配置:SPI_InitStructure.SPI_BaudRatePrescaler = **;---合适就好,过犹不及................



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 SPI 收发数据 ---规则 + 问题解析 的相关文章

  • 当数据大小较小时,内存到内存 DMA 传输是否需要权衡?

    我正在学习 STM32 F4 微控制器 我正在尝试找出使用 DMA 的限制 根据我的理解和研究 我知道如果数据量较小 即设备使用DMA生成或消耗少量数据 则开销会增加 因为DMA传输需要DMA控制器执行操作 从而不必要地增加系统成本 我做了
  • HAL库STM32常用外设教程(二)—— GPIO输入\输出

    HAL库STM32常用外设教程 二 GPIO输入 输出 文章目录 HAL库STM32常用外设教程 二 GPIO输入 输出 前言 一 GPIO功能概述 二 GPIO的HAl库驱动 三 GPIO使用示例 1 示例功能 四 代码讲解 五 总结
  • rt-thread studio中新建5.0不能用

    文章目录 一 版本对比 二 文件和文件夹打斜杠 在使用RT Thread studio创建新工程5 0版本的时候 结果发现新建完成之后程序不能正常运行 但是创建4 10版本的时候却能运行 那肯定是新版本出现了BUG 一 版本对比 首先对比了
  • 解决KEIL编译慢问题

    两种方案 使用v6版本的ARM Compiler 如果v6版本编译不过 必须使用v5版本的 则可以勾选掉Browse Information选项 提升很明显 1分多钟能优化到几秒 看代码量 但是这个有个弊端 在KEIL中会影响函数跳转 建议
  • 串口通讯第一次发送数据多了一字节

    先初始化IO再初始化串口 导致第一次发送时 多出一个字节数据 优化方案 先初始化串口再初始化IO 即可正常通讯
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • STM32 暂停调试器时冻结外设

    当到达断点或用户暂停代码执行时 调试器可以停止 Cortex 中代码的执行 但是 当皮质停止在暂停状态下执行代码时 调试器是否会冻结其他外设 例如 DMA UART 和定时器 您只能保留时间 r 取决于外围设备 我在进入主函数时调用以下代码
  • Freertos低功耗管理

    空闲任务中的低功耗Tickless处理 在整个系统运行得过程中 其中大部分时间都是在执行空闲任务的 空闲任务之所以执行 因为在系统中的其他任务处于阻塞或者被挂起时才会执行 因此可以将空闲任务的执行时间转换成低功耗模式 在其他任务解除阻塞而准
  • CMSIS & STM32,如何开始? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想在 STM32 上使用 CMSIS 启动项目 网上一搜 没找到具体的教程 有些使用 SPL 开始项
  • for循环延时时间计算

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 之前做led点亮的实验 好像是被delay函数影响了 因为delay参数设置的不对
  • systick定时器

    systick定时器 文章目录 前言 一 前期疑惑 二 解答 1 关于systick是阻塞的吗 2 非阻塞 三 软件编写 总结 前言 这边记录systick相关知识点 一 前期疑惑 在学习systick志气啊 其实对于systick还是一脸
  • Cortex-M3与M4权威指南

    处理器类型 所有的ARM Cortex M 处理器是32位的精简指令集处理器 它们有 32位寄存器 32位内部数据路径 32位总线接口 除了32位数据 Cortex M处理器也可以有效地处理器8位和16位数据以及支持许多涉及64位数据的操作
  • 嵌入式 C++11 代码 — 我需要 volatile 吗?

    采用 Cortex M3 MCU STM32F1 的嵌入式设备 它具有嵌入式闪存 64K MCU固件可以在运行时重新编程闪存扇区 这是由闪存控制器 FMC 寄存器完成的 所以它不像a b那么简单 FMC 获取缓冲区指针并将数据刻录到某个闪存
  • STM32内部时钟

    我对 STM32F7 设备 意法半导体的 Cortex M7 微控制器 上的时钟系统感到困惑 参考手册没有充分阐明这些时钟之间的差异 SYSCLK HCLK FCLK 参考手册中阅读章节 gt RCC 为 Cortex 系统定时器 SysT
  • STM32F0、ST-link v2、OpenOCD 0.9.0:打开失败

    我在用着发射台 http www ti com ww en launchpad about htmlgcc arm none eabi 4 9 2015q2 为 STM32F0 进行编译 现在我想使用该集合中的 arm none eabi
  • HAL_Delay() 陷入无限循环

    我被 HAL Delay 函数困住了 当我调用此函数 HAL Delay 时 控制陷入无限循环 在寻找问题的过程中 我发现了这个 http www openstm32 org forumthread2145 threadId2146 htt
  • 使用 STM32F0 ADC 单独读取不同的输入

    STM32F072CBU 微控制器 我有多个 ADC 输入 并且希望单独读取它们 STMcubeMX 生成样板代码 假设我希望按顺序读取所有输入 但我无法弄清楚如何纠正这个问题 这篇博文 http blog koepi info 2015
  • 如何用 C 语言从串行(SPI)连接读取数据?

    我正在尝试编写一个程序 该程序将安装在 Linux MCU Raspberry Pi 上 该程序将读取从另一个 MCU 我将自己构建的自制程序 发送到它的串行数据 我研究了如何做到这一点 并认为我有 大局 但仍然缺少一些东西 其一 我需要启
  • stm32l0: 执行MI命令失败。使用 vFlashErase 数据包擦除闪存时出错

    我正在使用 Nucleo STM32L031 和 AC6 STM32 工作台 eclipse 我编写应用程序并进入调试模式 一切正常 直到我在应用程序中添加另一个功能 我注意到当我删除 评论 新函数 软件可以再次进入调试模式 但是当我添加
  • 读取STM32 MCU SPI数据寄存器的值

    有很多类似的问题 但似乎没有一个问题完全相同 我正在将 STML4 MCU 连接到 6 轴传感器 LSM6DS3 我已经成功地在 I2C 中实现了所有内容 但想要 SPI 的额外速度 和 DMA 如果我能让这些第一步工作起来的话 因此 第一

随机推荐

  • opencv ImportError: libGL.so.1: cannot open shared object file: No such file or directory

    ModuleNotFoundError No module named cv2 使用opencv测试时 xff0c 发现没有安装 xff0c 报错如下 xff1a 安装一下吧 xff1a pip install opencv python
  • CMake中执行shell命令之execute_process、add_custom_target和add_custom_command

    背景 以下情况可能需要在CMake中执行shell脚本 xff1a cmake未提供的功能而实际构建中又需要时 xff0c 如获取Linux发行版本项目构建时需要执行脚本才能完成 xff0c 如boost构建过程 有的需要shell脚本的返
  • rsync增量同步文件用法实践

    rsync rsync remote sync xff0c 远程同步 xff0c 用于在本地机器及远程机器之间同步数据 对于本地机器之内 xff0c 同步数据使用cp即可 对于本地与远程 xff0c 使用scp即可 但上面两个命令同步数据时
  • 关于职业生涯发展的一点思考

    职业类型 从学校毕业步入社会 xff0c 即正式开始了人生职业生涯发展的第一步 总括地说 xff0c 大概有以下几类职业 xff1a 当公务员 xff0c 从政创立公司 xff0c 当企业家找一份工作 xff0c 成为职员 这三条道路 xf
  • c++矩阵计算性能对比:Eigen和GPU

    生成随机矩阵 生成随机矩阵有多种方式 xff0c 直接了当的方式是使用显式循环的方式为矩阵的每个元素赋随机值 span class token macro property span class token directive hash s
  • c语言中 char* 和 unsigned char* 的区别浅析

    背景 最近在项目中遇到了一个编译警告 xff0c 是因为定义的变量为char xff0c 而在使用时作为函数的unsigned char 类型的参数调用 这个警告很容易避免 xff0c 但是char 和unsigned char 到底有什么
  • c语言中static关键字用法详解

    概述 static关键字在c语言中比较常用 xff0c 使用恰当能够大大提高程序的模块化特性 xff0c 有利于扩展和维护 但是对于c语言初学者 xff0c static由于使用灵活 xff0c 并不容易掌握 本文就static在c语言中的
  • linux下把进程/线程绑定到特定cpu核上运行

    概述 现在大家使用的基本上都是多核cpu xff0c 一般是4核的 平时应用程序在运行时都是由操作系统管理的 操作系统对应用进程进行调度 xff0c 使其在不同的核上轮番运行 对于普通的应用 xff0c 操作系统的默认调度机制是没有问题的
  • git中submodule子模块的添加、使用和删除

    背景 项目中经常使用别人维护的模块 xff0c 在git中使用子模块的功能能够大大提高开发效率 使用子模块后 xff0c 不必负责子模块的维护 xff0c 只需要在必要的时候同步更新子模块即可 本文主要讲解子模块相关的基础命令 xff0c
  • ros下package中CMakelists的编写

    目录 一 package自动生成的Cmakelists1 指定cmake版本2 项目名字3 寻找构建所需依赖包4 启用python模块依赖5 Message Service Action 生成文件6 启动 message services
  • STM32跳至硬件错误中断(HardFault_Handle) 原因及参考解决方法

    一 HardFault Handle引起的原因 1 遇到错误问题是数据类型不对 xff0c 导致该步骤永远不能执行到 xff0c 跳至硬件错误中断 xff1b 所以硬件中断可尝试查找数据类型错误 2 堆栈设置错误也会跳至hardwarefa
  • 时间与日期插件 -- laydate 使用方法(摘自官网)

    简单例子 xff1a function var start 61 elem 39 start 39 选择ID为START的input format 39 YYYY MM DD hh mm ss 39 自动生成的时间格式 min laydat
  • nginx部署vue项目(包括一个nginx部署多个vue项目)

    部署准备 vue项目打包 首先打开public下的index目录 xff0c 修改后台的URL地址 xff0c 如下图所示 xff1a 使用CMD xff0c 打开命令行程序 进入项目根目录 执行命令 xff1a npm run build
  • 雅可比(Jacobian)矩阵

    在向量分析中 雅可比矩阵是一阶偏导数以一定方式排列成的矩阵 其行列式称为雅可比行列式 还有 在代数几何中 代数曲线的雅可比量表示雅可比簇 xff1a 伴随该曲线的一个代数群 曲线可以嵌入其中 它们全部都以数学家卡尔 雅可比 Carl Jac
  • 粒子滤波方法入门

    例子滤波方法入门 xff1a 分析典型非线性系统数学模型 主要内容 xff1a 1 非线性数学模型 2 用粒子滤波的MATLAB程序简介 1 非线性数学模型 2 用粒子滤波的MATLAB程序简介 function output args 6
  • 关于VIO中IMU预积分的讲解

    Why VIO 转自 xff1a https zhehangt github io 2019 03 23 SLAM Basic VIOInit 首先我们先简单回顾一下为什么要做VIO xff0c 以及为什么要做VIO初始化 我们知道单目相机
  • 线程互斥量死锁,与sleep没有关联

    文章目录 死锁问题死锁原因产生死锁的几个常见场景死锁产生的四个必要条件 61 61 仅供参考互斥条件占有和等待条件不可抢占条件环路等待条件 pthread mutex lock 线程互斥量死锁 与sleep没有关联 项目上 定位死锁原因 无
  • linux下,应用程序中的全局变量与so库中的全局变量名冲突,怎么办?

    文章目录 Wl Bsymbolic 动态库与应用 如果存在同名全局变量 会如何 实现了一个动态库 xff0c 封装了一些方法 然后基于这个动态库 xff0c 实现了一个应用程序 应用程序中含有全局变量A xff0c 动态库中也含有全局变量A
  • 内存管理:分页,分段,段页结合

    内存管理 xff1a 分页 xff0c 分段 xff0c 段页结合
  • STM32 SPI 收发数据 ---规则 + 问题解析

    规则 xff1a 1 xff09 高速同步串行口 3 xff5e 4线接口 xff08 CS xff0c CLK xff0c MOSI xff0c MISO xff09 xff0c 收发独立 可同步进行 2 xff09 SPI分为主从模式