一 前记

SPI接口平时用的比较少,再加上对CUBEMX不是很熟悉,这里踩了不少坑才把问题解决。针对遇到了不少问题,是要值得梳理一下了。

二 源码解析

1 SPI的DMA发送端配置:

2 主函数源码:

uint32_t g_spi_cnt = 0;

void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
g_spi_cnt++; }
2 主函数源码: /**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */
SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_SPI2_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
uart1_test();
memset(TX_Data,0x01,DATA_SIZE);
/* USER CODE END 2 */
HAL_SPI_Transmit_DMA(&hspi2, TX_Data, sizeof(TX_Data));
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
HAL_Delay(1000);
mprintf("g_spi_master_dma_cnt 2.18h is:0x%x \n\r",g_spi_cnt%0xff);
for (uint32_t iss = 0; iss < DATA_SIZE; iss++)
{
/* code */
TX_Data[iss] = g_spi_cnt%0xff;
}
dump8(TX_Data,sizeof(TX_Data));
HAL_SPI_Transmit_DMA(&hspi2, TX_Data, sizeof(TX_Data));
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}

3 SPI的DMA接收端配置:

4 SPI SLAVE源码:

#define DATA_SIZE 64
uint8_t RX_Data[DATA_SIZE];
uint32_t g_spi_cnt = 0; void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef * hspi)
{
HAL_SPI_Receive_DMA(&hspi2, RX_Data, DATA_SIZE);
dump8(RX_Data,10);
g_spi_cnt++;
mprintf("g_spi_slave_cnt 2.18hh is:%d \n\r",g_spi_cnt); } /**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */
SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_SPI2_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
uart1_test();
/* USER CODE END 2 */
memset(RX_Data,0x00,sizeof(RX_Data));
HAL_SPI_Receive_DMA(&hspi2, RX_Data, sizeof(RX_Data));
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
//HAL_Delay(200); /* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}

三 总结

1 DMA的配置模式,

笔者刚开始根据网上的资料,配置了circular模式,发现接收侧一直收到莫名其妙的数据,并且数据经常出错。

修改成了normal模式之后,接收到的数据就对了。关于这两种模式的区别,我已经在前文中介绍过了。

2 SPI位宽设置:

这里遇到的另外一个大问题就是SPI位宽,cube软件默认是4bit,加入按照这个模式设置,你会发现只收到后四个bit的数据,前四个bit为零。

所以,把这个改称8bit是一个必备的。如下图所示:

3 感触:

stm32 CUBE MX是一个比较强大的工具,可这个不是意味着你可以没带基础的话随便使用它,理解协议和里面的每一个含义,才能不至于掉入坑里面。

再者,进去了能否出来,这个要考验你的编码水平和经验了。

