SPI+DMA传输性能比较

news2025/1/11 5:00:49

  本文章仅仅简单记录32单片机的SPI+DMA驱动显示屏的性能测试,这里不花费时间介绍SPI和DMA。
硬件材料:SPI显示屏一个,32单片机
软件材料:
1.LCD的SPI驱动显示程序(SPI / SPI+DMA):
(1)SPI的配置程序:

SPI_HandleTypeDef SPI3_Handler;  //create a SPI handle
/**
 * @brief	SPI3 master mode
 * @param   void
 * @return  void
 */
void SPI3_Init(void)
{
    SPI3_Handler.Instance=SPI3;            
    SPI3_Handler.Init.Mode=SPI_MODE_MASTER;         
    SPI3_Handler.Init.Direction=SPI_DIRECTION_2LINES;  
    SPI3_Handler.Init.DataSize=SPI_DATASIZE_8BIT;    
    SPI3_Handler.Init.CLKPolarity=SPI_POLARITY_HIGH;    //Idle state clock is high
    SPI3_Handler.Init.CLKPhase=SPI_PHASE_2EDGE;        
    SPI3_Handler.Init.NSS=SPI_NSS_SOFT;                 
    SPI3_Handler.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_2;//baudrate is highest
    SPI3_Handler.Init.FirstBit=SPI_FIRSTBIT_MSB;       
    SPI3_Handler.Init.TIMode=SPI_TIMODE_DISABLE;     
    SPI3_Handler.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE;
    SPI3_Handler.Init.CRCPolynomial=7;                  //omit
    HAL_SPI_Init(&SPI3_Handler);
    __HAL_SPI_ENABLE(&SPI3_Handler);                  
}

/**
 * @brief	SPI3 lower driver config:perip clock ,io
 * @param   hspi: the SPI handle pointer should be use
 * @return  void
 */
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_GPIOB_CLK_ENABLE();    
    __HAL_RCC_SPI3_CLK_ENABLE();        
    
    GPIO_Initure.Pin=GPIO_PIN_3|GPIO_PIN_5;
    GPIO_Initure.Mode=GPIO_MODE_AF_PP;         
    GPIO_Initure.Pull=GPIO_PULLUP;              
    GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;           
    GPIO_Initure.Alternate=GPIO_AF6_SPI3;          
    HAL_GPIO_Init(GPIOB,&GPIO_Initure);
}

(2)SPI的读写接口(非DMA情况下需要使用到)

/**
 * @brief	SPI3 R/W one octet
 * @param   TxData	the u8 data which should be writed
 * @return  the u8 data received
 */
u8 SPI3_ReadWriteByte(u8 TxData)
{
    u8 Rxdata;
    HAL_SPI_TransmitReceive(&SPI3_Handler,&TxData,&Rxdata,1, 1000);       
 	return Rxdata;          		 	
}

/**
 * @brief	SPI3 Write one octet
 * @param   TxData	the tx payload
 * @param   size	payload length
 * @return  u8		0:success,others:fail
 */
u8 SPI3_WriteByte(u8 *TxData,u16 size)
{
	return HAL_SPI_Transmit(&SPI3_Handler,TxData,size,1000);
}

(3)SPI的DMA配置初始化
我使用的是Stm32L4做SPI3+DMA的测试,首先看芯片手册DMA相关的内容:

  上面的表格罗列了DMA2每个通道的DMA请求,SPI3_Tx对应通道2,请求3(0011),那么我们可以这样配置SPI3的DMA通道:

void vidSPI3DMA_Config(void)
{
    __HAL_RCC_DMA2_CLK_ENABLE();//DMA2 Clock Enable

    __HAL_LINKDMA(&SPI3_Handler, hdmatx, SPI3TxDMA_Handler);  //Link DMA to SPI3, here we use the dma tx function

    //Tx Dma config
    SPI3TxDMA_Handler.Instance = DMA2_Channel2;                        //select the channel
    SPI3TxDMA_Handler.Init.Request = DMA_REQUEST_3;                    //request(CxS:0011)
    SPI3TxDMA_Handler.Init.Direction = DMA_MEMORY_TO_PERIPH;           //memory to peripheral
    SPI3TxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;               //peripheral not increment
    SPI3TxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE;                   //memory inc 
    SPI3TxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;  //perip data length:8 bit
    SPI3TxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;     //mem data length:8 bit
    SPI3TxDMA_Handler.Init.Mode = DMA_NORMAL;                          
    SPI3TxDMA_Handler.Init.Priority = DMA_PRIORITY_HIGH;            
    SPI3TxDMA_Handler.State = HAL_DMA_STATE_READY;
    HAL_DMA_DeInit(&SPI3TxDMA_Handler);
    HAL_DMA_Init(&SPI3TxDMA_Handler);
		
	HAL_NVIC_SetPriority(DMA2_Channel2_IRQn, 0, 3);
    HAL_NVIC_EnableIRQ(DMA2_Channel2_IRQn);
}

(4)使用DMA中断需要调用DMA中断函数去清除相关中断标志位。

