你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【开发经验】LAT1500 如何通过DMA配合CRC功能

[复制链接]
攻城狮Melo 发布时间:2026-3-2 13:29

LAT1500 如何通过 DMA 配合 CRC 功能

【应用笔记】LAT1500 如何通过DMA配合CRC功能

关键字:CRC, DMA,AHB,STM32G4,AN4187

LAT1500 – Rev 1.0– Jan. 2025

1. 概述

STM32 的 CRC 外设是用来实现 CRC 计算的硬件单元,硬件实现 CRC 计算相对于软件算法实现来说,可以大大提高运算速度。CRC 计算单元具有单个 32 位读 / 写数据寄存器 (CRC_DR)。它用于输入新数据 (写访问) 并保存以前的 CRC 计算结果 (读访问)。当 DMA 用作数据传输处理器时,可以极大地减轻 CPU 负荷。本文以 STM32G474 为例,介绍如何通过 DMA 配合 CRC 计算,以供读者参考。

2. 原理

2.1. 时间上的可能性

单次 DMA 传输包括两个 AHB 传输阶段,通过 DMA AHB 总线 master 实现:

  • 通过内部当前外设 / 存储器地址寄存器进行寻址,从外设数据寄存器或存储器单元中读取单个数据 (字节、半字或字)。
  • 通过内部当前外设 / 存储器地址寄存器进行寻址,向外设数据寄存器或存储器单元中写入单个数据 (字节、半字或字)。 image.png

从上面解释可以看出,单次 DMA 传输可以传输单个数据 (字节,半字或字),其中包含两个传输过程,一次 AHB 读传输过程以及一次 DMA 写传输过程。

从 AHB 协议的描述中可以看到,一次 AHB 传输分为两个阶段,分别是地址阶段和数据阶段,这两个阶段即使在最快的情况下也各需要一个 AHB 时钟周期。即一次 AHB 传输至少需要两个 AHB 时钟周期。

HWRITE 控制着与主设备之间的数据传输方向。因此:

  • 当 HWRITE 为高电平时,表示写传输,主设备在写数据总线 HWDATA 上广播数据
  • 当 HWRITE 为低电平时,执行读传输,从设备必须在读取数据总线 HRDATA 上生成数据

最简单的传输是无等待状态的传输,因此该传输包括一个地址周期和一个数据周期。 image.png

从上面的分析可以看出,单次 DMA 传输至少 4 个 AHB 时钟周期,如果加上寻址计算等操作,需要的时间可能更多。

而 CRC 单次计算,最多需要 4 个 AHB 时钟周期:

CRC_DR 寄存器可以按字、右对齐半字和右对齐字节访问。对于其他寄存器,仅允许 32 位访问。计算的持续时间取决于数据宽度:32 位为 4 个 AHB 时钟周期,16 位为 2 个 AHB 时钟周期,8 位为 1 个 AHB 时钟周期。 image.png

综上所述,在 AHB 总线上一次读 + 写就至少需要 4 个 AHB 时钟周期,这就已经可以满足 CRC 单次计算所需的时间。所以单次 DMA 数据传输之后即可进行下次数据传输 (背靠背传输),无需额外等待。

2.2. 内部连接的可能性

CRC 外设寄存器是挂在 AHB1 总线上的,具体地址映射如下: image.png

总线矩阵提供从主器件 (master) 到从器件 (slave) 的访问。DMA 作为 Master,而 SRAM、FLASH 以及 AHB1 外设都是作为 Slave。所以 DMA 可以通过总线矩阵对 SRAM、FLASH 以及 CRC 外设进行访问,也即通过 DMA 传输数据到 CRC 是可行的。

系统架构主要由 32 位多层 AHB 总线矩阵组成,该矩阵互连:

最多五个主设备:带 FPU 内核的 Cortex-M4 I 总线、带 FPU 内核的 Cortex-M4 D 总线、带 FPU 内核的 Cortex-M4 S 总线、DMA1、DMA2;