基于stm32的spi接口dma 数据收发实例解析的更多相关文章

  1. STM32与物联网02-网络数据收发

    在上一节中,介绍了 ESP8266 的使用方法.不过上一节中都是通过串口调试工具手动发送信息的方式来操作 ESP8266 ,这肯定不能用于实际开发.因此,本节介绍如何编写合适的程序来和 ESP8266 ...

  2. HAL UART DMA 数据收发

    UART使用DMA进行数据收发,实现功能,串口2发送指令到上位机,上位机返回数据给串口2,串口2收到数据后由串口1进行转发,该功能为实验功能 1.UART与DMA通道进行绑定 void HAL_UAR ...

  3. java接口传递数据的实例

    我们要讲E类中的数据变化通知A类,这样通过接口F来实现.具体原理就是E的每次数据改变都让其通知接口:而A类继承接口,所以每次E的调用接口都会触发A类的数据更改事件的触发. 首先创建一个类E: publ ...

  4. 基于ssh框架的highcharts前后台数据交互实例

    Highcharts 是一个用纯JavaScript编写的一个图表库, 能够很简单便捷的在web网站或是web应用程序添加有交互性的图表,并且免费提供给个人学习.个人网站和非商业用途使用.HighCh ...

  5. STM32的SPI口的DMA读写[原创www.cnblogs.com/helesheng]

    SPI是我最常用的接口之一,连接管脚仅为4根:在常见的芯片间通信方式中,速度远优于UART.I2C等其他接口.STM32的SPI口的同步时钟最快可到PCLK的二分之一,单个字节或字的通信时间都在us以 ...

  6. linux驱动基础系列--Linux下Spi接口Wifi驱动分析

    前言 本文纯粹的纸上谈兵,我并未在实际开发过程中遇到需要编写或调试这类驱动的时候,本文仅仅是根据源码分析后的记录!基于内核版本:2.6.35.6 .主要是想对spi接口的wifi驱动框架有一个整体的把 ...

  7. 嵌入式物联网之SPI接口原理与配置

    本实验采用W25Q64芯片 W25Q64是华邦公司推出的大容量SPI FLASH产品,其容量为64Mb.该25Q系列的器件在灵活性和性能方面远远超过普通的串行闪存器件.W25Q64将8M字节的容量分为 ...

  8. 基于Stm32的MP3播放器设计与实现

    原创博文,转载请注明出处 这是我高级电子技术试验课做的作业,拿来共享一下.项目在安福莱例程基础之上进行的功能完善,里面的部分内容可参考安福莱mp3例程.当然用的板子也是安福莱的板子,因为算起来总共做了 ...

  9. C#从基于FTPS的FTP server下载数据 (FtpWebRequest 的使用)SSL 加密

    FTPS,亦或是FTPES, 是FTP协议的一种扩展,用于对TLS和SSL协议的支持. 本文讲述了如何从一个基于FTPS的Server中下载数据的实例.   任何地方,如有纰漏,欢迎诸位道友指教.   ...

  10. stm32 DMA数据搬运 [操作寄存器+库函数](转)

    源:stm32 DMA数据搬运 [操作寄存器+库函数]        DMA(Direct Memory Access)常译为“存储器直接存取”.早在Intel的8086平台上就有了DMA应用了.   ...

随机推荐

  1. C/C++ Npcap包实现ARP欺骗

    npcap 是Nmap自带的一个数据包处理工具,Nmap底层就是使用这个包进行收发包的,该库,是可以进行二次开发的,不过使用C语言开发费劲,在进行渗透任务时,还是使用Python构建数据包高效,唯一的 ...

  2. Hadoop3 No FileSystem for scheme "hdfs"

    Hadoop3 No FileSystem for scheme "hdfs" 异常信息: org.apache.hadoop.fs.UnsupportedFileSystemEx ...

  3. LeetCode刷题日记 2020/03/25

    力扣刷题继续! 题目:计算三维形体表面积 题干 在 N * N 的网格上,我们放置一些 1 * 1 * 1  的立方体. 每个值 v = grid[i][j] 表示 v 个正方体叠放在对应单元格 (i ...

  4. java线程池实现多任务并发执行

    Java线程池实现多任务并发执行 1️⃣ 创建一些任务来落地多任务并发执行 每一个数组里面的数据可以看成任务,或者是需要并发的业务接口, 数组与数组之间,可以看作为他们之间有血缘关系,简单来说就是: ...

  5. PHP 编程技巧与优化

    PHP 编程技巧与优化 1. 尽量采用大量的PHP内置函数. 2. 使用echo代替print,并且使用echo的多重参数(译注:指用逗号而不是句点)代替字符串连接 3. 用单引号代替双引号来包含字符 ...

  6. TValue 的 TTypeKind 的自动转换

    首先官方的定义: TTypeKind = (tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat, tkString, tkSet, tkClass ...

  7. .NET Avalonia开源、免费的桌面UI库 - SukiUI

    前言 今天分享一款.NET Avalonia基于MIT License协议开源.免费的桌面UI库:SukiUI. Avalonia介绍 Avalonia是一个强大的框架,使开发人员能够使用.NET创建 ...

  8. Java并发编程实例--11.在线程组中处理未检查异常

    第8个例子讲了如何在线程中捕捉未检查异常,本例将介绍如何在线程组中处理未检查异常. Task.java package com.dylan.thread.ch1.c11.task; import ja ...

  9. 用virtualenv创建虚拟环境

    步骤 1.打开终端cmd,直接输入命令pip install virtualenv,前提已经将pip加入到环境变量中了 2.在e盘创建一个专门用来装虚拟环境的文件夹,如django_web_env 3 ...

  10. 【Filament】Filament环境搭建

    1 前言 ​ Filament 是一个实时物理渲染引擎,用于 Android.iOS.Linux.macOS.Windows 和 WebGL 平台.该引擎旨在提供高效.实时的图形渲染,并被设计为在 A ...