5.5 CRC 使用说明

本章说明 N32G41x 标准外设库中 CRC 驱动的文件组成与 17 个公开函数,内容包括 CRC32 与 CRC16 校验值的计算、CRC32 独立数据寄存器与 CRC16 清除和大小端配置,以及 LRC 校验值的读写;示例 CalCRC 用软件算法复算硬件结果,CRC_DMA 用 DMA 搬运数据完成校验。生成多项式与 CRC32、CRC16 的使用流程请配合用户手册的“CRC 计算单元”章节阅读,芯片已知问题以勘误手册为准。

5.5.1 相关文件

相对路径 作用
firmware/n32g41x_std_periph_driver/inc/n32g41x_crc.h 定义 CRC16 清除、清除屏蔽、结果清零值与大端小端四个宏,并按 CRC32 计算、CRC16 底层配置、CRC16 计算、CRC16 LRC 四个区段声明 17 个公开函数
firmware/n32g41x_std_periph_driver/src/n32g41x_crc.c 实现上述 17 个函数:读写 CRC32 与 CRC16 的待校验数据、结果与独立数据寄存器,配置 CRC16 控制位,并读写 LRC 寄存器
projects/n32g41x_EVAL/examples/CRC/ CRC 示例根目录,含 CalCRC、CRC_DMA 2 个示例
projects/n32g41x_EVAL/examples/CRC/CalCRC/ 该示例的工程目录组成:MDK-ARM/、EWARM/、inc/、src/、readme.txt
projects/n32g41x_EVAL/bsp/ 两个示例共用的板级支持文件:串口日志初始化与 printf 重定向(log.h、log.c)

5.5.2 API 参考

搜索 API共 17 个函数

以下 17 个公开函数按 n32g41x_crc.h 的声明顺序分为 4 组;每个条目给出功能摘要与 n32g41x_crc.c 中该函数正上方的注释原文。

CRC32 计算

CRC32_ResetCrc、CRC32_CalcCrc、CRC32_CalcBufCrc、CRC32_GetCrc、CRC32_SetIDat、CRC32_GetIDat

CRC16 底层配置

__CRC16_SetLittleEndianFmt、__CRC16_SetBigEndianFmt、__CRC16_SetCleanEnable、__CRC16_SetCleanDisable

CRC16 计算

__CRC16_CalcCrc、__CRC16_SetCrc、__CRC16_GetCrc、CRC16_CalcBufCrc、CRC16_CalcCRC

CRC16 LRC

__CRC16_SetLRC、__CRC16_GetLRC

void CRC32_ResetCrc(void)复位 CRC 数据寄存器(DAT)。
源码注释
name    CRC32_ResetCrc.
fun     Resets the CRC Data register (DAT).
param   none
return  none
uint32_t CRC32_CalcCrc(uint32_t Data)计算给定 32 位数据字的 32 位 CRC。
源码注释
name    CRC32_CalcCrc.
fun     Computes the 32-bit CRC of a given data word(32-bit).
param   Data :
          - data word(32-bit) to compute its CRC
return  32-bit CRC
uint32_t CRC32_CalcBufCrc(const uint32_t pBuffer[], uint32_t BufferLength)计算给定 32 位数据缓冲区的 32 位 CRC。
源码注释
name    CRC32_CalcBufCrc.
fun     Computes the 32-bit CRC of a given buffer of data word(32-bit).
param   pBuffer :
          - pointer to the buffer containing the data to be computed
param   BufferLength :
          - length of the buffer to be computed
return  32-bit CRC

使用提示: 实现逐字写入 CRC->CRC32DAT 并在循环结束后返回 CRC->CRC32D,函数内部不改写 CRC32CTRL,初值沿用复位默认值 0xFFFF_FFFF 或上一次运算的结果。

uint32_t CRC32_GetCrc(void)返回当前 CRC 值。
源码注释
name    CRC32_GetCrc.
fun     Returns the current CRC value.
param   none
return  32-bit CRC
void CRC32_SetIDat(uint8_t IDValue)把 8 位数据存入独立数据(ID)寄存器。
源码注释
name    CRC32_SetIDat.
fun     Stores an 8-bit data in the Independent Data(ID) register.
param   IDValue :
          - 8-bit value to be stored in the ID register