最多九个从设备:ICode 总线上的内部闪存、DCode 总线上的内部闪存、内部 SRAM1、内部 SRAM2、内部 CCM SRAM、包含 AHB 到 APB 桥和 APB 外设的 AHB1 外设(连接到 APB1 和 APB2)、AHB2 外设、灵活静态存储器控制器 (FSMC)、四路 SPI 存储器接口 (QUADSPI)。

总线矩阵提供从主设备到从设备的访问,即使多个高速外设同时工作,也能实现并发访问和高效操作。 image.png

2.3. DMA 传输方式

由于 CRC 是一个简单的计算单元,计算完成时直接将结果放到 CRC_DR 寄存器中,所以没有信号来触发 DMA 传输。

DMA 控制器可以在没有外设请求触发的情况下运行,这种模式叫做 Memory-to-memory 模式,由软件发起传输。所以我们必须将 DMA 的传输模式设置为 Memory-to-memory 模式。DMA 在数据传输期间,CPU 仅在 CRC 和 DMA 配置期间以及 DMA 中断处理程序执行期间进行干预,极大的减少 CPU 负载。

Memory-to-memory 模式说明

DMA 通道可以在没有外设请求触发的情况下运行,此模式称为存储器到存储器模式,由软件启动。如果设置了 DMA_CCRx 寄存器中的 MEM2MEM 位,则该通道(如果启用)将启动传输,一旦 DMA_CNDTRx 寄存器达到零,传输将停止。

注意

存储器到存储器模式不得在循环模式下使用。在以存储器到存储器模式(MEM2MEM=1)启用通道之前,软件必须清除 DMA_CCRx 寄存器的 CIRC 位。 image.png

3. 实现

这里以 NUCLEO-G474RE 为例进行介绍,这里不对基本操作做过多介绍,只介绍与 DMA 和 CRC 相关的配置部分,详细配置可参考附件。

3.1. 创建工程

  1. 使用 STM32CubeMX 选择 STM32G474RET6 创建工程。然后选择 CRC 外设,点击 "Activated" 选项。本例的 "Input Data Format" 参数配置为 "Words",其他参数保持默认,实际应用中可根据需求配置,至此 CRC 外设配置完毕。 image.png
  2. 找到 DMA 外设,点击 "Add" 添加 DMA Request,并选择 "MemToMem" 模式。 image.png
  3. 配置保持默认即可,Mode 设置为 "Normal"。需注意 "Dst Memory" 不要勾选,因为 CRC_DR 寄存器的地址是固定的。"Data Width" 配置为 Byte、Half Word 或者 Word 都可以,本示例中配置为 Word。 image.png
  4. 配置 DMA 中断,在 "NVIC" 里面 Enable "DMA1 channel1 global interrupt",注意该配置与实际使用的 DMA 相关,本例中使用的是 DMA1。 image.png
  5. 然后点击 "GENERATE CODE" 生成代码。

3.2. 软件配置

本例中将 114 个 32-bit 数据放在 "aDataBuffer" 数组中,使用 CRC 外设默认参数的计算结果为 "0x379E9F06"。

c

运行

