SPI+DMA传输性能比较

这篇具有很好参考价值的文章主要介绍了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 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相关的内容:
dma spi,笔记,单片机,单片机,stm32,嵌入式硬件
  上面的表格罗列了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。
dma spi,笔记,单片机,单片机,stm32,嵌入式硬件
   第一次我是以SPI+DMA驱动LCD显示240X82的图片,可以看出显示该图片在有DMA(加DMA中断)的加持下,耗时156us。第二次是我单独用SPI驱动LCD显示240X82的图片,耗时8685us,所以区别还是蛮大的。文章来源地址https://www.toymoban.com/news/detail-698749.html

到了这里,关于SPI+DMA传输性能比较的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)

    本文教你把U8g2图形库移植到STM32上,基于STM32的硬件SPI、CubeMX U8g2库Github网址:https://github.com/olikraus/u8g2 U8g2库CSDN镜像网址:https://gitcode.net/mirrors/olikraus/u8g2?utm_source=csdn_github_accelerator 硬件准备:STM32C8T6(STM32系列芯片)、0.96寸OLED(128×64)、J-Link(或其他) 引脚连接: 出自此

    2024年02月09日
    浏览(47)
  • GD32 SPI DMA收发

    由于需求用到GD32 SPI, 故做相关实验记录分享,本实验为 SPI DMA 发送与接收 16bit 数据, GD32 相关配置如下 GD32 F30x系列 DMA配置如下   SPI DMA 发:使用SPI0,对应的DMA为0 Channel 2。  注意打开 对应 DMA 与 SPI 相关时钟, DMA write 使用时需要先拉低 NSS,发送结束,拉高NSS SPI DMA 收

    2024年02月13日
    浏览(44)
  • STM32使用SPI+DMA(标准库)

    DMA DMA原理 DMA通道资源分配 SPI+DMA配置 主函数编写如下 1.CPU配置好DMA。 2.SPI发出DMA请求。(在DMA_Mode_Normal模式下,该请求实际上需要CPU命令SPI发出请求) 3.若该通道有多个请求,DMA控制器通过仲裁器判断,根据配置的优先级,选择先回应该通道高优先级的请求,再回应低优先

    2024年02月11日
    浏览(45)
  • [HAL]STM32 SPI+DMA驱动WS2812

    该程序是纯手敲,非Cube生成!所有代码均注释。 源码在文章后面获取 Keyword: 单线通讯、归零码、Reset、RGB顺序 RGB一共有24bit位 -相当于驱动一个灯要24bit位 -驱动若干个灯要24* n bit位,通过Reset码决定数据终止(保持) 24bit位应该如何发送? 可见: 表示低电平需要 T0H和T0L的配

    2024年02月09日
    浏览(48)
  • STM32 硬件SPI+DMA实现快速刷TFT屏

    首先在TB上找一块SPI驱动的彩屏,下载商家提供的示例 例如我买的一款2.8寸SPI的TFT彩屏,商家提供的资料很齐全,模拟SPI和硬件SPI驱动的程序都有 打开硬件SPI驱动的工程,商家提供的代码是SPI2驱动,想换成其他的SPI可以到SPI.c文件中更改 打开main.c,测试一下简单颜色填充刷

    2024年04月15日
    浏览(57)
  • 华大HC32F460 SPI+DMA通信实验代码详解

    声明:以下内容均为本人学习心得。 一、基础知识。 华大HC32F460 提供的SPI是4线式和3线式。搭载4个通道的串行外设接口,支持高速全双工串行同步传输。 4线式:SCK、MOSI、MISO、SS0~SS3。3线式:SCK、MOSI、MISO。 SPI数据发送时:传送数据先进入发送缓冲器(TX_BUFF),再将TX_BUFF的数据

    2024年02月11日
    浏览(27)
  • 讲解STM32驱动WS281x灯珠的多种实现方式:普通IO、SPI+DMA、以及PWM+DMA驱动方法

    STM32作为一款高性能、功能丰富的单片机,其丰富的外设和强大的性能,使其在嵌入式领域得到了广泛的应用。本篇文章将介绍如何利用STM32驱动WS281x系列的LED灯珠。我们会使用三种不同的驱动方式进行实现:一种是普通IO方式驱动,一种是SPI+DMA方式驱动,最后一种是PWM+DMA方

    2024年02月11日
    浏览(37)
  • 使用STM32F103的SPI+DMA驱动ws2812 LED

    目录 前言 一、WS2812协议 1.1 数据传输编码方式:  1.2 传输的数据结构 二、驱动方式:SPI+DMA 2.1 原理介绍 2.2 SPI+DMA操作  2.3 编写代码 2.4 使用 三 总结 参考文章 主要使用的STM32F103C8T6芯片的SPI+DMA方式实现WS2812的驱动协议,总体可以看作是使用SPI来实现一种通信协议来发送信号。

    2024年02月09日
    浏览(62)
  • stm32HAL库 G4 SPI 从机DMA可变长度接受数据乱码问题

    使用一个引脚当作SPI CS, 边沿触发; 在电平位0时候接受SPI数据20个字节 如果实际主机只发了小于20字节时候, 下一个帧就会错乱; 去老外找了之后,需要复位SPi RCC时钟才能复位掉SPI 下面的不行 正确的做法

    2024年02月10日
    浏览(32)
  • STM32CubeMX配置HAL库实现SPI-DMA的递归调用

    核心: STM32F407ZET6   外设ADC: ADS1258   数量:3个   ※ 核心与3个ADC使用SPI总线 “一主多从” 方式连接,PCB布线的方式与下图一致。 ※ 在电路板上STM32与三个ADS1258在同一直线上分布,STM32在一端,三个ADC依次排布。 ※ 离STM32最远ADC的DRDY硬件管脚与STM32的EXTI line4 interrupt连接

    2024年02月15日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包