return  none
uint8_t CRC32_GetIDat(void)返回独立数据(ID)寄存器中存储的 8 位数据。
源码注释
name    CRC32_GetIDat.
fun     Returns the 8-bit data stored in the Independent Data(ID) register.
param   none
return  8-bit value of the ID register
void __CRC16_SetLittleEndianFmt(void)设置待计算数据为小端格式。
源码注释
name    __CRC16_SetLittleEndianFmt.
fun     Set the calculate data to little endian format.
param   none
return  none
void __CRC16_SetBigEndianFmt(void)设置待计算数据为大端格式。
源码注释
name    __CRC16_SetBigEndianFmt.
fun     Set the calculate data to big endian format.
param   none
return  none
void __CRC16_SetCleanEnable(void)使能清除 CRC16 结果。
源码注释
name    __CRC16_SetCleanEnable.
fun     Enable Clean CRC16 value.
param   none
return  none
void __CRC16_SetCleanDisable(void)禁用清除 CRC16 结果。
源码注释
name    __CRC16_SetCleanDisable.
fun     Disable Clean CRC16 value.
param   none
return  none
uint16_t __CRC16_CalcCrc(uint8_t Data)计算给定 8 位数据字的 16 位 CRC。
源码注释
name    __CRC16_CalcCrc.
fun     Computes the 16-bit CRC of a given data word(8-bit).
param   Data :
          - data word(8-bit) to compute its CRC
return  16-bit CRC
void __CRC16_SetCrc(uint8_t Data)把 8 位数据写入 CRC16 数据寄存器(CRC16DAT)。
源码注释
name    __CRC16_SetCrc.
fun     Writes an 8-bit data to the CRC16 data register (CRC16DAT).
param   Data :
          - 8-bit data value to be written to the CRC16 data register
return  none
uint16_t __CRC16_GetCrc(void)返回当前 CRC 值。
源码注释
name    __CRC16_GetCrc.
fun     Returns the current CRC value.
param   none
return  16-bit CRC
uint16_t CRC16_CalcBufCrc(const uint8_t pBuffer[], uint32_t BufferLength)计算给定 8 位数据缓冲区的 16 位 CRC。
源码注释
name    CRC16_CalcBufCrc.
fun     Computes the 16-bit CRC of a given buffer of data word(8-bit).
param   pBuffer :
          - pointer to the buffer containing the data to be computed
param   BufferLength :
          - length of the buffer to be computed
return  16-bit CRC

使用提示: 实现先把 CRC->CRC16D 写为 CRC_CRC16D_CLEAR_VALUE(0x0000),再逐字节写入 CRC->CRC16DAT,最后返回 CRC->CRC16D。

uint16_t CRC16_CalcCRC(uint8_t Data)计算给定 8 位数据字的 16 位 CRC。
源码注释
name    CRC16_CalcCRC.
fun     Computes the 16-bit CRC of a given data word(8-bit).
param   Data :
          - data word(8-bit) to compute its CRC
return  16-bit CRC
void __CRC16_SetLRC(uint8_t Data)写入 LRC 初始值。
源码注释
name    __CRC16_SetLRC.
fun     Write LRC initial value.
param   Data :
          - 8-bit data
return  none
uint8_t __CRC16_GetLRC(void)返回当前 LRC 值。
源码注释
name    __CRC16_GetLRC.
fun     Returns the current LRC value.
param   none
return  8-bit LRC

5.5.3 Demo 示例说明

本节说明 CRC 的 2 个示例:CalCRC 用硬件与软件分别计算同一组数据的 CRC32、CRC16 并比较结果,CRC_DMA 用 DMA 通道搬运数据与读回结果来完成 CRC32、CRC16 与 LRC 校验。

5.5.3.1 CalCRC 硬件与软件 CRC 对比

工程目录: projects/n32g41x_EVAL/examples/CRC/CalCRC/

开启 CRC 时钟并初始化串口日志→硬件对 32 位数据缓冲区计算 CRC32→软件按同一多项式复算并比较→硬件对 8 位数据缓冲区计算 CRC16→软件复算并比较→经串口打印两项校验结论