#define BUFFER_SIZE 114
static const uint32_t aDataBuffer[BUFFER_SIZE] = {
0x00001021, 0x20423063, 0x408450a5, 0x60c670e7, 0x9129a14a, 0xb16bc18c, 0xd1ade1ce, 0xf1ef1231, 0x32732252, 0x52b54294, 0x72f762d6, 0x93398318, 0xa35ad3bd, 0xc39cf3ff, 0xe3de2462, 0x34430420, 0x64e674c7, 0x44a45485, 0xa56ab54b, 0x85289509, 0xf5cfc5ac, 0xd58d3653, 0x26721611, 0x063076d7, 0x569546b4, 0xb75ba77a, 0x97198738, 0xf7dfe7fe, 0xc7bc48c4, 0x58e56886, 0x78a70840, 0x18612802, 0xc9ccd9ed, 0xe98ef9af, 0x89489969, 0xa90ab92b, 0x4ad47ab7, 0x6a961a71, 0x0a503a33, 0x2a12dbfd, 0xfbbfeb9e, 0x9b798b58, 0xbb3bab1a, 0x6ca67c87, 0x5cc52c22, 0x3c030c60, 0x1c41edae, 0xfd8fcdec, 0xad2abd0b, 0x8d689d49, 0x7e976eb6, 0x5ed54ef4, 0x2e321e51, 0x0e70ff9f,
0xefbedfdd, 0xcffcbf1b, 0x9f598f78, 0x918881a9, 0xb1caa1eb, 0xd10cc12d, 
0xe16f1080, 0x00a130c2, 0x20e35004, 0x40257046, 0x83b99398, 0xa3fbb3da, 
0xc33dd31c, 0xe37ff35e, 0x129022f3, 0x32d24235, 0x52146277, 0x7256b5ea, 
0x95a88589, 0xf56ee54f, 0xd52cc50d, 0x34e224c3, 0x04817466, 0x64475424, 
0x4405a7db, 0xb7fa8799, 0xe75ff77e, 0xc71dd73c, 0x26d336f2, 0x069116b0, 
0x76764615, 0x5634d94c, 0xc96df90e, 0xe92f99c8, 0xb98aa9ab, 0x58444865, 
0x78066827, 0x18c008e1, 0x28a3cb7d, 0xdb5ceb3f, 0xfb1e8bf9, 0x9bd8abbb, 
0x4a755a54, 0x6a377a16, 0x0af11ad0, 0x2ab33a92, 0xed0fdd6c, 0xcd4dbdaa, 
0xad8b9de8, 0x8dc97c26, 0x5c644c45, 0x3ca22c83, 0x1ce00cc1, 0xef1fff3e, 
0xdf7caf9b, 0xbfba8fd9, 0x9ff86e17, 0x7e364e55, 0x2e933eb2, 0x0ed11ef0 
}; 

/** 
* @ Brief Expected CRC Value(Default configuration) 
* @ Width : 32 
* @ Poly : 0x04C11DB7 
* @ Init : 0xFFFFFFFF 
* @ RefIn : False 
* @ RefOut : False 
* @ XorOut : 0x00000000 
*/
const uint32_t uwExpectedCRCValue = 0x379E9F06;

由于已经配置了 DMA,STM32CubeMX 生成代码时会生成相应的句柄,本例中生成的 DMA 句柄为hdma_memtomem_dma1_channel1image.png

这里我们添加一个 DMA 中断传输完成回调函数,中断传输完成时 HAL 库中断处理函数会调用该回调函数,传输完成后可通过读取 CRC_DR 寄存器获取计算结果(本例使用uwCRCValue获取 CRC 计算结果)。

c

运行

/**
* @brief DMA CRC transmit process complete callback. 
* @param hdma DMA handle. 
* @retval None 
*/
static void UART_DMACrcTransferCpltCallback(DMA_HandleTypeDef *hdma) {
if(hdma->Instance == DMA1_Channel1) {
/* Get the CRC computed value */ 
uwCRCValue = hcrc.Instance->DR;
}
}

在开始计算之前,首先使用HAL_DMA_RegisterCallback将上述回调函数注册到 DMA 句柄中,然后重置 CRC 数据寄存器,最后开启 DMA 传输。

c

运行

/* USER CODE BEGIN 2 */ 
/* Set the DMA CRC transfer complete callback */ 
HAL_DMA_RegisterCallback(&hdma_memtomem_dma1_channel1, 
HAL_DMA_XFER_CPLT_CB_ID, UART_DMACrcTransferCpltCallback); 
/* Reset CRC Calculation Unit (hcrc->Instance->INIT is written in hcrc->Instance->DR) */ 
__HAL_CRC_DR_RESET(&hcrc); 
/* Start the DMA Transfer with interrupt enabled */ 
HAL_DMA_Start_IT(&hdma_memtomem_dma1_channel1, (uint32_t)aDataBuffer, 
(uint32_t)&(hcrc.Instance->DR), BUFFER_SIZE); 
/* USER CODE END 2 */

3.3. 运行结果

运行结果与理论值一致,可成功获取 CRC 计算结果。 image.png

4. 小结

本文对通过 DMA 配合 CRC 应用从原理上进行了可行性分析,并且介绍了该功能的具体实现过程,希望能对读者有所帮助。

收藏 评论0 发布时间:2026-3-2 13:29

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版