一 前言
最近在调试stm32的SPI时候i,遇到了一个非常诡异的问题。中间花费了不少时间才把问题搞定。这中间暴露的问题值得反思。借此机会,还是梳理一下stm32的SPI的代码做一个总结吧。
二 初始化
1.SPI接口的初始化比较标准,和几乎所有的stm32外围接口一样,分为接口初始化和链接部分组成:
接口初始化:
/* SPI2 init function */
void MX_SPI2_Init(void)
{ /* USER CODE BEGIN SPI2_Init 0 */ /* USER CODE END SPI2_Init 0 */ /* USER CODE BEGIN SPI2_Init 1 */ /* USER CODE END SPI2_Init 1 */
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 7;
hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI2_Init 2 */ /* USER CODE END SPI2_Init 2 */

  链接:

  /* USER CODE END SPI2_MspInit 0 */
/* SPI2 clock enable */
__HAL_RCC_SPI2_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE();
/**SPI2 GPIO Configuration
PB13 ------> SPI2_SCK
PB14 ------> SPI2_MISO
PB15 ------> SPI2_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* SPI2 DMA Init */
/* SPI2_TX Init */
hdma_spi2_tx.Instance = DMA1_Channel5;
hdma_spi2_tx.Init.Request = DMA_REQUEST_1;
hdma_spi2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi2_tx.Init.Mode = DMA_NORMAL;
hdma_spi2_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_spi2_tx) != HAL_OK)
{
Error_Handler();
} __HAL_LINKDMA(spiHandle,hdmatx,hdma_spi2_tx); /* SPI2_RX Init */
hdma_spi2_rx.Instance = DMA1_Channel4;
hdma_spi2_rx.Init.Request = DMA_REQUEST_1;
hdma_spi2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi2_rx.Init.Mode = DMA_NORMAL;
hdma_spi2_rx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_spi2_rx) != HAL_OK)
{
Error_Handler();
} __HAL_LINKDMA(spiHandle,hdmarx,hdma_spi2_rx); /* SPI2 interrupt Init */
HAL_NVIC_SetPriority(SPI2_IRQn, 7, 0);
HAL_NVIC_EnableIRQ(SPI2_IRQn);
注意事项:
这里面调试的时候注意以下几个地方:
一个是接口不能被复用了。另外一个是接口硬件部分是通的。这两个可以通过GPIO的拉高拉地来测电平实现。
另外一个就是系统的主频要注意,尽量不要设置太高,因为有些SPI接口速率没那么高的。
 
三 数据收发:
 
1.数据发送:
HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
2.数据接收:
HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
3.注意事项:
其实,数据收发一般不会出问题,可是一旦出问题了,就不是小问题。这里,注意几个东西。
由于是DMA接收和发送,所以CS一定要拉地的时间尽量长,系统允许的话,开始的时候,尽量不要随意拉高CS。
否则会出现丢数据的情况。
 
四 总结
 
1.不要盲目详细计算机。它不会代替你思考的。遇到了问题,还是要凭借对代码的理解和实践出来的技能来判断的。