项目 源码解读
功能 用硬件 CRC 与软件参考算法分别计算同一组数据的 32 位与 16 位校验值,逐一比较后经串口打印比较结论。
源码组成 src/main.c:main、软件参考算法 GetCRC16_Software 与 GetCRC32_Software、数据缓冲区;
inc/main.h:包含驱动与 BSP 头文件;
src/n32g41x_it.c、inc/n32g41x_it.h:中断服务函数;
readme.txt:功能、环境与使用说明;
MDK-ARM/、EWARM/:Keil 与 IAR 工程。
关键配置 BUFFER_SIZE 为 114,DataBuffer 为 114 个 32 位字,首字为 0x00001021;
Buffer 为 8 字节 0x7e、0x11、0x36、0x4e、0x55、0x0a、0xf1、0x1a。
软件 CRC16 多项式 CRC16_DFE_POLY 为 0x8005,软件 CRC32 多项式 CRC32_DFE_POLY 为 0x04C11DB7;
软件 CRC32 初值传 0xffffffff,软件 CRC16 初值传 0x00。
系统时钟为 HSI+PLL,N32G412 为 80 MHz、N32G415 为 96 MHz;
打印串口为 PA9、115200 bps。
程序与数据路径 main 先开 CRC 时钟并调用 log_init 初始化串口;
CRC32_CalcBufCrc 对 DataBuffer 的 114 个字求硬件 CRC32,GetCRC32_Software 复算同一缓冲区,相等时打印 CRC32 calculation is correct!;
随后 CRC16_CalcBufCrc 对 Buffer 的 8 字节求硬件 CRC16,GetCRC16_Software 复算,相等时打印 CRC16 calculation is correct!;
最后进入空的 while (1)。
主要 API CRC32_CalcBufCrc、CRC16_CalcBufCrc
验证方法 复位运行后观察串口输出:应出现 CRC32 calculation is correct! 与 CRC16 calculation is correct!;
出现以 error 结尾的提示说明硬件与软件结果不一致。
使用提示 开发环境为 KEIL MDK-ARM V5.34 或 IAR EWARM 8.50.1,基于 N32G41x 评估板;
串口打印为 PA9、115200 bps。
核心代码解读与移植

示例让同一组数据分别跑硬件 CRC 与软件参考算法,通过比较两者结果验证硬件计算。

数据路径: DataBuffer、Buffer → CRC32_CalcBufCrc、CRC16_CalcBufCrc 写入 CRC->CRC32DAT、CRC->CRC16DAT 并读回结果 → GetCRC32_Software、GetCRC16_Software 逐位复算 → 比较结果后经 printf 输出

1. 定义校验数据与多项式。 数据规模与两条生成多项式由文件顶部的宏给出,硬件与软件两路使用同一组数据。

src/main.csrc/main.c
#define BUFFER_SIZE    114
#define CRC16_DFE_POLY 0x8005
#define CRC32_DFE_POLY 0x04C11DB7

移植到自己的数据时同步改 BUFFER_SIZE 与 DataBuffer、Buffer 的元素个数,更换生成多项式时同步改这两个宏。

2. 打开 CRC 时钟并先算硬件 CRC32。 main 打开 CRC 时钟、初始化串口后先算硬件 CRC32,再算软件 CRC32,两者都作用在 DataBuffer 上。

src/main.csrc/main.c · main
    /* Enable CRC clock */
    RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_CRC, ENABLE);

    log_init();

    /* Compute the 32-bit CRC of DataBuffer using hardware */
    CRC32Value = CRC32_CalcBufCrc((uint32_t*)DataBuffer, BUFFER_SIZE);

    /* Compute the 32-bit CRC of DataBuffer using software */
    CRCValue   = GetCRC32_Software((uint32_t*)DataBuffer, BUFFER_SIZE, 0xffffffff);

CRC32_CalcBufCrc 只逐字写入 CRC->CRC32DAT 再读回 CRC->CRC32D,函数内部不复位 CRC32,硬件初值取 CRC_CRC32DAT 的复位值 0xFFFF_FFFF;软件侧传入的初值 0xffffffff 必须与之一致,结果才有可比性。

3. 软件参考算法逐位复算。 GetCRC32_Software 对每个字按位左移并异或生成多项式,得到与硬件一致的 CRC32。