/*
 * @brief: DMA2 Channel2 IRQ handler function
 *         mainly clear the interrupt flag
*/
void DMA2_Channel2_IRQHandler(void)
{
    HAL_DMA_IRQHandler(&SPI3TxDMA_Handler);
}

/*
 * @brief: After Tx is completed, the SPI DMA should be stopped for next transfer 
*/
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
	HAL_SPI_DMAStop(hspi);    
}

2.LCD显示驱动程序:
(1)LCD基于SPI的数据发送接口:

/**
 * @brief	LCD SPI send data API
 * @return  void
 */
#define NO_USING_DMA 1
static void LCD_SPI_Send(u8 *data, u32 size)
{
#if NO_USING_DMA
	u32 i;
	u32 delta = size/0xFFFF;
	for(i = 0; i<=delta; i++)
	{
		if( i==delta )  /* Send the last data */
			SPI3_WriteByte(&data[i*0xFFFF], size%0xFFFF);//cause this API 2nd param is u16 type
		else    /* send 0xFFFF octets */
			SPI3_WriteByte(&data[i*0xFFFF], 0xFFFF);
    }
#else
	while(SPI3_Handler.State != HAL_SPI_STATE_READY);
	HAL_SPI_Transmit_DMA(&SPI3_Handler, data, size);
#endif
  return;
}

  往LCD写任何数据都是用的这个接口LCD_SPI_Send。关于图片的绘制的函数这里不多余贴出来,相信网上一大把程序可以参考,这里直接使用定时器去了解不开DMA和开DMA显示同一张图片耗时差异,时间从串口打印出来:

    u32 t=0;
    printf("Show a 240X82 picture,Start: %d | ", t);
	vidEnableTIM3(1);//enable TIM3,and clear the counter
    Display_240x82_pic(0, 0);
    t = u32GetTim3Counter();
	printf("End: %d\r\n", t);

  这里我定时器计数频率分频到1Mhz,最大计数50000次,也是就计数频率1us,周期50ms。
在这里插入图片描述
   第一次我是以SPI+DMA驱动LCD显示240X82的图片,可以看出显示该图片在有DMA(加DMA中断)的加持下,耗时156us。第二次是我单独用SPI驱动LCD显示240X82的图片,耗时8685us,所以区别还是蛮大的。

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

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

相关文章

葡萄酒(WINE)数据集分类(PyTorch实现)

一、数据集介绍 Data Set Information: These data are the results of a chemical analysis of wines grown in the same region in Italy but derived from three different cultivars. The analysis determined the quantities of 13 constituents found in each of …

QML debugging is enabled. Only use this in a safe environment.

系列文章目录 文章目录系列文章目录前言一、Qt Quick是什么1.QML核心二、使用步骤1.main.cpp3.运行结果前言 因为有个需求&#xff1a;C和web交互&#xff0c;初步想到在Qt中使用QWebChannel 今天第一次使用Qt Qml&#xff0c;建了qt Quick工程 一、Qt Quick是什么 QML&…

代码随想录算法训练营第三十五天 | 435. 无重叠区间,763.划分字母区间,56. 合并区间

一、参考资料无重叠区间 https://programmercarl.com/0435.%E6%97%A0%E9%87%8D%E5%8F%A0%E5%8C%BA%E9%97%B4.html 划分字母区间https://programmercarl.com/0763.%E5%88%92%E5%88%86%E5%AD%97%E6%AF%8D%E5%8C%BA%E9%97%B4.html 合并区间https://programmercarl.com/0056.%E5%90…

分享111个HTML艺术时尚模板,总有一款适合您

分享111个HTML艺术时尚模板&#xff0c;总有一款适合您 111个HTML艺术时尚模板下载链接&#xff1a;https://pan.baidu.com/s/1sYo2IPma4rzeku3yCG7jGw?pwdk8dx 提取码&#xff1a;k8dx Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 时尚理发沙龙服务网站模…

实现8086虚拟机(二)——模拟CPU和内存

文章目录CPU 架构EU&#xff08;执行单元&#xff09;BIU&#xff08;总线接口单元&#xff09;小结一下模拟内存模拟 BIU模拟 EU模拟 CPU总结要模拟 8086 CPU 运行&#xff0c;必须知道 CPU 的一些知识。下文的知识点都来自《Intel_8086_Family_Users_Manual 》。CPU 架构 微…

spring之Spring AOP基于注解

文章目录前言一、Spring AOP基于注解的所有通知类型1、前置通知2、后置通知3、环绕通知4、最终通知5、异常通知二、Spring AOP基于注解之切面顺序三、Spring AOP基于注解之通用切点三、Spring AOP基于注解之连接点四、Spring AOP基于注解之全注解开发前言 通知类型包括&#x…

J4、哨兵集群、redis切片还是加实例

哨兵集群 单节点的哨兵还是可能会发生故障&#xff0c;需要部署集群。 部署哨兵时&#xff0c;只需要下面的命令&#xff0c;那哨兵是如果互相发现的&#xff1f; sentinel monitor <master-name> <ip> <redis-port> <quorum> 基于 pub/sub 机制的哨…

Premiere基础操作

