SPI+DMA传输性能比较
本文章仅仅简单记录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 highSPI3_Handler.Init.CLKPhase=SPI_PHASE_2EDGE; SPI3_Handler.Init.NSS=SPI_NSS_SOFT; SPI3_Handler.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_2;//baudrate is highestSPI3_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; //omitHAL_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 configSPI3TxDMA_Handler.Instance = DMA2_Channel2; //select the channelSPI3TxDMA_Handler.Init.Request = DMA_REQUEST_3; //request(CxS:0011)SPI3TxDMA_Handler.Init.Direction = DMA_MEMORY_TO_PERIPH; //memory to peripheralSPI3TxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE; //peripheral not incrementSPI3TxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE; //memory inc SPI3TxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; //perip data length:8 bitSPI3TxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; //mem data length:8 bitSPI3TxDMA_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_DMAu32 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 typeelse /* send 0xFFFF octets */SPI3_WriteByte(&data[i*0xFFFF], 0xFFFF);}
#elsewhile(SPI3_Handler.State != HAL_SPI_STATE_READY);HAL_SPI_Transmit_DMA(&SPI3_Handler, data, size);
#endifreturn;
}
往LCD写任何数据都是用的这个接口LCD_SPI_Send。关于图片的绘制的函数这里不多余贴出来,相信网上一大把程序可以参考,这里直接使用定时器去了解不开DMA和开DMA显示同一张图片耗时差异,时间从串口打印出来:
u32 t=0;printf("Show a 240X82 picture,Start: %d | ", t);vidEnableTIM3(1);//enable TIM3,and clear the counterDisplay_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,所以区别还是蛮大的。
相关文章:
SPI+DMA传输性能比较
本文章仅仅简单记录32单片机的SPIDMA驱动显示屏的性能测试,这里不花费时间介绍SPI和DMA。 硬件材料:SPI显示屏一个,32单片机 软件材料: 1.LCD的SPI驱动显示程序(SPI / SPIDMA): (1&a…...
Centos7系统编译Hadoop3.3.4
1、背景 最近在学习hadoop,此篇文章简单记录一下通过源码来编译hadoop。为什么要重新编译hadoop源码,是因为为了匹配不同操作系统的本地库环境。 2、编译源码 2.1 下载并解压源码 [roothadoop01 ~]# mkdir /opt/hadoop [roothadoop01 ~]# cd /opt/had…...
pb并发控制
并发控制(一) 并发能力是指多用户在同一时间对相同数据同时访问的能力。一般的关系型数据库都具 有并发控制的能力,但是这种并发功能也会对数据的一致性带来危险。试想若有两个用 户都试图访问某个银行用户的记录并同时要求修改该用户的存款余额时,情况将会怎样 呢?我们可以…...
登录拦截器
文章目录前言一、interceptor1.interceptor 包下新建loginInterceptor.java2.config 包下新建 AdminWebConfig.java3.返回登录页面接收提示信息前言 本篇主要介绍spring框架里提供的 HandlerInterceptor 拦截器做登录拦截。 一、interceptor 1.interceptor 包下新建loginInte…...
STM32 - HAL库UART串口
1.串口初始化配置/******************************************************************************* Function: BSP_UART_Init Description: 串口初始化 Input: instance 串口号baudRate: 波特率 Output: 无 Return: 无 ************************************************…...
Vue3 的状态管理库(Pinia)
目录前言:一、什么是 Pinai二、安装与使用pinia三、什么是 store四、state1. 定义 state2. 组件中访问 state五、Getters1. 定义 Getters2. 在组件中使用 Getters六、Actions1. 定义Actions2. 组件中访问 Actions总结:前言: 在编写vue里的项目…...
信息系统项目管理师知识点汇总(2023最新)
信息系统项目管理师 信息系统项目管理师简介如何应对考试考试细节与学习 十大管理 十大管理四十七过程 信息化和信息系统 项目管理基础 项目整体管理 项目范围管理 项目进度管理 项目成本管理 项目质量管理 项目人力资源管理 项目沟通管理 项目干系人管理 项目风险…...
标题标题标题
图床(Typora uPic/PicGo 七牛云) 图床(Typora uPic/PicGo 七牛云) 笔者平时使用 Typora 编写 markdown 文档,文档中常常会放置图片,如果文档不需要分享的话,其实讲图片存放在本地就可以了…...
OKR学习总结二
总结 绩效管理不是进行事后管理,而是参与整个过程并进行实时把控。 我们将受益目标分为两个子目标: 新增收入和重复收入。第一部分目标由市场营销部承担,第二个目标则由产品部承担。 简而言之,文化是一系列价值观和信仰的体现&…...
MAC中docker搭建fastdfs
1:首先搭建Docker2:通过Docker搭建fastdfs(1)查找镜像打开终端通命令查找fastdfs的镜像docker search fastdfs(二)拉取镜像在找到合适的镜像后执行命令:docker pull delron/fastdfs(三) 创建storage和track…...
JavaScript 变量
变量是用于存储信息的"容器"。实例var x5;var y6;var zxy;尝试一下 就像代数那样x5y6zxy在代数中,我们使用字母(比如 x)来保存值(比如 5)。通过上面的表达式 zxy,我们能够计算出 z 的值为 11。在…...
【前端验证】环境仿真中对于寄存器配置的随机策略讨论
前言 本篇文章旨在讨论环境仿真中对于寄存器配置的随机。 寄存器域的随机性 使用ralgen生成的寄存器本身是rand属性的,也就是说其自身是可以通过约束随机的方式在用例中进行随机性配置的,比如下面这个寄存器: class ral_reg_REG_PRJ_sys_cfg_base_config extends uvm_re…...
Servlet如何读取Web资源文件?【操作演示】
在实际开发中,有时候可能会需要读取Web应用中的一些资源文件,比如配置文件,图片等。为此,在ServletContext接口中定义了一些读取Web资源的方法,这些方法是依靠Servlet容器来实现的。Servlet容器根据资源文件相对于Web应…...
[ vulhub漏洞复现篇 ] Drupal 远程代码执行漏洞(CVE-2019-6339)
🍬 博主介绍 👨🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…...
flex-shrink和felx-grow
本文就是简单的介绍下flex-shrink和felx-grow的作用和计算方式吧;关于这个介绍也是很多;flex-shrinkflex-shrink是flex布局中的一种方式,简单来说,就是当布局大小小于容器大小的时候,使用flex-shrink能够按照一定的比例…...
将HTTP接口配置成HTTPS
一、使用Java的keytool.exe程序生成本机的TLS许可找到Java的jdk目录进入bin默认安装路径C:\Program Files\Java\jdk1.8.0_91\bin 进入命令面板,在bin的路径栏中输入cmd敲击回车即可使用keytoolkeytool -genkeypair -alias tomcat_https -keypass 123456 -keyalg RSA…...
YOLOV5报错解决办法
🌈🌈😄😄 欢迎来到茶色岛独家岛屿,本期将为大家揭晓YOLOV5报错解决办法,做好准备了么,那么开始吧。 🌲🌲🐴🐴 1.在pycharm终端使用pip install…...
java final关键字 详解
概述:作用:细节:演示:总结:一、概述 : final [ˈ faɪnl],最终的,最后的,决定性的,不可改变的。final作为Java中的一个关键字可以用来修饰类,方法,…...
Vbs_To_Exe制作简易exe程序
文章目录一、准备vbs脚本文件二、工具打包exe一、准备vbs脚本文件 新建一个文本文档 复制下面代码到文本文档中 Set speech CreateObject("SAPI.SpVoice") speech.Speak "l love you!"修改文本后缀为.vbs。编码选择ANSI(解决中文乱码问题&am…...
AI制药 - TMScore(US-align)、RMSD、Sequence 源码
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://blog.csdn.net/caroline_wendy/article/details/129125467 参考文档:Nature Methods | 蛋白、RNA、DNA及其复合物结构的比对算法US-align 官网地址:https://zhanggroup.org/US-align/ TMScore TMScore,…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
协议转换利器,profinet转ethercat网关的两大派系,各有千秋
随着工业以太网的发展,其高效、便捷、协议开放、易于冗余等诸多优点,被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口,具有实时性、开放性,使用TCP/IP和IT标准,符合基于工业以太网的…...
Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...
Matlab实现任意伪彩色图像可视化显示
Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中,如何展示好看的实验结果图像非常重要!!! 1、灰度原始图像 灰度图像每个像素点只有一个数值,代表该点的亮度(或…...