src/main.csrc/main.c · GetCRC32_Software
    for (i = 0; i < len; i++)
    {
        xbit = 0x80000000;

        for (bits = 0; bits < 32; bits++)
        {
            if (crc32 & 0x80000000)
            {
                crc32 <<= 1;
                crc32 ^= CRC32_DFE_POLY;
            }
            else
            {
                crc32 <<= 1;
            }

            if (buf[i] & xbit)
            {
                crc32 ^= CRC32_DFE_POLY;
            }

            xbit >>= 1;
        }
    }

这段只处理 32 位字;换成字节或半字数据时,字长、位宽与多项式都要与硬件侧同步调整。

4. 比较结果并打印结论。 把易失变量读入局部变量后比较,相等则打印正确、否则打印错误;16 位一路用同样的方式再比一次。

src/main.csrc/main.c · main
    /* Read volatile values into local variables to avoid undefined access order */
    crc32_hw = CRC32Value;
    crc32_sw = CRCValue;
    if (crc32_hw == crc32_sw)
    {
        printf(" CRC32 calculation is correct! \r\n");
    }
    else
    {
        printf(" CRC32 calculation error! \r\n");
    }

    /* Compute the 16-bit CRC of Buffer using hardware */
    CRC16Value = CRC16_CalcBufCrc((uint8_t*)Buffer, 8);

    /* Compute the 16-bit CRC of Buffer using software */
    CRCValue   = GetCRC16_Software((uint8_t*)Buffer, 8, 0x00);

CRC16_CalcBufCrc 会先把 CRC->CRC16D 写为 0x0000 再累加,软件侧初值 0x00 与之对应;移植时这一段的数据长度 8 要与 Buffer 的实际元素个数一致。

对应源码: src/main.c、inc/main.h

5.5.3.2 CRC_DMA 通过 DMA 搬运完成校验

工程目录: projects/n32g41x_EVAL/examples/CRC/CRC_DMA/

开启 CRC 与 DMA 时钟并初始化串口→复位 CRC32 计算单元→用 DMA 把 32 位数据送入 CRC32 计算→用 DMA 把 8 位数据送入 CRC16 计算→经 DMA 读回校验结果并与期望值比较→串口打印 CRC32、CRC16 与 LRC 结果

项目 源码解读
功能 用 DMA 通道把内存中的字、字节数据搬入 CRC 待校验数据寄存器,验证 CRC32、CRC16 与 LRC 的硬件计算结果,并把结果寄存器经 DMA 读回内存。
源码组成 src/main.c:main 与 assert_failed;
src/crc_dma.c:TestCrc32AndDma、TestCrc16AndDma 与两个数据缓冲区;
inc/main.h:包含驱动与 BSP 头文件;
src/n32g41x_it.c、inc/n32g41x_it.h:中断服务函数;
readme.txt:功能、环境与使用说明;
MDK-ARM/、EWARM/:Keil 与 IAR 工程。
关键配置 CRC_original_word_data 为 114 个 32 位字,首字为 0x00001021;
CRC_original_byte_data 为 456 字节,与字数据逐字节对应。
DMA 使用 DMA_CH1,Mem2Mem 为 DMA_M2M_ENABLE、Priority 为 DMA_PRIORITY_VERY_HIGH、CircularMode 为 DMA_MODE_NORMAL;
CRC32 搬运 MemDataSize 为 DMA_MemoryDataSize_Word、BufSize 为 114,CRC16 搬运 MemDataSize 为 DMA_MemoryDataSize_Byte、BufSize 为 456。
CRC16 运算前选大端格式并带结果清除。
期望值为 CRC32 的 0x379E9F06、CRC16 的 0x5268、LRC 的 0x00。
程序与数据路径 main 开 CRC 与 DMA 时钟、log_init 后打印 CRC DMA test start.,调用 CRC32_ResetCrc 复位 CRC32,再依次调用 TestCrc32AndDma、TestCrc16AndDma;
前者两次配置 DMA_CH1,完成内存到 CRC32 待校验数据寄存器、结果寄存器到内存的搬运,读回后与期望值比较;
后者先设 CRC16 初值与 LRC 初值、使能清除并选大端,再用 DMA 搬运 456 字节,读回 CRC16D 与 LRC 后比较。
主要 API CRC32_ResetCrc、CRC32_GetCrc、__CRC16_SetCrc、__CRC16_SetLRC、__CRC16_SetCleanEnable、__CRC16_SetBigEndianFmt、__CRC16_GetCrc、__CRC16_GetLRC
验证方法 复位运行后观察串口:应打印 CRC32 为 0x379e9f06、CRC16 为 0x5268、LRC 为 0x00,且不出现以 error 结尾的提示行。
使用提示 开发环境为 KEIL MDK-ARM V5.34 或 IAR EWARM 8.50.1,基于 N32G41x 评估板;
串口打印为 PA9、115200 bps;
示例依赖 DMA 驱动。
核心代码解读与移植

