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,…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
