基于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;
            else
                CRC_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 flag
        TxCnt++;
        if(TxCnt >= 10)
        {
            //send interrupt disable
            TxCnt=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;    //准备下次发送数据
            }
        }
    }
}
时间: 2024-10-11 18:11:53

基于STM32的CRC校验说明的相关文章

Redis源码中的CRC校验码(crc16、crc64)原理浅析

在阅读Redis源码的时候,看到了两个文件:crc16.c.crc64.c.下面我抛砖引玉,简析一下原理. CRC即循环冗余校验码,是信息系统中一种常见的检错码.大学课程中的"计算机网络"."计算机组成"等课程中都有提及.我们可能都了解它的数学原理,在试卷上手工计算一个CRC校验码,并不是难事.但是计算机不是人,现实世界中的数学原理需要转化为计算机算法才能实现目的.实际上作为计算机专业背景人并不会经常使用或接触到CRC的计算机算法实现的原理,通常是电子学科背景的人士

CRC校验码的verilog实现与仿真结果

循环冗余校验码(CRC)的基本原理是: 将被处理的报文比特序列当做一个二进制多项式A(x)的系数,(任意一个由二进制位串组成的代码都可以和一个系数仅为'0'和'1'取值的多项式一一对应.例如:代码1010111对应的多项式为x6+x4+x2+x+1,而多项式为x5+x3+x2+x+1对应的代码101111),该系数乘以2^n(n为生成多项式g(x)中x的最高次幂)以后再除以发送方和接收方事先约定好的生成多项式g(x)后,求得的余数P(x)就是CRC校验码,把它副到原始的报文A(x)后面形成新的报

基于STM32的RFID射频识别技术 韦根协议C语言驱动解码程序

RFID工作原理 RFID技术的基本工作原理并不复杂:标签进入磁场后,接收解读器发出的射频信号,凭借感应电流所获得的能量发送出存储在芯片中的产品信息(无源标签或被动标签),或者由标签主动发送某一频率的信号(Active Tag,有源标签或主动标签),解读器读取信息并解码后,送至中央信息系统进行有关数据处理. 一套完整的RFID系统, 是由阅读器与电子标签也就是所谓的应答器及应用软件系统三个部份所组成,其工作原理是Reader发射一特定频率的无线电波能量,用以驱动电路将内部的数据送出,此时Read

文档:网络通讯包结构(crc校验,加解密)

包结构: 包 对(datacrc+protoID+dataSize)组成的byte[] 进行crc计算而得到 对(数据内容)进行crc计算而得到 协议号 数据内容的字节长度 数据内容 字段 headcrc datacrc protoID dataSize data 类型 uint uint ushort ushort byte[] 字节数 4 4 2 2 dataSize crc校验 问:TCP协议中,底层做了校验,那通信时我们还有必要再进行有CRC或者其他校验吗? 答:tcp 是可靠的, 就是

[转]四旋翼飞行器 - 基于stm32

原文地址:http://www.cnblogs.com/moranBlogs/p/3684275.html 期待我也可以做出一个飞行器来!! 尝试制作这个四旋翼飞控的过程,感触颇多,整理了思绪之后,把重要的点一一记下来: 这个飞控是基于STM32,整合了MPU6050,即陀螺仪和重力加速计,但没有融合电子罗盘: 另外,四旋翼飞行器的运动方式请百度百科,不太复杂,具体不再赘述: 这是飞控程序的控制流程(一个执行周期): 比较重要的地方: 1.i2c通信方式: 因为我不是学电类专业,最开始对i2c这

CRC校验的C语言实现

文章转自 循环冗余校验(CRC)算法入门引导 - Ivan 的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/liyuanbhu/article/details/7882789   一.原理部分 CRC 算法的基本思想是将传输的数据当做一个位数很长的数,将这个数除以另一个数,得到的余数作为校验数据附加到原数据后面.除法采用正常的多项式乘除法,而加减法都采用模2运算.模2运算就是结果除以2后取余数,如3 mod 2 = 1,在计算机中就是异或运算: 例如: 要传

基于Verilog的CRC-CCITT校验

由于笔者在自己设计CRC模块时遇到很多问题,在网上并未找到一篇具有实际指导意义的文章,在经过多次仿真修改再仿真之后得到了正确的结果,故愿意在本文中为大家提供整个设计流程供大家快速完成设计.本文章主要针对具体的实际应用给出一套亲测可行的实现办法,给出设计代码并提供仿真结果,供各位参考. 一.CRC概述 CRC(Cyclic Redundancy Check),循环冗余校验,是一种数字通信中的常用查错校验码.其特征是信息段和校验字段的长度可以任意选定. 校验方法为发送方对信息数据执行约定好除数的二进

毕业设计——基于STM32的音乐播放器设计(一)

基于STM32的音乐播放器设计, 源代码下载地址:http://download.csdn.net/detail/cxp2205455256/8334021      SD卡文件下载地址:http://download.csdn.net/detail/cxp2205455256/8334089 电路图下载地址:文件太大了,上传不了....... 以下是截图: 1.硬件电路 2.软件主界面 3.音乐播放器界面 4.音乐定时播放界面 5.音乐列表界面 6.日历功能界面 9.温度功能界面 10.计算器

CRC校验程序3:通过窗体程序打开txt文件获取数据源,进行逐字节CRC校验

在上一篇中,生成输出的CRC.exe将要成为这个窗体应用的内置模块. 新建一个windows窗体应用程序,叫做CRClick.将应用程序CRC.exe从Console应用程序中找到,复制到CRClick文件夹的Debuge文件夹下.同时还有测试用的Test.txt. 打开窗体设计页面,插入两个Textbox和一个按钮,长度Textbox用来显示被校验的文件的绝对路径,短Textbox显示最终校验码.按钮激发选择文件的窗口.设计如下: 对于按钮的触发事件,我们生成一个OpenFileDialog控