STM32的CRC_Calculation(免费)
stm32f103的crc原理
![stm32f103的crc原理](https://img.taocdn.com/s3/m/c72a9e4777c66137ee06eff9aef8941ea66e4b70.png)
stm32f103的crc原理
STM32F103的CRC计算单元是根据固定的生成多项式得到任一32位全字的CRC计算结果。
具体来说,CRC计算的基本原理是在一个p位二进制数据序列之后附加一个r位二进制检验码(序列),从而构成一个总长为
n=p+r位的二进制序列。
附加在数据序列之后的这个检验码与数据序列的
内容之间存在着某种特定的关系,如果数据序列中的某一位或某些位发生错误,这种特定关系就会被破坏。
因此,通过检查这一关系,就可以实现对数据正确性的检验。
STM32F103的CRC计算单元包括2个数据寄存器和1个控制寄存器。
其中,数据寄存器用于存储要进行CRC计算的新数据,独立数据寄存器用于
存储CRC计算的结果,而控制寄存器则用于控制CRC计算单元的工作模式。
在STM32F103中,CRC计算单元使用硬件实现,可以在4个AHB时钟周期(HCLK)内完成32位全字的CRC计算。
相比于纯软件实现,硬件实现
可以大大提高计算速度,特别是在处理大量数据时。
如需更多关于STM32F103 CRC计算原理的相关信息,建议查询专业网站
或论坛。
基于STM32的CRC校验说明
![基于STM32的CRC校验说明](https://img.taocdn.com/s3/m/d85af3aef021dd36a32d7375a417866fb84ac0de.png)
基于STM32的CRC校验说明///*****************************************************************************//下⾯是test.c⾥⾯的函数///*****************************************************************************//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////串⼝猎⼈⽤的程序 ////////////值得说明的是,CRC协议同样适⽤于串⼝猎⼈适⽤,也就是”协议”是通⽤的 ////////// USART1->DR=num; //////////串⼝猎⼈只能发送hex值,即只能发送16进制的数据,才能显⽰出波形 /////////// while((USART1->SR&0X40)==0); ////////// delay_ms(500); ////////// num-=1; ////////// if(num==0x00) ////////// num=0xff; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////值得说明的是,CRC协议同样适⽤于串⼝猎⼈适⽤,也就是”协议”是通⽤的 //////////串⼝助⼿⽤的程序 ////////// printf("%d ",0XA5); ////////// printf("%d ",t); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Visualscope串⼝⽰波器的程序 ////////////////for(i=0;i<4;i++)//先装载数据 ////////{ ////////OutData[i]= num; ////////num-=70; ////////} ////////num=0xff; ////////OutPut_Data();//调⽤主函数 ////////delay_ms(10);//定义发送频率 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*****************************************************************************//下⾯是USART.H⾥⾯的函数///*****************************************************************************//串⼝⽰波器的变量extern float OutData[4];//这是全局变量unsigned short CRC_CHECK(unsigned short *Buf, unsigned short CRC_CNT);void voTxIsr(void);void OutPut_Data();///*****************************************************************************//下⾯的是USART.C⾥⾯的⽂件//这⾥⽤到了串⼝接收数据中断函数,所以需要把原先的数据串⼝中断函数屏蔽了///*****************************************************************************//the following is MCU code for CRC16 ,please refer.//-------------------------------------------------------------------------------------------#define ULONG unsigned long#define RxCountMax 18//float OutData[4]; 这个是全局变量,在main函数和USART.H中都有定义unsigned short TxBuf[10];unsigned short RxBuf[RxCountMax];unsigned short RxCnt;unsigned short TxCnt;unsigned short Rx50msCnt;unsigned long pAddr1,pAddr2,pAddr3,pAddr4;//CRC16校验算法unsigned short CRC_CHECK(unsigned short *Buf, unsigned short CRC_CNT){unsigned short CRC_Temp;unsigned char i,j;CRC_Temp = 0xffff;for (i=0;i<CRC_CNT; i++){CRC_Temp ^= Buf[i];for (j=0;j<8;j++) {if (CRC_Temp & 0x01)CRC_Temp = (CRC_Temp >>1 ) ^ 0xa001;elseCRC_Temp = CRC_Temp >> 1;}}return(CRC_Temp);}//Receive interrupt routine 串⼝接收中断函数void USART1_IRQHandler(void){unsigned short i,CRC_RX,CRC_Tmp;RxBuf[RxCnt] = USART1->DR; //acquire data 接收数据RxCnt++;if(RxCnt == RxCountMax) {CRC_Tmp = CRC_CHECK(RxBuf,16); //CRC Calculation 计算接收到的数据的CRC校验值CRC_RX = ((unsigned short)RxBuf[RxCountMax-1]<<8) + RxBuf[RxCountMax-2]; //接收的数据中的最后两位就是CRC校验值if(CRC_Tmp == CRC_RX){ //⽐较两个校验值是否相同LED0=~LED0; //这⾥是我做的⼀个现象,通信成功就亮/灭⼀下灯pAddr1 = ((ULONG)(RxBuf[0x3])<<24)|((ULONG)(RxBuf[0x2])<<16)|((ULONG)(RxBuf[0x1])<<8)|RxBuf[0x0]; //然后把数据保存起来 pAddr2 = ((ULONG)(RxBuf[0x7])<<24)|((ULONG)(RxBuf[0x6])<<16)|((ULONG)(RxBuf[0x5])<<8)|RxBuf[0x4];pAddr3 = ((ULONG)(RxBuf[0xB])<<24)|((ULONG)(RxBuf[0xA])<<16)|((ULONG)(RxBuf[0x9])<<8)|RxBuf[0x8];pAddr4 = ((ULONG)(RxBuf[0xF])<<24)|((ULONG)(RxBuf[0xE])<<16)|((ULONG)(RxBuf[0xD])<<8)|RxBuf[0xC];}RxCnt = 0;}Rx50msCnt = 0;//to add--Clear Receive Data Register Fll flag;// USART1->DR=res;// while((USART1->SR&0X40)==0);//}//Transfer interrupt routine 串⼝发送数据函数void voTxIsr(void){if(TxCnt <= 9){USART1->DR = TxBuf[TxCnt];//Clear Tx interrupt flagTxCnt++;if(TxCnt >= 10){//send interrupt disableTxCnt=0;}}}//-------------------------------------------------------------------------------------------//Monitor routine Execute every T Period time 应⽤函数,在主函数中直接调⽤这个就可以了void OutPut_Data(){int temp[4] = {0};unsigned int temp1[4] = {0};unsigned short databuf[10] = {0};unsigned char i;unsigned short CRC16 = 0;for(i=0;i<4;i++){temp[i] = (u16)OutData[i]; //把要发送的数据传过来temp1[i] = (u16)temp[i]; //并复制⼀份数据,进⾏下⾯的处理}for(i=0;i<4;i++){databuf[i*2] = (u8)(temp1[i]%256); //⾼低位处理databuf[i*2+1] = (u8)(temp1[i]/256);}CRC16 = CRC_CHECK(databuf,8); //计算要发送数据的CRC16校验值 databuf[8] = CRC16%256; //并保存在databuf的8 9⾥⾯databuf[9] = CRC16/256;for(i=0;i<10;i++)//把数据和校验位⼀起发送出去{// voTxIsr();if(TxCnt <= 9){USART1->DR = databuf[TxCnt];//发送数据给寄存器while((USART1->SR&0X40)==0);//直到发送完成才结束发送TxCnt++;if(TxCnt >= 10){TxCnt=0; //准备下次发送数据}}}}。
STM32 CRC计算单元
![STM32 CRC计算单元](https://img.taocdn.com/s3/m/4b4f051f76c66137ee0619c8.png)
This replaces the same operation as “RBIT” instruction not available in Cortex-M0 instruction set but is in Cortex-M3/M4 and will save many CPU cycles if done by software…
31 0
1 1 0 1 0 1 0 0 0 1 0 1 1 0 0 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 0 0 0x58D43CB2 with bit-reversal done on the byte
3
CRC Features (4/4)
New Modes (Continued) Reversibility on Input and Output data without extra cycles Output: the reversing is done at bit level only
What is the value taken in CRC computation if input is : 0x11223344 and reversal mode is set to half word ? ____________
6
31 0
1 0 1 1 0 0 1 0 0 0 1 1 1 1 0 0 1 1 0 1 0 1 0 0 0 1 0 1 1 0 0 0
31
0xD458B23C with bit-reversal done by half-word
0
0x1A2B3C4D 0xD458B23C
0 0 0 1 1 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 1 1 0 0 0 1 0 0 1 1 0 1
STM32正交编码器例程
![STM32正交编码器例程](https://img.taocdn.com/s3/m/00ce6068e418964bcf84b9d528ea81c758f52e00.png)
如图,STM32的每个TIMER都有正交编码器输入接口,TI1,TI2经过输入滤波,边沿检测产生TI1FP1,TI2FP2接到编码器模块,通过配置编码器的工作模式,即可以对编码器进行正向/反向计数。
如下图,编码器使用了A,B两相信号,但是我只需要对TI1信号进行计数(第一行),我也是刚发现了这个错误,原来对两个信号都计数,导致码盘转一周得到不止100个脉冲(100线的光电码盘)。
通过STM32的编码器模块比较两想的电平信号就可以很容易地计算出编码器的运行情况了。
下面是我调试OK的代码:void Encoder_Configration(void){GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_ICInitTypeDef TIM_ICInitStructure;//PC6 A相PC7 B相GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC,&GPIO_InitStructure);/* Enable the TIM3 Update Interrupt *//*NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIMx_PRE_EMPTION_PRI ORITY;NVIC_InitStructure.NVIC_IRQChannelSubPriority = TIMx_SUB_PRIORITY;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);*//* Timer configuration in Encoder mode */TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // No prescalingTIM_TimeBaseStructure.TIM_Period = 10000;TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);TIM_EncoderInterfaceConfig(TIM8, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);TIM_ICStructInit(&TIM_ICInitStructure);TIM_ICInitStructure.TIM_ICFilter = 6;//ICx_FILTER;TIM_ICInit(TIM8, &TIM_ICInitStructure);// Clear all pending interruptsTIM_ClearFlag(TIM8, TIM_FLAG_Update);TIM_ITConfig(TIM8, TIM_IT_Update, ENABLE);//Reset counterTIM2->CNT = 0;TIM_Cmd(TIM8, ENABLE);}n_Counter = TIM_GetCounter(TIM8);Diled_Disp_Num((float)n_Counter);另外一个值得注意的问题是,STM32 的定时器是16位的,意思是只能计数到65535,有两种方法,一是采用链式的方式用两个定时器将16位扩展为32位,还有一种简单的方法就是开启定时器的溢出中断,每中断一次就代表编码器运转了特定的角度。
简单有效的单片机CRC快速算法
![简单有效的单片机CRC快速算法](https://img.taocdn.com/s3/m/4d8de9d431126edb6e1a106e.png)
简单实用的单片机CRC快速算法1 引言CRC(循环冗余码)检验技术广泛应用于测控及通信领域。
在很多情况下,CRC计算是靠专用的硬件来实现的,但是对于小型低成本的单片机系统来说,若要在没有这些硬件的支持下实现CRC检验,首先要解决的就是如何通过软件高效快速地完成CRC计算的问题,也就是CRC算法的问题。
这里将提供两种算法,它们稍有不同,一种适用于程序空间大一些的51系列等单片机,另一种适用于程序空间的使用条件十分苛刻的PIC单片机。
这些算法按字节进行计算,仅使用查表和简单的异或运算等操作,所以,计算过程相当简捷,而计算速度却很快。
下面先简述一下CRC原理,然后再以CRC-CCITT标准生成多项式为例对算法进行说明,并给出一个51系列单片机子程序和一个PIC单片机子程序。
2 CRC原理CRC检验原理实际上就是在一个p位二进制数据序列之后附加一个r位二进制检验码(序列),从而构成一个总长为n=p +r位的二进制序列,例如,p位二进制数据序列D=[dp-1dp-2 ......d1d0],r位二进制检验码R=[rr-1 rr-2....r1 r0],所得到的这个n位二进制序列就是M=[dp-1dp-2 ......d1d0 rr-1 rr-2....r1 r0];附加在数据序列之后的这个检验码与数据序列的内容之间存在着某种特定的关系。
如果因干扰等原因使数据序列中的某一位或某些位发生错误,这种特定关系就会被破坏,因此,通过检查这一关系, 就可以实现对数据正确性的检验。
校验码R是通过对数据序列D进行二进制除法取余式运算得到的,它被一个称为生成多项式的(r+1)位二进制序列G =[gr gr-1 .... g1 g0]来除,用多项式形式表示为其中,xrD(x)表示将数据序列D左移r位(即在D的末尾再增加r个0位),Q(x)代表这一除法所得的商,R(x)就是所需的余式。
这一运算关系还可以用式(2)来表达其中,Re[ ]表示对括号内的式子进行取余式运算。
crc_calcblockcrc校验原理
![crc_calcblockcrc校验原理](https://img.taocdn.com/s3/m/1ffa36bf0342a8956bec0975f46527d3250ca64f.png)
CRC(Cyclic Redundancy Check)是一种数据传输中常用的校验方法,用于检测数据传输过程中可能出现的错误。
CRC校验原理简单而实用,广泛应用于各种通信协议中,包括以太网、USB、蓝牙等。
本文将从CRC的概念、原理和计算方法三个方面来详细介绍CRC校验的相关知识。
一、CRC的概念1. CRC的定义CRC是一种通过对数据进行运算得到一个固定长度的校验值,然后将这个校验值附加在数据后面进行传输的技术。
接收端在接收到数据后,也对数据进行CRC校验,并将得到的校验值与接收到的校验值进行比较,从而判断数据是否在传输过程中发生了错误。
2. CRC的特点CRC校验具有以下特点:(1)高效性:CRC校验采用多项式运算的方法,计算速度快,适合于高速数据传输。
(2)可靠性:CRC校验方法能够检测大部分错误,特别是位错误。
(3)灵活性:CRC校验的位数可以根据需求进行选择,通常为16位或32位。
(4)简单性:CRC校验算法简单,易于实现。
以上特点使得CRC校验在数据通信领域得到了广泛的应用。
二、CRC的原理1. CRC生成多项式CRC校验的关键在于选择合适的生成多项式。
生成多项式通常是一个二进制数,通常是一个不可约多项式。
生成多项式的选择对CRC校验的性能有较大影响,一般情况下,生成多项式的次数越高,CRC校验的可靠性越好。
2. CRC校验过程CRC校验的具体过程如下:(1)初始化:需要在数据的末尾附加上一个初始值,通常为0。
(2)生成余数:将数据与生成多项式进行模2除法运算,得到余数。
(3)得到校验值:将余数附加在原始数据的末尾,得到校验值。
3. CRC校验的原理CRC校验的原理可以简要概括为:发送端在发送数据时,利用生成多项式对数据进行计算,得到一个校验值,然后将这个校验值附加在数据末尾进行传输;接收端在接收到数据后,同样利用生成多项式对数据进行计算,得到一个校验值,然后将这个校验值与接收到的校验值进行比较,若两者一致,则数据传输没有发生错误。
STM32之CRC库
![STM32之CRC库](https://img.taocdn.com/s3/m/e6ac86af284ac850ad02427c.png)
函数名称: 函数原型: 功能描述: 输入参数: 输出参数: 返回参数:
CRC_GetIDRegister u8 CRC_GetIDRegister(void) 返回保存到独立的数据(ID)寄存器中 8 位的数据 无 无 独立的数据(ID)寄存器的 8 位数值
函数名称: 函数原型: 功能描述: 输入参数: 输出参数: 返回参数:
CRC_CalcBlockCRC u32 CRC_CalcBlockCRC(u32 pBuffer[], u32 BufferLength) 计算一个缓冲区的数据的 32 位 CRC (1) pBuffer:指向包含需要计算数据的缓冲区的指针 (2) BufferLength: 待计算的缓冲区的长度 无 32 位 CRC 码
函数 CRC_ResetDR CRC_CalcCRC CRC_CalcBlockCRC CRC_GetCRC CRC_SetIDRegister CRC_GetIDRegister 复位 CRC 数据寄存器 计算已知字的 32 位 CRC
描述
计算一个缓冲区的数据的 32 位 CRC 返回当前的 CRC 值 在独立的数据(ID)寄存器中保存一个 8 位的数据 返回保存到独立的数据(ID)寄存器中 8 位的数据
函数名称: 函数原型: 功能描述: 输入参数: 输出参数: 返回参数:
CRC_GetCRC u32 CRC_GetCRC(void) 返回当前的 CRC 值 无 无 32 位 CRC 码
函数名称:
CRC_SetIDRegister
函数原型: 功能描述: 输入参数: 输出参数: 返回参数:
void CRC_SetIDRegister(u8 IDValue) 在独立的数据(ID)寄存器中保存一个 8 位的数据 等待保存到独立的数据(ID)寄存器中 8 位的数据值 无 无
STM32关于SPI2因为DMA通道而异常发送CRC问题描述
![STM32关于SPI2因为DMA通道而异常发送CRC问题描述](https://img.taocdn.com/s3/m/6b19d72110661ed9ad51f34a.png)
关键词:SMT32105 SPI2 DMA1_Channel5 CRC USART1现象描述:同时使用SPI2和USART1时,SPI2的数据会异常多发送一个字节数据,实际监控到,每次当USART1接收到固定长度的数据后,SPI2就会自己多发送一帧数据。
问题原因:1、DMA通道问题:STM32 105的SPI2发送和USART1的接收都归同一个DMA1_Channel5管理,但是使用时,一个DMA通道下最好只管理一个外设,否则多个设备复用一个通道处理会很复杂,稍微处理不好就会出异常,为了避免复用,笔者只使用DMA1_Channel5管理USART1,但是使用中还是出了问题,这里我们看到DMA1_Channel5下还有其他外设,如果用DMA管理其他外设,SPI2也会出现问题,具体问题我们下面详细描述。
2、SPI设置问题:笔者使用时,SPI作为主设备,全双工模式,通讯时,如果开启了CRC校验,发送数据时就会异常,会莫名奇妙多发送一帧数据,后来发现和USART1的接收有关,其实是因为DMA1_Channel5的管理问题,这里附上SPI2的设置,供大家参考,特殊标注的部分就是出问题的CRC部分,需要关掉才好使。
void SPI2_Init(void){SPI_InitTypeDefSPI_InitStructure;//DMA_InitTypeDefDMA_InitStructure;GPIO_InitTypeDefGPIO_InitStructure;/* Enable SPI2 and GPIO clocks *//*!< SPI_FLASH_SPI_CS_GPIO, SPI_FLASH_SPI_MOSI_GPIO,SPI_FLASH_SPI_MISO_GPIO, SPI_FLASH_SPI_DETECT_GPIOand SPI_FLASH_SPI_SCK_GPIO Periph clock enable */RCC_APB1PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);/*!< SPI_FLASH_SPI Periph clock enable */RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);/*!< AFIO Periph clock enable *//*!< Configure SPI_FLASH_SPI pins: SCK */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOB, &GPIO_InitStructure);/*!< Configure SPI_FLASH_SPI pins: MISO */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;GPIO_Init(GPIOB, &GPIO_InitStructure);/*!< Configure SPI_FLASH_SPI pins: MOSI */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;GPIO_Init(GPIOB, &GPIO_InitStructure);/*!< Configure SPI_FLASH_SPI_CS_PIN pin: SPI_FLASH Card CS pin */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOB, &GPIO_InitStructure);/* Deselect the FLASH: Chip Select high */SPI_CS_HIGH();/* SPI1 configuration */// W25X16: data input on the DIO pin is sampled on the rising edge of the CLK.// Data on the DO and DIO pins are clocked out on the falling edge of CLK.SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //两线全双工SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位数据SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//时钟空闲保持高电平SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //第二个时钟沿采集SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //片选信号由软件产生SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;//SPI_BaudRatePrescaler_8; //8分频,9MHzSPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前SPI_InitStructure.SPI_CRCPolynomial = 0; //SPI_Init(SPI2, &SPI_InitStructure);SPI_CalculateCRC(SPI2, ENABLE);//这里,如果Enable CRC功能,SPI发送数据时//就会异常多发数据,这里我们只开启,不设置CRC数据,实际发送时也不控制CRC发送,这样在发送数据时就能看到异常数据。
STM32的软硬件CRC性能比较研究
![STM32的软硬件CRC性能比较研究](https://img.taocdn.com/s3/m/569c8e516fdb6f1aff00bed5b9f3f90f76c64da0.png)
STM32的软硬件CRC性能比较探究引言:随着嵌入式系统的广泛应用,对数据安全和完整性的要求也越来越高。
CRC(循环冗余校验)是一种常用的校验算法,常被用于数据传输过程中检测错误。
STM32是一系列由STMicroelectronics开发的32位嵌入式微控制器,提供了软件CRC和硬件CRC两种实现方式。
本文将对STM32的软硬件CRC性能进行比较探究,旨在援助开发者选择合适的CRC实现方式。
一、CRC概述1.1 CRC原理循环冗余校验(CRC)是一种纠错编码技术。
数据传输的过程中,发送方利用CRC算法对数据进行运算得到校验码,附加在数据报文的末尾发送。
接收方在接收到数据后,同样利用CRC 算法对数据进行运算得到校验码,并与接收到的校验码进行比对。
若果两者一致,则说明数据传输无误。
否则,则存在数据传输错误。
1.2 CRC应用CRC广泛应用于串行通信、存储系统、网络协议、信号处理等领域。
通过使用CRC校验,可以检测并纠正数据在传输过程中产生的任何错误。
二、软件CRC2.1 软件CRC实现原理软件CRC是通过软件算法实现的。
软件CRC算法按照生成多项式对数据进行处理,最终得到校验码。
STM32提供了多种软件CRC实现方式,包括Bit by Bit、Table Lookup和Table Lookup with Memorized Pre-existing Remainders。
2.2 软件CRC性能特点相比于硬件CRC,软件CRC具有如下特点:(1)灵活性:软件CRC可以灵活选择生成多项式,并依据需要进行修改和调整。
(2)占用资源少:软件CRC的实现一般只需要使用少许的RAM和Flash资源。
(3)适用范围广:软件CRC可以在全部的STM32系列微控制器上使用。
三、硬件CRC3.1 硬件CRC实现原理硬件CRC是通过硬件模块实现的。
硬件模块直接处理输入数据,并生成校验码。
STM32的硬件CRC模块支持多种生成多项式,可以直接调用。
STM32F3产品技术培训-02.CRC-数模转换-看门狗
![STM32F3产品技术培训-02.CRC-数模转换-看门狗](https://img.taocdn.com/s3/m/43deee19866fb84ae45c8dbc.png)
8
• One 12-bit DAC converter inside STM32F30x:
• DAC1 with 2 DAC output channels
• Features and differences:
• • • • • • • • • • 8-bit or 12-bit mode (left or right data alignment in 12-bit mode) Synchronized update capability Noise-wave or Triangular-wave generation DMA capability for each channel (with DMA underrun error detection) External triggers for conversion (Timers, ext. pin, SW trigger) Programmable output buffer to drive more current Input voltage reference VREF+ DAC supply requirement: VDDA = 2.4V to 3.6 V DAC outputs range: 0 ≤ DAC_OUTx ≤ VREF+ Dual DAC channel mode supported by DAC1 only:
STM32F3 Technical Training
For reference only
Refer to the latest documents for details
CRC calculation unit
CRC Introduction 1/2
• CRC-based techniques are used to verify data integrity (communications) • In functional safety standards (such as EN/IEC 60335-1), CRC peripheral offers a means of verifying the embedded Flash memory integrity • Single input/output 32-bit data register, but handles 8,16, 32-bits input data size • CRC computation done in 4 AHB clock cycles (HCLK) maximum • General-purpose 8-bit register (can be used for temporary storage)
STM32F10x学习笔记3(CRC计算单元)
![STM32F10x学习笔记3(CRC计算单元)](https://img.taocdn.com/s3/m/7934de1f11661ed9ad51f01dc281e53a58025112.png)
STM32F10x学习笔记3(CRC计算单元)STM32F10x 学习笔记3(CRC 计算单元)STM32F 系列的单片机内部带了CRC32 计算单元。
这个内置CRC 模块的方法使用非常简单。
其操作如下图所示。
图1CRC 计算单元框图归纳起来有如下几步操作:1. 开启CRC 单元的时钟。
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE)2. 复位CRC 模块(设置CRC_CR=0x01),这个操作把CRC 余数初始化为0xFFFFFFFF3. 把要计算的数据按逐个地写入CRC_DR 寄存器4. 写完所有的数据字后,从CRC_DR寄存器读出计算的结果STM32F10x StdPeriph Driver 中提供了几个函数。
CRC_ResetDR(void)用来复位CRC 模块。
uint32_t CRC_CalcCRC(uint32_t Data)将一个数据写入CRC_DR 寄存器,返回值为计算结果。
uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength)计算一个数组的CRC 值。
uint32_t CRC_GetCRC(void)读取CRC_DR 寄存器的结果。
另外,CRC 模块中还有个独立数据寄存器(CRC_IDR)。
这是个单字节的寄存器,用于临时存放1 字节的数据,不受复位操作影响。
相应的操作函数有两个。
void CRC_SetIDRegister(uint8_t IDValue) uint8_t CRC_GetIDRegister(void)分别是写CRC_IDR 和读CRC_IDR 寄存器。
虽然STM32F 上的CRC 单元用起来很简单,但是似乎它计算出来的结果与传统的CRC32 算法得到的结果有些不同。
下面是个简单的例子。
#include”stm32f10x.h”intmain(void){uint32_tj;uint32_tstr[11]={1,2,3, 4,5,6,7,8,9,};SystemInit();RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC,ENABLE);CRC_ ResetDR();str[9]=CRC_CalcBlockCRC(str,1);CRC_ResetDR();CRC_CalcCRC(0x A5A5A5A5); j=CRC_GetCRC();CRC_CalcCRC(j);for(;;){}}tips:感谢大家的阅读,本文由我司。
stm32_32位寄存器_频率计算_理论说明
![stm32_32位寄存器_频率计算_理论说明](https://img.taocdn.com/s3/m/b849025553d380eb6294dd88d0d233d4b14e3f3b.png)
stm32 32位寄存器频率计算理论说明1. 引言1.1 概述:本篇文章旨在介绍STM32 32位寄存器的使用以及频率计算原理。
作为一款广泛应用于嵌入式系统开发的微控制器,STM32系列芯片具备强大的性能和丰富的功能,其中的32位寄存器是实现各种功能和控制的关键。
同时,频率计算作为嵌入式系统开发中一个重要的问题,对于正确、精确地进行时钟配置和定时操作起着关键作用。
因此,深入了解STM32寄存器与频率计算之间的关系对于开发人员来说至关重要。
1.2 文章结构:本文分为五个主要部分:引言、STM32 32位寄存器、频率计算原理、理论说明和结论。
在引言部分,将对文章主题进行概述,并详细介绍各部分的内容安排。
接下来,在STM32 32位寄存器部分,将向读者介绍什么是寄存器以及如何使用它们进行数据读写操作。
在频率计算原理部分,将阐述频率的定义和计算公式,并介绍STM32中常用的频率计算方法。
然后,在理论说明部分,将解析STM32寄存器与频率计算之间的关系,并详细说明STM32相关定时器和时钟的配置方法。
最后,在结论部分,将对全文进行总结,并探讨未来研究的方向。
1.3 目的:本文旨在帮助读者深入理解STM32 32位寄存器的使用以及频率计算原理。
通过对寄存器的介绍和应用实例的讲解,读者将能够更加熟悉并灵活运用32位寄存器来实现各种功能和控制需求。
同时,通过频率计算原理的讲解与实例说明,读者将对如何准确地计算嵌入式系统中的频率有更深入、全面的了解。
通过本文内容的学习,读者可以提高嵌入式系统开发的效率,并避免常见错误以及优化频率计算精度。
2. STM32 32位寄存器:2.1 寄存器介绍:STM32微控制器中的寄存器是一种特殊的内部存储区域,用于存储和操作各种配置和状态信息。
STM32微控制器使用了32位寄存器,这意味着每个寄存器可以容纳32位的数据。
这些寄存器通常用于控制外设、时钟设置以及输入输出等功能。
2.2 寄存器操作方法:为了访问和设置STM32微控制器中的寄存器,我们需要使用指定的地址来读取或写入数据。
STM32内置CRC模块的使用
![STM32内置CRC模块的使用](https://img.taocdn.com/s3/m/b6094137abea998fcc22bcd126fff705cc175cbb.png)
STM32内置CRC模块的使⽤所有的STM32芯⽚都内置了⼀个硬件的CRC计算模块,可以很⽅便地应⽤到需要进⾏通信的程序中,这个CRC计算模块使⽤常见的、在以太⽹中使⽤的计算多项式:X32 + X26 + X23 + X22 + X16 + X12 + X11 + X10 +X8 + X7 + X5 + X4 + X2+ X +1写成16进制就是:0x04C11DB7使⽤这个内置CRC模块的⽅法⾮常简单,既⾸先复位CRC模块(设置CRC_CR=0x01),这个操作把CRC计算的余数初始化为0xFFFFFFFF;然后把要计算的数据按每32位分割为⼀组数据字,并逐个地把这组数据字写⼊CRC_DR寄存器(既下图中的绿⾊框),写完所有的数据字后,就可以从CRC_DR寄存器(既下图中的兰⾊框)读出计算的结果。
注意:虽然读写操作都是针对CRC_DR寄存器,但实际上是访问的不同物理寄存器。
下⾯是⽤C语⾔描述的这个计算模块的算法,⼤家可以把它放在通信的另⼀端,对通信的正确性进⾏验证:DWORD dwPolynomial = 0x04c11db7;DWORD cal_crc(DWORD *ptr, int len){DWORD xbit;DWORD data;DWORD CRC = 0xFFFFFFFF; // initwhile (len--) {xbit = 1 << 31;data = *ptr++;for (int bits = 0; bits < 32; bits++) {if (CRC & 0x80000000) {CRC <<= 1;CRC ^= dwPolynomial;}elseCRC <<= 1;if (data & xbit)CRC ^= dwPolynomial;xbit >>= 1;}}return CRC;}有⼏点需要说明:1)上述算法中变量CRC,在每次循环结束包含了计算的余数,它始终是向左移位(既从最低位向最⾼位移动),溢出的数据位被丢弃。
STM32的硬件CRC
![STM32的硬件CRC](https://img.taocdn.com/s3/m/78eca77e59fafab069dc5022aaea998fcd224053.png)
STM32的硬件CRC简介基于STM32F105介绍STM32的硬件CRC和使⽤⽅法,并记录软件检验实现。
STM32的CRC介绍⼿册中说明STM32的CRC硬件校验使⽤的是32位CRC校验,多项式为0x04C11DB7;CRC计算时⼀次性运算32bits,不是按照字节运算;CRC_DR寄存器的复位值为0xFFFFFFFF,即CRC计算的初始值。
STM32的CRC使⽤STM32的CRC_DR寄存器既作为输⼊寄存器⼜作为输出寄存器作为输⼊寄存器时直接写⼊要进⾏CRC计算的数据作为输出寄存器时,通过读操作返回上次CRC计算结果每⼀次写⼊数据寄存器的计算结果是前⼀次计算结果和新计算结果的组合;在新的数据块进⾏CRC计算之前,需要复位CRC_DR寄存器以STM32F105的标准库为例,介绍CRC计算的步骤uint32_t buff[4] = {0x01,0x02,0x03,0x04};CRC_ResetDR();CRC_CalcBlockCRC(buff,4);delay(5);ret = CRC_GetCRC();STM32的CRC软件实现STM32硬件CRC计算出来的结果与常⽤的CRC32计算出的CRC值不⼀样,如果通信中⽤到了STM32的硬件CRC计算值,需要外部实现与硬件CRC⼀致的计算结果,详细代码如下,提供uint32_t crc32_st(uint32_t *pbuf, uint32_t size){const uint32_t st_const_value = 0x04c11db7;uint32_t crc_value = 0xffffffff;uint32_t xbit;uint32_t bits;uint32_t i;for (i = 0; i < size; i++){xbit = 0x80000000;for (bits = 0; bits < 32; bits++){if (crc_value & 0x80000000){crc_value <<= 1;crc_value ^= st_const_value;}else{crc_value <<= 1;}if (pbuf[i] & xbit){crc_value ^= st_const_value;}xbit >>= 1;}}return crc_value;}总结其它平台与STM32通信时,如果⽤到CRC值,可以通过这种软件计算与STM32的CRC保持⼀致。
STM32之CRC库
![STM32之CRC库](https://img.taocdn.com/s3/m/e6ac86af284ac850ad02427c.png)
函数名称: 函数原型: 功能描述: 输入参数: 输出参数: 返回参数:
CRC_ResetDR void CRC_ResetDR(void) 复位 CRC 数据寄存器 无 无 无
函数名称: 函数原型: 功能描述: 输入参数: 输出参数: 返回参数:
CRC_CalcCRC u32 CRC_CalcCRC(u32 Data) 计算已知字的 32 位 CRC - Data:待计算 CRC 的数据字 无 无
函数名称: 函数原型: 功能描述: 输入参数: 输出参数: 返回参数:
CRC_CalcBlockCRC u32 CRC_CalcBlockCRC(u32 pBuffer[], u32 BufferLength) 计算一个缓冲区的数据的 32 位 CRC (1) pBuffer:指向包含需要计算数据的缓冲区的指针 (2) BufferLength: 待计算的缓冲区的长度 无 32 位 CRC 码
函数名称: 函数原型: 功能描述: 输入参数: 输出参数: 返回参数:
CRC_GetCRC u32 CRC_GetCRC(void) 返回当前的 CRC etIDRegister
函数原型: 功能描述: 输入参数: 输出参数: 返回参数:
void CRC_SetIDRegister(u8 IDValue) 在独立的数据(ID)寄存器中保存一个 8 位的数据 等待保存到独立的数据(ID)寄存器中 8 位的数据值 无 无
函数名称: 函数原型: 功能描述: 输入参数: 输出参数: 返回参数:
CRC_GetIDRegister u8 CRC_GetIDRegister(void) 返回保存到独立的数据(ID)寄存器中 8 位的数据 无 无 独立的数据(ID)寄存器的 8 位数值
stm32生成bin文件并添加CRC校验到文件末尾
![stm32生成bin文件并添加CRC校验到文件末尾](https://img.taocdn.com/s3/m/c39a2999d1d233d4b14e852458fb770bf78a3b71.png)
stm32⽣成bin⽂件并添加CRC校验到⽂件末尾做STM32的IAP升级需要⽤到BIN⽂件,为了确保BIN⽂件正确,于是在BIN⽂件的末尾增加了CRC校验。
校验值是⾃动⽣成的并添加的。
⾸先是准备⼯作:1.下载下载后⾥⾯的exe⽂件解压到keil任意的⽂件下,这⾥我是放在D:\Keil_v5\ARM\ARMCC⽂件夹内。
这个路径后续需要⽤到。
2.在你项⽬的启动⽂件所在的⽂件夹内,增加⼀个bat⽂件 ⽅法:新建txt⽂件,然后将下⾯的内容拷贝进去,最后修改后缀名内容如下:@echo offECHO Add CRC32 At the end of the documentECHO -------------------------------------SET SREC_PATH=D:\Keil_v5\ARM\ARMCC //这⾥的SET SREC_PATH是你安装⼯具的位置(这句话记得删除)for /f %%i in ('dir /b .\raw.bin') do (set indexdx=%%~zi)ECHO %indexdx%ECHO %SREC_PATH%\srec_cat.exe raw.bin -Binary -crop 0 %indexdx% -crc32-b-e %indexdx% -o gps_bass.bin -Binary%SREC_PATH%\srec_cat.exe raw.bin -Binary -crop 0 %indexdx% -crc32-l-e %indexdx% -o gps_bass.bin -Binary3.打开你的项⽬,点击魔术棒,打开user选项卡,在After Build栏,勾选RUN1,RUN2。
在RUN1 栏添加“D:\Keil5\ARM\ARMCC\bin\fromelf.exe --bin --output=raw.bin !L” //安装路径不⼀定相同,找到你安装keil的⽂件夹,选中ARM\ARMCC\bin\fromelf.exe,后⾯照抄在RUN2栏,选中刚刚增加的BAT⽂件最后直接编译就会得到两个bin⽂件,⼀个raw.bin ⼀个gps_bass.bin想要BIN⽂件的命名不⼀样?1.在RUN1 output=raw.bin这⾥修改成 output=xxxx.bin2.在BAT⽂件内,把所有raw改成xxxx,把gps_bass.bin改成你想要的aaa.bin。
PC端实现STM32硬件CRC32计算结果(基本原理)
![PC端实现STM32硬件CRC32计算结果(基本原理)](https://img.taocdn.com/s3/m/bfb6da7aae1ffc4ffe4733687e21af45b307fef1.png)
PC端实现STM32硬件CRC32计算结果(基本原理)需要提前掌握的内容1. CRC32的基本原理可以通过过其他博⽂或者我附件中的WORD来学习2. STM32硬件CRC32校验结果⽣成初学建议使⽤CubeMX及HAL库STM32硬件CRC与常规CRC的不同使⽤CRC在线计算⼯具,STM32硬件CRC32⽣成案例给出代码如下:/* 使⽤HAL库,测试STM32硬件CRC32⽣成码 *************************************/// 定义并赋值初始变量uint8_t input_data1[]={0x41,0x42,0x43,0x44};uint8_t input_data2[]={0x41,0x42,0x43,0x44,0x44,0x43};// 定义并赋值CRC⽣成码存放变量uint32_t crc_check1 =HAL_CRC_Calculate(&hcrc,(uint32_t*)input_data1,1);uint32_t crc_check2 =HAL_CRC_Calculate(&hcrc,(uint32_t*)input_data2,2);// 通过串⼝向PC端发送CRC⽣成码,并以⼗六进制显⽰之// stm32中printf()函数的配置可以搜寻其他博⽂printf("%x, %x", crc_check1, crc_check2);将上述代码写⼊main函数,编译烧录即可得到测试结果,结果如下:⽆视相关的说明,测试结果如下:CF534AE1, 45EE68FB上述两个⼗六进制字符串便为STM32硬件CRC32根据不同的输⼊数据的⽣成码使⽤CRC32在线计算⼯具⽣成不需要太多的理论叙述,如下图所⽰便可得到我们所需的CRC32⽣成码:从上图的配置可以得到和STM32硬件CRC32相同的结果。
如果使⽤常规的CRC32结果会完全不同:常规CRC32与STM32硬件CRC32的不同点输⼊数据按字节反转以0x41为例:将0x41写成⼆进制为:0100 0001,将其反转为:1000 0010,反转后的数⼗六进制为:0x82同理,将[0x41, 0x42, 0x43, 0x44]依次反转便为[0x82, 0x42, 0xc2, 0x22],同时字节的存放也需要反转,即[0x22, 0xc2, 0x42, 0x82],结果图如下:由于,STM32硬件CRC是以32位为最⼩单位进⾏计算,所以对于数据[0x41, 0x42,0x43,0x44,0x44,0x43]其反转后应为:[0x22,0xc2,0x42,0x82,0x00,0x00,0xc2,0x22],结果如下图:结果异或值常规CRC32为0xFFFFFFFF,即上述结果值与其做异或即取反处理输出数据反转同上上节内容总结⼀种实现的思路便是现将输⼊的数据按字节反转后输⼊常规CRC32,然后再将结果反转并取反即可得到与STM32硬件CRC32相同的校验码了。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
00014 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
00065 void Delay(__IO uint32_t nCount);
00066
00067 /* Private functions ---------------------------------------------------------*/
00068
00069 /**
00015 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
00016 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
00026 * @{
00027 */
00028
00029 /** @addtogroup CRC_Calculation
00030 * @{
00031 */
00032
00033 /* Private typedef -----------------------------------------------------------*/
00017 *
00018 * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
00019 ******************************************************************************
00070 * @brief Main program.
00071 * @param None
00072 * @retval None
00073 */
00074 int main(void)
00075 {
00076 /*!< At this stage the microcontroller clock setting is already configured,
00053 0x95a88589, 0xf56ee54f, 0xd52cc50d, 0x34e224c3, 0x04817466, 0x64475424,
00054 0x4405a7db, 0xb7fa8799, 0xe75ff77e, 0xc71dd73c, 0x26d336f2, 0x069116b0,
00001 /**
00002 ******************************************************************************
00003 * @file CRC/CRC_Calculation/main.c
00004 * @author MCD Application Team
00105
00106 /**
00107 * @brief Reports the name of the source file and the source line number
00108 * where the assert_param error has occurred.
00079 To reconfigure the default setting of SystemInit() function, refer to
00080 system_stm32f10x.c file
00081 */
00082
00109 * @param file: pointer to the source file name
00110 * @param line: assert_param error line source number
00097 * @retval None
00098 */
00099 void Delay(__IO uint32_t nCount)
00100 {
00101 for(; nCount != 0; nCount--);
00102 }
00103
00104 #ifdef USE_FULL_ASSERT
00055 0x76764615, 0x5634d94c, 0xc96df90e, 0xe92f99c8, 0xb98aa9ab, 0x58444865,
00056 0x78066827, 0x18c008e1, 0x28a3c,
00088
00089 while (1)
00090 {
00091 }
00092 }
00093
00094 /**
00095 * @brief Inserts a delay time.
00096 * @param nCount: specifies the delay time length.
00047 0x4ad47ab7, 0x6a961a71, 0x0a503a33, 0x2a12dbfd, 0xfbbfeb9e, 0x9b798b58,
00048 0xbb3bab1a, 0x6ca67c87, 0x5cc52c22, 0x3c030c60, 0x1c41edae, 0xfd8fcdec,
00020 */
00021
00022 /* Includes ------------------------------------------------------------------*/
00023 #include "stm32f10x.h"
00024
00025 /** @addtogroup STM32F10x_StdPeriph_Examples
00005 * @version V3.5.0
00006 * @date 08-April-2011
00007 * @brief Main program body.
00008 ******************************************************************************
00043 0xa35ad3bd, 0xc39cf3ff, 0xe3de2462, 0x34430420, 0x64e674c7, 0x44a45485,
00044 0xa56ab54b, 0x85289509, 0xf5cfc5ac, 0xd58d3653, 0x26721611, 0x063076d7,
00049 0xad2abd0b, 0x8d689d49, 0x7e976eb6, 0x5ed54ef4, 0x2e321e51, 0x0e70ff9f,
00050 0xefbedfdd, 0xcffcbf1b, 0x9f598f78, 0x918881a9, 0xb1caa1eb, 0xd10cc12d,
00077 this is done through SystemInit() function which is called from startup
00078 file (startup_stm32f10x_xx.s) before to branch to application main.
00057 0x4a755a54, 0x6a377a16, 0x0af11ad0, 0x2ab33a92, 0xed0fdd6c, 0xcd4dbdaa,
00058 0xad8b9de8, 0x8dc97c26, 0x5c644c45, 0x3ca22c83, 0x1ce00cc1, 0xef1fff3e,
00041 0x00001021, 0x20423063, 0x408450a5, 0x60c670e7, 0x9129a14a, 0xb16bc18c,
00042 0xd1ade1ce, 0xf1ef1231, 0x32732252, 0x52b54294, 0x72f762d6, 0x93398318,
00051 0xe16f1080, 0x00a130c2, 0x20e35004, 0x40257046, 0x83b99398, 0xa3fbb3da,
00052 0xc33dd31c, 0xe37ff35e, 0x129022f3, 0x32d24235, 0x52146277, 0x7256b5ea,
00034 /* Private define ------------------------------------------------------------*/
00035 #define BUFFER_SIZE 114
00036
00037 /* Private macro -------------------------------------------------------------*/
00059 0xdf7caf9b, 0xbfba8fd9, 0x9ff86e17, 0x7e364e55, 0x2e933eb2, 0x0ed11ef0
00060 };
00061
00062 __IO uint32_t CRCValue = 0;
00063
00064 /* Private function prototypes -----------------------------------------------*/