首页 > 其他分享 >基于stm32的spi接口dma 数据收发实例解析

基于stm32的spi接口dma 数据收发实例解析

时间:2024-02-19 11:33:39浏览次数:30  
标签:dma BEGIN CODE SPI stm32 spi Init USER Data

一 前记

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

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

标签:dma,BEGIN,CODE,SPI,stm32,spi,Init,USER,Data
From: https://www.cnblogs.com/dylancao/p/18020729

相关文章

  • JAVA基础-SPI
    1,什么是SPISPI全名ServiceProviderinterface,翻译过来就是“服务提供接口”,再说简单就是提供某一个服务的接口,提供给服务开发者或者服务生产商来进行实现。JavaSPI是JDK内置的一种动态加载扩展点的实现。这个机制在一般的业务代码中很少用到(个人接触到的业务没有用到过),但是......
  • STM32 SPI接口 DMA normal 和circual区别
     DMA有normal和circular两种模式。circular模式:就调用这个函数一次就可以了,DMA一直开启,一帧数据发送完毕之后里面发送下一帧,中间没有停顿。这样确实是快了,也释放了CPU,各路的数据采集因为缺少了等待串口发送的时间,所以就间接提高的了数据更新速率。但有个致命缺陷:数据采集和数......
  • 01. 初识STM32
    一、什么是STM32  STM32,从字面上来理解,ST是意法半导体,M是Microelectronics的缩写,32表示32位,合起来理解,STM32就是指ST公司开发的32位微控制器。  STM32主要分两大块,MCU和MPU,MCU就是我们常见的STM32微控制器,不能跑Linux,而MPU则是ST在19年才推出的微......
  • stm32芯片的SPI接口调试总结之轮询模式
    一概念1组成SPI系统可直接与各个厂家生产的多种标准外围器件接口,它只需4条线:串行时钟线(SCK)、主机输入/从机输出数据线(MISO)、主机输出/从机输入数据线(MOSI)和低电平有效的从机选择线(NSS)。(1)MISO:主设备输入/从设备输出引脚。该引脚在从模式下发送数据,在主模式下接收数......
  • STM32之红外遥控信号自学习实现
    一、序言很早前就想实现这个红外遥控自学习的这个实验,用于来自己控制房子里如空调等红外遥控设备的自动化,NEC的标准到具体的产品上可能就被厂家定义为不一样了,所以自学习就应该是接收到什么就发送什么,不用管内容是什么!二、硬件实现原理由上述原理图可知,当IE为高电平时发送红外......
  • 【STM32】成功创建Keil MDK工程的条件(可对照查缺补漏)
    文中所有文件夹数量和名称没有限制,按自己理解建也OK。首先:确保编码格式正确(UTF-8),可在小扳手那里更改。安装对应芯片器件支持包。建启动文件夹Start(记得在Keil项目界面添加同名分组导入文件),启动文件的最后字母为型号缩写。STM32F1系列的具体芯片型号缩写参照下表:建......
  • STM32系统开发--基于LL库的多串口Printf使用
    MDK:Keilv5.38/STM32CubeMXMCU:STM32G431CBUx外设:串口USART1、2使用多串口Printf,基于C语言中的函数可变参数,首先要包含头文件"stdarg.h"。基于LL库,编写多串口打印函数:/************************************************函数名称:USART_Printf功能:多串口Printf函数......
  • stm32 esp8266测试问题原因记录
    现象:连上WIFI但发送数据失败 原因:WIFI网络延时过大,或者程序设置的等待超时时间过小解法:换个网络延时小的WIFI连,或者增加程序等待超时的时间 现象:连不上WIFI 原因:esp8266_mqtt_init()中的的延迟过长,测试4S不行,要2S解法:将4秒延时改回2S1int32_tesp8266_mqtt_init(v......
  • STM32超声波模块问题
    先写没问题用法,有问题的语法就不示范voidSr04_Init(void){GPIO_InitTypeDefGPIO_InitStruct;TIM_TimeBaseInitTypeDefTIM_TimeBaseInitStruct;//打开GPIO组时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);RCC_AHB1PeriphClockCm......
  • 【译】发布 .NET Aspire 预览版 2(二)
    原文|DamianEdwards翻译|郑子铭组件更新组件包现在有单独的图标大多数Aspire组件的NuGet包现在都具有代表性图标,以便在NuGet包管理器对话框中更轻松地识别它们,并给体验带来一些视觉差异:MySqlConnector的组件和托管支持感谢社区成员BradleyGrainger(流行的MyS......