STM32CRC校验入门介绍+固件库函数

    今天刚看了一点CRC校验的内容,在这里记录一下STM32F103C8T6关于CRC校验的内容,仅作入门了解。

    CRC校验通俗的来说其实就是一种验证数据的算法,跟串口通讯的奇偶校验本质上其实没有什么区别,就是复杂了一些。简单来说,就是通过你想要发送的数据,使用CRC校验算法,生成一个32位的数据,等你的数据被接收方接收到以后,接收方也使用这个CRC校验算法,将接收来的数据算一下,生成一个32位的数,拿你发送时算出来的结果,和接收后算出来的结果一比对,如果一样,那说明数据传输没问题,如果不一样,那说明数据有地方传错了。

    看一下手册:

第一条就说的是用的算法是啥,这个不用管。

第二条说的32位寄存器就是用来数据输入和读取CRC校验结果的,当你需要计算一些数据的CRC校验结果时,你只需要将数据32位、32位的传入到这个寄存器中,传完后就计算好了,需要这个结果的时候再读这个寄存器,读出来的32数就是算出来的CRC校验结果。需要注意的是,输入数据和读取结果,都用的是一个寄存器。

第三条就是计算时间。

第四条是CRC的另一个寄存器,通用的8位寄存器,这个寄存器可以用来存放一些临时数据,后面介绍有函数可以操作读写。

    上图是手册里的CRC 计算单元框图,总的流程就是数据通过AHB总线传输到数据寄存器,然后通过CEC计算得出结果,读结果的时候再通过AHB总线将结果发出去,需要注意的是,这个图中的数据寄存器(输入)和数据寄存器(输出),其实指的是同一个寄存器。

    功能描述可以看一下,需要注意的内容是,每次使用CRC校验时,需要先将这个数据寄存器进行清空,不然会影响到结果,然后如果输入的数据不足32位的话,会自动补齐到32位,最后说的那个CRC_CR指的是CRC中的控制寄存器,CRC一共有三个寄存器,前面说了两个,这是第三个,这个控制寄存器中只有1位有用,可以用来重置输入输出的32位数据寄存器。

    然后看一下相关库函数。

    下图是stm32f10x_crc.h中声明的库函数。

大概看一下:

①void CRC_ResetDR(void);

这个函数就是用来复位CRC的输入输出数据寄存器的,每次使用前要调用这个函数。

②uint32_t CRC_CalcCRC(uint32_t Data);

这个函数用来给输入输出的32位寄存器输入需要计算的值。如果数据比较长,那就一次输入32位,然后再最后一次输入后,读取这个函数的返回值,即CRC结果。

③uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength);

这个函数也是给输入输出的数据寄存器传数据的,返回的也是CRC校验结构。与上一个函数不同的是,这个函数可以传输数组,可以定义一个u32的数组,将数组当参数传给这个函数,函数的第二个参数是数据的长度。

④uint32_t CRC_GetCRC(void);

这个就是获取CRC结果的函数,不需要传数据。

⑤void CRC_SetIDRegister(uint8_t IDValue);

这个函数用来给通用8位寄存器写数据。

⑥uint8_t CRC_GetIDRegister(void);

这个函数用来读取通用8位寄存器的结果。

    总结:上面就是所以的函数了,在使用CRC校验时,先调用CRC_ResetDR函数,对CRC数据寄存器进行复位,再使用CalcCRC给数据寄存器传入数据,传入最后一个数据时读取寄存器数据,就可得到CRC校验结果。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这里我提供一个使用STM32固件库函数配置STM32F103的CAN通信的示例代码。在这个示例中,我们将使用CAN1接口和PA11和PA12引脚进行通信,这些引脚将用于CAN的RX和TX线路。 首先,需要在STM32CubeMX工具中配置CAN模块。具体步骤如下: 1. 打开STM32CubeMX工具,选择你的STM32F103型号。 2. 在“Pinout & Configuration”选项卡中选择CAN1模块,并将其映射到PA11和PA12引脚上。 3. 在“Configuration”选项卡中选择CAN1模块,并按照下图所示的方式配置CAN模块: ![CAN Configuration](https://i.imgur.com/vw8wJ8H.png) 4. 点击“GENERATE CODE”按钮,生成代码并打开工程。 接下来,需要添加以下代码来初始化和配置CAN模块: ```c #include "stm32f10x.h" #include "stm32f10x_can.h" #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" void CAN_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; CAN_InitTypeDef CAN_InitStructure; /* Enable CAN clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); /* Enable GPIO clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE); /* Configure CAN pin: RX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure CAN pin: TX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /* CAN register init */ CAN_DeInit(CAN1); /* CAN cell init */ CAN_StructInit(&CAN_InitStructure); /* CAN cell init */ CAN_InitStructure.CAN_TTCM = DISABLE; CAN_InitStructure.CAN_ABOM = DISABLE; CAN_InitStructure.CAN_AWUM = DISABLE; CAN_InitStructure.CAN_NART = DISABLE; CAN_InitStructure.CAN_RFLM = DISABLE; CAN_InitStructure.CAN_TXFP = DISABLE; CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq; CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq; CAN_InitStructure.CAN_Prescaler = 4; CAN_Init(CAN1, &CAN_InitStructure); /* Enable FIFO0 message pending Interrupt */ CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); /* NVIC Configuration */ NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } ``` 在以上代码中,首先初始化GPIO引脚并配置CAN模块,然后使用CAN_Init()函数初始化CAN模块,并使用CAN_ITConfig()函数启用FIFO0消息挂起中断。最后,使用NVIC_Init()函数配置CAN中断向量。 接下来,可以使用以下代码来发送CAN消息: ```c void CAN_Send(uint8_t* data, uint8_t len) { CanTxMsg TxMessage; /* Set up the message */ TxMessage.StdId = 0x123; TxMessage.ExtId = 0x00; TxMessage.RTR = CAN_RTR_DATA; TxMessage.IDE = CAN_ID_STD; TxMessage.DLC = len; TxMessage.Data[0] = data[0]; TxMessage.Data[1] = data[1]; /* Send the message */ if (CAN_Transmit(CAN1, &TxMessage) != CAN_TxStatus_NoMailBox) { /* Transmission request Mailbox has been successfully sent */ } } ``` 在以上代码中,首先定义一个CanTxMsg结构体,并设置其成员以指定要发送的消息的属性。然后,使用CAN_Transmit()函数发送消息。 最后,可以使用以下代码来接收CAN消息: ```c void USB_LP_CAN1_RX0_IRQHandler(void) { CanRxMsg RxMessage; /* Receive the message */ CAN_Receive(CAN1, CAN_FIFO0, &RxMessage); /* Process the message */ if (RxMessage.StdId == 0x123 && RxMessage.IDE == CAN_ID_STD && RxMessage.DLC == 2) { /* Handle the received data */ } } ``` 在以上代码中,在中断处理函数中使用CAN_Receive()函数从FIFO0中接收消息,并根据消息的属性进行相应的处理。 以上就是使用STM32固件库函数配置STM32F103的CAN通信的示例代码。需要注意的是,以上代码只是一个简单的示例,实际应用中需要根据具体情况进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值