这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【换取逻辑分析仪】STM32G4从入门到大师之三:STM32G4用硬件SIPDM

共9条 1/1 1 跳转至

【换取逻辑分析仪】STM32G4从入门到大师之三:STM32G4用硬件SIPDMA驱动TFT显示屏

高工
2025-04-01 20:35:09     打赏

  STM32G4微控制器中的SPI(Serial Peripheral Interface,串行外设接口)功能强大与DMA(Direct Memory Access,直接内存访问)技术的结合使用。进一步增强了STM32G4在数据传输方面的能力,使其更适合于需要高速、可靠数据传输的应用场景。

优点:

1,释放CPU资源:

在传统的数据传输方式中,CPU需要负责数据的读取、写入以及传输控制等工作,这会导致CPU资源的占用。

而当SPI与DMA结合使用时,DMA控制器可以自动完成数据传输工作,从而释放了CPU资源,使CPU能够专注于其他任务的处理。

2可靠性增强。

硬件级别的数据传输:DMA控制器是在硬件级别上实现数据传输的,因此具有更高的稳定性和可靠性。相比于软件层面的数据传输方式,DMA传输更不容易受到软件错误或中断的影响。

一、SPI通信原理

SPI是一种高速、全双工、同步的通信总线,由四条线组成:SCLK(Serial Clock,串行时钟)、MISO(Master In Slave Out,主设备输入/从设备输出)、MOSI(Master Out Slave In,主设备输出/从设备输入)和CS(Chip Select,片选信号,也称为SS,Slave Select)。

SCLK:由主设备提供,用于同步数据传输,即控制数据的发送和接收时序。

MISO:数据从从设备传输到主设备的线路。

MOSI:数据从主设备传输到从设备的线路。

CS:由主设备控制,用于选择要通信的从设备。

SPI通信可以配置为四种模式,取决于时钟极性和相位的不同配置。通过合理配置这些参数,SPI通信可以适应不同外围设备的要求,实现高效的数据交换。

二、DMA技术原理

DMA是一种能够自动完成数据传输的技术,它可以在不占用CPU资源的情况下,实现内存与外设之间的数据交换。DMA控制器具有独立的内存地址和数据计数器,可以自动地读取或写入内存中的数据。

三、SPI DMA通信原理

在STM32G4微控制器中,SPI与DMA的结合使用可以实现高效的数据传输。当配置为SPI DMA模式时,CPU只需初始化SPI和DMA的相关参数,并启动DMA传输。之后,DMA控制器会自动地读取或写入内存中的数据,并通过SPI总线传输到外设或从外设接收数据。

具体来说,当主设备需要通过SPI发送数据时,DMA控制器会自动从内存中读取数据,并将其发送到SPI总线的MOSI线上。同时,当主设备需要从SPI接收数据时,DMA控制器会自动从MISO线上接收数据,并将其存储到内存中。整个过程无需CPU的干预,从而释放了CPU的负载,提高了系统的性能。

四、配置解析

时序配置:在设计SPI通信系统时,时序配置是核心之一。这涉及到对SCLK频率的设置、时钟极性和相位的配置,以及CS信号的管理。

主从模式:在STM32的SPI主机模式下,DMA控制器无法自动产生片选CS信号,只能与无需同步CS信号的外设器件通信。而在从模式下,STM32的SPI可以在DMA的支持下实现高效、实时的数据接收。

中断与轮询:在实际应用中,为了提高数据读写效率,建议使用DMA中断而不是轮询方式。当DMA传输完成时,可以触发中断服务例程来处理后续操作。

CubeMX软件时间配置:

M2.png


M3.png




关键函数解析

HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)

功能:通过硬件 SPI 使用 DMA 方式发送一组数据;

参数 1:SPI 句柄,根据实际需要填写;

参数 2:要发送数据的指针,常见为发送数据数组的首地址;

参数 3:发送数据长度,单位字节;

返回:操作结果,HAL_OK,HAL_ERROR;

示例:HAL_SPI_Transmit_DMA(&hspi4,data_color,2*xLong);//通过 SPI4 的 DMA 方式发送

颜色数据

HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)

功能:通过硬件 SPI 的 DMA 方式接收一组数据;

参数 1:SPI 句柄,根据实际需要填写;

参数 2:要接收数据保存指针;

参数 3:接收数据长度,单位字节;

返回:操作结果,HAL_OK,HAL_ERROR;


HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)

功能:通过硬件 SPI 的 DMA 方式交换一组数据;

参数 1:SPI 句柄,根据实际需要填写;