示例用 DMA 通道代替软件写寄存器,在数据缓冲区和结果寄存器之间来回搬运,再由读回的值判断校验结果。

数据路径: CRC_original_word_data、CRC_original_byte_data → DMA_Init、DMA_EnableChannel 搬入 CRC->CRC32DAT、CRC->CRC16DAT → CRC32_GetCrc、__CRC16_GetCrc、__CRC16_GetLRC 或 DMA 读回结果 → printf 打印并与期望值比较

1. 打开 CRC 与 DMA 时钟并复位 CRC32。 main 同时打开两个外设的 AHB 时钟,初始化串口后先复位 CRC32,再进入两个测试函数。

src/main.csrc/main.c · main
    /* Enable CRC and DMA clock */
    RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_CRC | RCC_AHB_PERIPH_DMA, ENABLE);

    log_init();

    printf(" CRC DMA test start.\r\n");

    CRC32_ResetCrc();

    TestCrc32AndDma();
    TestCrc16AndDma();

两个测试函数都依赖 DMA,移植到其它工程时要同时把 CRC 与 DMA 驱动的源文件加入编译。

2. 用 DMA 把字数据搬入 CRC32。 DMA 通道把 CRC_original_word_data 的 114 个字逐个搬到 CRC 的 32 位待校验数据寄存器,搬运结束后由传输完成标志退出等待。

src/crc_dma.csrc/crc_dma.c · TestCrc32AndDma
    /* Memory -> CRC32DAT */
    DMA_InitStructure.PeriphAddr     = (uint32_t)&CRC->CRC32DAT;
    DMA_InitStructure.MemAddr        = (uint32_t)CRC_original_word_data;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_DST;
    DMA_InitStructure.Mem2Mem        = DMA_M2M_ENABLE;
    DMA_InitStructure.MemDataSize    = DMA_MemoryDataSize_Word;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_WORD;
    DMA_InitStructure.DMA_MemoryInc  = DMA_MEM_INC_ENABLE;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;
    DMA_InitStructure.CircularMode   = DMA_MODE_NORMAL;
    DMA_InitStructure.Priority       = DMA_PRIORITY_VERY_HIGH;
    DMA_InitStructure.BufSize        = 114;

    DMA_Init(DMA_CH1, &DMA_InitStructure);
    DMA_EnableChannel(DMA_CH1, ENABLE);
    while (!DMA_GetFlagStatus(DMA_FLAG_TC1, DMA));
    DMA_DeInit(DMA_CH1);

外设地址固定为结果寄存器不动、存储地址自增,每个字依次进入 CRC;更换缓冲区时同步改 MemAddr 与 BufSize,字节数据要改用字节宽度。

3. 读回 CRC32 结果并与期望值比较。 搬运结束后用 CRC32_GetCrc 读结果寄存器,再与固定期望值比较,不符则打印错误。

src/crc_dma.csrc/crc_dma.c · TestCrc32AndDma
    CRC32_Value = CRC32_GetCrc();
    printf("The CRC 32 code after Memory->CRC32DAT DMA transmission is %08x.\r\n", CRC32_GetCrc());

    if (CRC32_Value != 0x379E9F06)
        printf("The CRC 32 code computed through DMA transmission is error, it should be 0x379E9F06.\r\n");

期望值 0x379E9F06 对应这组固定的 114 字数据;更换数据或多项式后这个比较值必须同步重算。

4. 设定 CRC16 初值、清除与大端格式后再搬运。 进入 CRC16 搬运前先设初值、清除结果并选大端,再按字节宽度把 456 字节搬入。