一&#xff1a;设置缓存二&#xff1a;ctrI导入素材三&#xff1a;导入图像序列四&#xff1a;打开吸附。打开吸附后素材会对齐。五&#xff1a;按~键可以全屏窗口。六&#xff1a;向前选择轨道工具。在时间线上点击&#xff0c;向前选中时间线上素材。向后选择轨道工具&#x…

19_微信小程序之优雅实现侧滑菜单

19_微信小程序之优雅实现侧滑菜单一.先上效果图 要实现这样一个效果&#xff0c;布局其实很简单&#xff0c;整体布局是一个横向滚动的scroll-view&#xff0c;难点在于怎么控制侧滑菜单的回弹&#xff0c;以及寻找回弹的边界条件? 此篇文章主要是基于uni-app来实现的&#xf…

MySQL 记录锁+间隙锁可以防止删除操作而导致的幻读吗?

文章目录什么是幻读&#xff1f;实验验证加锁分析总结什么是幻读&#xff1f; 首先来看看 MySQL 文档是怎么定义幻读&#xff08;Phantom Read&#xff09;的: The so-called phantom problem occurs within a transaction when the same query produces different sets of r…

使用Fairseq进行Bart预训练

文章目录前言环境流程介绍数据部分分词部分预处理部分训练部分遇到的问题问题1可能遇到的问题问题1问题2前言 本文是使用 fairseq 做 Bart 预训练任务的踩坑记录huggingface没有提供 Bart 预训练的代码 facebookresearch/fairseq: Facebook AI Research Sequence-to-Sequence…

字符串匹配 - 文本预处理:后缀树(Suffix Tree)

上述字符串匹配算法(朴素的字符串匹配算法, KMP 算法, Boyer-Moore算法)均是通过对模式&#xff08;Pattern&#xff09;字符串进行预处理的方式来加快搜索速度。对 Pattern 进行预处理的最优复杂度为 O(m)&#xff0c;其中 m 为 Pattern 字符串的长度。那么&#xff0c;有没有…

windows环境下,vue启动项目后打开chrome浏览器

前言&#xff1a;关于vue启动后打开chrome浏览器&#xff0c;我查了很多资料&#xff0c;方案如下&#xff1a; 1、增加环境变量BROWSER为chrome&#xff08;试了没效果&#xff09; 2、设置系统的默认浏览器为chrome&#xff08;应该可以&#xff0c;但没试&#xff1b;因为…

有序表的应用:[Leetcode 327] 区间和的个数

一、题目 1、题目描述 给你一个整数数组 nums 以及两个整数 lower 和 upper 。求数组中&#xff0c;值位于范围 [lower, upper] &#xff08;包含 lower 和 upper&#xff09;之内的 区间和的个数 。 区间和 S(i, j)表示在 nums 中&#xff0c;位置从 i 到 j 的元素之和&…

基于jsplumb构建的流程设计器

项目背景 最近在准备开发工作流引擎相关模块&#xff0c;完成表结构设计后开始着手流程设计器的技术选型&#xff0c;调研了众多开源项目后决定基于jsplumb.js开源库进行自研开发&#xff0c;保证定制化的便捷性&#xff0c;相关效果图及项目地址如下 项目地址&#xff1a;ht…

进程切换-

实验课之前有一些问题 中断机制 第一个问题&#xff1a; interrupt的两个状态源头&#xff1a; 外中断多由随机中断&#xff08;异步中断&#xff09;造成&#xff0c;如鼠标点击&#xff0c;键盘输入&#xff1b; 内终端多由故障终端&#xff1a;程序运行异常&#xff0c;硬件…

使用PyQtGraph 自定义绘图

Python 的主要优势之一是探索性数据科学和可视化生态体系。一般的工具链为Pandas、numpy、sklearn 进行数据分析和使用matplotlib进行绘图。 但是如果需要自己自定义一个个性化的图形界面工具&#xff0c;则可能不是很合适。为了实现这种需求&#xff0c;可以使用PyQt构建GUI应…

【进阶篇】线程的硬件基础

文章目录高速缓存缓存一致性协议写缓冲区和无效化队列高速缓存 简介 高速缓存是主内存与处理器之间的硬件&#xff0c;其容量小于主存&#xff0c;但存取速率远高于主存。因此处理器在执行读写操作时&#xff0c;可直接和高速缓存交互&#xff0c;提高响应速度。 我们常见的变…

2049. 统计最高分的节点数目

2049. 统计最高分的节点数目题目算法设计&#xff1a;深度优先搜索题目 传送门&#xff1a;https://leetcode.cn/problems/count-nodes-with-the-highest-score/ 算法设计&#xff1a;深度优先搜索 这题的核心是计算分数。 一个节点的分数 左子树节点数 右子树节点数 除自…

【Opencv 系列】 第4章 直方图

文章目录[TOC](文章目录)前言1、直方图的定义、意义、特征2、直方图&#xff1a;2.1 灰度直方图2.2 彩色直方图前言 1、直方图的定义、意义、特征 在统计学中&#xff0c;直方图是一种对数据分布情况的图形表示&#xff0c;是一种二维统计图表&#xff0c;他的两个坐标分别是统…