参数 2:要发送数据的指针,常见为发送数据数组的首地址;

参数 3:要接收数据的指针,接收数据数组的首地址;

参数 4:数据长度,单位字节;

返回:操作结果,HAL_OK,HAL_ERROR;

注意:使用相应 DMA 时需要对该 DMA 请求进行配置;

void MX_DMA_Init(void)
{

  /* DMA controller clock enable */
  __HAL_RCC_DMAMUX1_CLK_ENABLE();
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Channel1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);

}


void MX_SPI4_Init(void)
{

  /* USER CODE BEGIN SPI4_Init 0 */

  /* USER CODE END SPI4_Init 0 */

  /* USER CODE BEGIN SPI4_Init 1 */

  /* USER CODE END SPI4_Init 1 */
  hspi4.Instance = SPI4;
  hspi4.Init.Mode = SPI_MODE_MASTER;
  hspi4.Init.Direction = SPI_DIRECTION_2LINES;
  hspi4.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi4.Init.CLKPolarity = SPI_POLARITY_HIGH;
  hspi4.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi4.Init.NSS = SPI_NSS_SOFT;
  hspi4.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
  hspi4.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi4.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi4.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi4.Init.CRCPolynomial = 7;
  hspi4.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi4.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
  if (HAL_SPI_Init(&hspi4) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI4_Init 2 */

  /* USER CODE END SPI4_Init 2 */

}


void LCD_WriteByteSPI(unsigned char byte) //SPIº¯Êý£¬Ð´Ò»¸ö8bitµÄÊý¾Ý
{
#if USE_HARDSPI
		HAL_SPI_Transmit(&hspi4,&byte,1,1);

#else
		unsigned char buf;
    unsigned char i;
    for(i=0;i<8;i++) 
    {
        buf=(byte>>(7-i))&0x1;
				SPI_DCLK(0);
        SPI_SDA(buf);
        SPI_DCLK(1);
    }	
#endif
	
}
int main(void)
{

 
  HAL_Init();
  SystemClock_Config(); 
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_SPI4_Init();
  /* USER CODE BEGIN 2 */
	LCD_Initial();
	Lcd_ColorBox(0,0,XSIZE_PHYS,YSIZE_PHYS,Blue);//ÓÃÀ¶É«ÇåÆÁ
//	HAL_Delay(500);
	Lcd_ColorBox(0,0,XSIZE_PHYS,YSIZE_PHYS,Red);//ÓúìÉ«ÇåÆÁ
//	HAL_Delay(500);
	Lcd_ColorBox(0,0,XSIZE_PHYS,YSIZE_PHYS,Green);//ÓÃÂÌÉ«ÇåÆÁ
//	HAL_Delay(500);
	Lcd_ColorBox(0,0,XSIZE_PHYS,YSIZE_PHYS,White);//Óð×É«ÇåÆÁ
	LCD_PutString(10,10,"STM32G474Test",Red,White,0);
	LCD_PutString(10,30,"I LOVE EEPW",Red,White,0);


  
  while (1)
  {
   
  }
  /* USER CODE END 3 */
}

MM.png

下图GIF显示通过SPI+DMA可以实现高速刷屏,比GPIO默默SPI快了几十倍。

666.gif

STM32G4的SPI DMA原理是通过结合SPI通信和DMA技术,实现高效、可靠的数据传输方式。这种方式能够释放CPU的负载,提高系统的性能,并广泛应用于各种嵌入式系统中。



院士
2025-04-01 23:44:06     打赏
2楼

SPI和DMA二者太配了。

对于速率的提升最显著了。



专家
2025-04-01 23:51:52     打赏
3楼

感谢分享


高工
2025-04-03 17:58:41     打赏
4楼

相对于前一版本软件模拟的SPI, SPI + DMA 在传输一整屏数据上,能释放多少CPU资源


高工
2025-04-03 23:45:50     打赏
5楼

 没看到设置SPI速度,是不是有机会把SPI的速度提高到接近驱屏IC支持的最高速率?


工程师
2025-04-04 08:54:28     打赏
6楼

代码中数据还阻塞式的发送,代码与标题不相符。


专家
2025-04-07 14:11:58     打赏
7楼

缺少必要的代码。只看提供的,不太好理解是如何实现DMA与SPI之间的数据处理过程,例如 LCD_PutString函数的实现过程


专家
2025-04-08 12:03:29     打赏
8楼

理论上提高很多,是否有屏幕刷新率问题?



助工
2025-04-08 14:34:17     打赏
9楼

写的很好, 这次核心代码有讲解了就很棒


共9条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]