STM32 SPI DMA 源码解析及总结的更多相关文章

  1. dubbo源码解析-spi(4)

    前言 本篇是spi的第四篇,本篇讲解的是spi中增加的AOP,还是和上一篇一样,我们先从大家熟悉的spring引出AOP. AOP是老生常谈的话题了,思想都不会是一蹴而就的.比如架构设计从All in ...

  2. dubbo源码解析-spi(3)

    前言 在上一篇的末尾,我们提到了dubbo的spi中增加了IoC和AOP的功能.那么本篇就讲一下这个增加的IoC,spi部分预计会有四篇,因为这东西实在是太重要了.温故而知新,我们先来回顾一下,我们之 ...

  3. dubbo源码解析-spi(一)

    前言 虽然标题是dubbo源码解析,但是本篇并不会出现dubbo的源码,本篇和之前的dubbo源码解析-简单原理.与spring融合一样,为dubbo源码解析专题的知识预热篇. 插播面试题 你是否了解 ...

  4. 【Java实战】源码解析Java SPI(Service Provider Interface )机制原理

    一.背景知识 在阅读开源框架源码时,发现许多框架都支持SPI(Service Provider Interface ),前面有篇文章JDBC对Driver的加载时应用了SPI,参考[Hibernate ...

  5. Dubbo源码解析之SPI(一):扩展类的加载过程

    Dubbo是一款开源的.高性能且轻量级的Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用.智能容错和负载均衡,以及服务自动注册和发现. Dubbo最早是阿里公司内部的RPC框架,于 ...

  6. 5.2 dubbo-compiler源码解析

    ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.class); final P ...

  7. 2.2 dubbo-spi源码解析

    package com.alibaba.dubbo.demo.test; import com.alibaba.dubbo.common.extension.ExtensionLoader; impo ...

  8. 第零章 dubbo源码解析目录

    第一章 第一个dubbo项目 第二章  dubbo内核之spi源码解析 2.1  jdk-spi的实现原理 2.2 dubbo-spi源码解析 第三章 dubbo内核之ioc源码解析 第四章 dubb ...

  9. Sentinel源码解析一(流程总览)

    引言 Sentinel作为ali开源的一款轻量级流控框架,主要以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度来帮助用户保护服务的稳定性.相比于Hystrix,Sentinel的设计更加简 ...

  10. [源码解析] TensorFlow 分布式环境(3)--- Worker 静态逻辑

    [源码解析] TensorFlow 分布式环境(3)--- Worker 静态逻辑 目录 [源码解析] TensorFlow 分布式环境(3)--- Worker 静态逻辑 1. 继承关系 1.1 角 ...

随机推荐

  1. 学生成绩管理系统|Python小应用练习

    题目要求 实现学生成绩管理系统 输入学生成绩信息序列,获得成绩从高到低.从低到高.按某一门成绩的排列,相同成绩都按先录入排列在前的规则处理. 数据如下:(数据规则:学生姓名 高数成绩 英语成绩 大物成 ...

  2. 理论与实战:一篇看懂Python词云

    理论与实战:一篇看懂Python词云 后宫王镇贴 前言:本文初编辑于2024年2月2日 该项目代码的仓库地址:https://github.com/A-Piece-Of-Maple/WordCloud ...

  3. 交换变量a,b的值(java)

    方法1:引入中间变量 int a = 10; int b = 20; int temp = a; a = b; b = temp; System.out.println("a = " ...

  4. webpack学习笔记(一)安装与试用

    由于初次接触 webpack(官网),对很多方面都不是很理解,在查找部分资料后记录一下自己的见解(本文实践基于webpack4). 1. 个人见解 简单来说,webpack就是js的 打包 工具.个人 ...

  5. Python学习之Pytorch

    一.如何查看本机是否安装了Pytorch 在Python环境中查看是否安装了PyTorch可以通过几个简单的步骤来完成.这里有一些方法: 使用Python命令行: 打开你的命令行工具(比如Termin ...

  6. Power BI 7 DAY

    DAX 表达式(Data Analysis Expressions) DAX表达式的结果应用在数据透视表中 DAX表达式的结果作用于整列或者表中所有行 还需注意以下几点: a. 表名用"'' ...

  7. NC51178 没有上司的舞会

    题目链接 题目 题目描述 Ural大学有N名职员,编号为1~N. 他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司. 每个职员有一个快乐指数,用整数 \(Hi\) 给出,其中 \(1\le ...

  8. NC14699 队伍配置

    题目链接 题目 题目描述 萌学姐在玩大型手游<futa go>,他现在准备进入作战环节,所以他准备安排自己的队伍. 队伍配置里,可供玩家选择的作战人物被称作"从者",玩 ...

  9. NC14704 美味菜肴

    题目链接 题目 题目描述 小明是个大厨,早上起来他开始一天的工作.他所在的餐厅每天早上都会买好 \(n\) 件食材(每种食材的数量可以视为无限),小明从到达餐厅开始就连续工作 \(T\) 时间.每道菜 ...

  10. IPFS Gateway Selector IPFS下载网关选择工具

    简介 用IPFS作文件分享可以覆盖很多场景, 现在IPFS网关也相当多了, 但是因为国内网络的状况, 不同网关在不同网络运营商的表现差别很大, 导致你提供的下载链接在对方那里可能速度很慢, 甚至无法访 ...