src/crc_dma.csrc/crc_dma.c · TestCrc16AndDma
    __CRC16_SetCrc(0x00);
    __CRC16_SetLRC(0x00);
    __CRC16_SetCleanEnable();
    __CRC16_SetBigEndianFmt();

    /* Memory -> CRC16DAT */
    DMA_InitStructure.PeriphAddr     = (uint32_t)&CRC->CRC16DAT;
    DMA_InitStructure.MemAddr        = (uint32_t)CRC_original_byte_data;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_DST;
    DMA_InitStructure.Mem2Mem        = DMA_M2M_ENABLE;
    DMA_InitStructure.MemDataSize    = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;
    DMA_InitStructure.DMA_MemoryInc  = DMA_MEM_INC_ENABLE;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;
    DMA_InitStructure.CircularMode   = DMA_MODE_NORMAL;
    DMA_InitStructure.Priority       = DMA_PRIORITY_VERY_HIGH;
    DMA_InitStructure.BufSize        = 456;

    DMA_Init(DMA_CH1, &DMA_InitStructure);
    DMA_EnableChannel(DMA_CH1, ENABLE);
    while (!DMA_GetFlagStatus(DMA_FLAG_TC1, DMA));
    DMA_DeInit(DMA_CH1);

__CRC16_SetBigEndianFmt 把 ENDIAN 位清 0,使待校验数据从高位到低位运算;__CRC16_SetCleanEnable 置清除位,结果寄存器先取默认值 0x0000。数据端序或初值不一致会直接改变 CRC16 结果。

5. 读回 CRC16 与 LRC 结果并比较。 搬运完成后分别读结果寄存器与 LRC 寄存器,与期望值比较。

src/crc_dma.csrc/crc_dma.c · TestCrc16AndDma
    CRC16_Value = __CRC16_GetCrc();
    LRC_Value = __CRC16_GetLRC();

    printf("The CRC 16 code after Memory->CRC16DAT DMA transmission is %04x.\r\n", __CRC16_GetCrc());
    if (CRC16_Value != 0x5268)
        printf("The CRC 16 code computed through DMA transmission is error, it should be 0x5268.\r\n");

    printf("The LRC code after Memory->CRC16DAT DMA transmission is %02x.\r\n", __CRC16_GetLRC());
    if (LRC_Value != 0x00)
        printf("The LRC code computed through DMA transmission is error, it should be 0x00.\r\n");

CRC 与 LRC 计算同时进行,读 CRC->LRC 得到的是同一组数据的 LRC 校验值;本例数据对应的期望值为 CRC16 的 0x5268、LRC 的 0x00。

对应源码: src/main.c、src/crc_dma.c、inc/main.h

5.5.4 注意与排障

场景 检查与建议 来源
CRC32 结果初值与复位 CRC_CRC32CTRL.RESET 只能写 1,硬件自动清 0,置位后把 CRC_CRC32D 置为 0xFFFF_FFFF;
不置位时初值沿用上一次运算的结果,新一轮校验前应复位或自行写入初值。
用户手册
CRC16 结果的清除与数据端序 CRC_CRC16CTRL.CLEAR 为只写清、软件置 1 仅维持一个周期(软件读恒为 0),置 1 后结果取默认值 0x0000;
CRC_CRC16CTRL.ENDIAN 只作用于待校验数据,0 为高位到低位、1 为低位到高位。
用户手册
LRC 的读取与清零 CRC 与 LRC 计算同时进行,读 CRC_LRC 后下次运算前应软件清零,否则结果会延续上次的值。 用户手册
保留位与访问宽度 CRC_CRC32CTRL 位 31:1、CRC_CRC32IDAT 位 31:8、CRC_CRC16CTRL 位 31:3 与位 0、CRC_CRC16DAT 位 31:8、CRC_CRC16D 位 31:16、CRC_LRC 位 31:8 为保留位,必须保持复位值;
CRC16 相关寄存器支持 8 位、16 位、32 位操作。
用户手册

N32G412、N32G415 系列勘误手册 V1.0.0(2026.6.30)的勘误列表只列出一行 A 版芯片条目,勘误链接列为空,未列出 CRC 相关条目。

国民技术开发套件文档中心

按芯片系列在线查阅国民技术 MCU 开发套件的芯片资料、SDK、驱动 API 与 Demo 示例说明。

© 2026 国民技术股份有限公司 版权所有粤ICP备11069485号本站使用不含 Cookie 的匿名访问统计