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

ARM®mbed OS入门开发 STM32内置CRC模块的使用 十进制转二进制

[复制链接]
anywill 提问时间:2016-10-21 13:50 /
本帖最后由 anywill 于 2016-10-21 13:52 编辑

所有的STM32芯片都内置了一个硬件的CRC计算模块,可以很方便地应用到需要进行通信的程序中,这个CRC计算模块使用常见的、在以太网中使用的计算多项式:
  X32 + X26 + X23 + X22 + X16 + X12 + X11 + X10 +X8 + X7 + X5 + X4 + X2+ X +1
写成16进制就是:0x04C11DB7

使用这个内置CRC模块的方法非常简单,


2009414182656610.gif
CRC1.jpg
705475424727017944.jpg


用四个开关表示十进制转二进制:
#include "mbed.h"
/*

Last chage:    21-03-2014

Project Name:  NUCLEO-F070R-DigIN-CRC-DEC to BIN

By:            www.emcu.it - Enrico Marinoni

NOTE: see here: http://www.emcu.it/NUCLEOevaBoards/NUCLEOevaBoards.html#Tutorial


    This program show this functionality:
        USART2 (Virtual Com for debug)
        USART1
        DigitalIn
        Decimal to Binary conversion//十进制转二进制
        CRC calculation
    NOTE:
        A jumper must be present from PB_6 to PA_10 (USART1)
        More details  are available here:
        http://www.emcu.it/NUCLEOevaBoards/mBed/QSG-Mbed-Library.pdf


  VARIABLEs

  IO Status -> variable name is: IOStatus
        Name    Bit Directions  Note
        Din1    0   IN          PB_8
        Din2    1   IN          PB_9
        Din3    2   IN          PA_6 - Not used in this release of FW
        Din4    3   IN          PA_7    "       "       "       "   
        RL1     4   OUT         PA_8 Optional 4 Relay shield from SEED STUDIO - Not used in this release of FW
        RL2     5   OUT         PB_10    "       "       "       "       "    -     "       "       "       "   
        RL3     6   OUT         PB_4     "       "       "       "       "    -     "       "       "       "   
        RL4     7   OUT         PB_5     "       "       "       "       "    -     "       "       "       "   

  ADC Status - Not used in this release of FW
        Name     Variable Name  Note
        Ain0        ValAin0     PA_0 - Not used in this release of FW
        Ain1        ValAin1     PA_1      "       "       "       "   
        Ain2        ValAin2     PA_4      "       "       "       "   
        Ain3        ValAin3     PB_0      "       "       "       "   
        Ain4        ValAin4     PC_1      "       "       "       "   


  USART2 (RX==D0 - PA_3, TX==D1 - PA2) it is used for debug (connected to the PC) using TeraTerm.
  USART1 (RX==D2 - PA_10 , TX==D10 - PB_6) it is used for show the way to use another USART.
  Both USART are used in RX Interrupt mode.
  The USART parameters are:
    Baud Rate: 1200
    Data: 8
    Parity: NONE
    Stop: 1
    Flow Control: NONE        

*/         

Serial pc(SERIAL_TX, SERIAL_RX);    // This is USART2 tx, rx
                                    //      It is used for Debug via VirtualCOM
                                    //     
Serial Serial1(PB_6, PA_10);        // This is USART1 tx, rx暂时无用

DigitalOut myled(LED1);             // This LED is on NUCLEO-F070R

DigitalIn BlueButton(USER_BUTTON);  // This is Blue-Button and is on NUCLEO-F070R
// Digital InPut - from the field
DigitalIn Din1(PB_8);
DigitalIn Din2(PB_9);
DigitalIn Din3(PA_6);
DigitalIn Din4(PA_7);

#define Pressed 0
#define NotPressed 1
#define Enable 1
#define Disable 0
#define POLYNOMIAL 0xD8  /* Is for CRC calculation - 11011 followed by 0's */

int Car='\0';
int CarSerial1='\0';
int n=0;
int DinStatus = 0;
int ValCRC = 0;



// Functions -----------------------------------------------------------------------
void SendToPCtheDinStatusAndCRC(void);

int ReadIO(void);       // Read and return the Din1...4 status

void ConvDecToBin(int); // Convert Decimal number in Binary and send the result
                        //      to the PC

uint8_t crcNaive(uint8_t const);

void callback2() // PC - USART2 used for Debug
    {
    // Note: you need to actually read from the serial to clear the RX interrupt
    Car = pc.getc();
    }

void USART1_INT() // USART1
    {
    // Note: you need to actually read from the serial to clear the RX interrupt
    CarSerial1 = Serial1.getc();
    }

// Interrupt used for flashing the Green Led
Timeout to1;
#define ON 1
#define OFF 0
#define DLYFlash 0.5
int ONOFF_Flashing = ON;
void IntFlash(void);


// MAIN program ---------------------------------------------------------------------
int main() {

    // Define the USART ports
    Serial1.attach(&USART1_INT);
    pc.attach(&callback2);

    // SetUp the baud rate
    pc.baud(1200);
    Serial1.baud(1200);   


    // Set PullUp on Digital Input Pins (Din1...4)
    Din1.mode(PullUp);
    Din2.mode(PullUp);
    Din3.mode(PullUp);
    Din4.mode(PullUp);

    // Start flashing the Green Led
    ONOFF_Flashing = ON;              // Enabling flashing flag
    to1.attach(&IntFlash, DLYFlash);  // Enabling flashing Interrupt


    pc.printf("\n\r\n\r START MAIN - NucleoF334R8-DigIN-CRC-DECtoBIN\n\r");

    while(1) // Main infinite loop --------------------------------------------------
    {

    // Test the Blue Button
    if (BlueButton == Pressed)
        {
        while(BlueButton == Pressed)
            {
            if (n == 0)
                pc.printf("Please release the BLUE Button\n\r");
            n++;
            }
        n = 0;
        pc.printf("The Digital Input status are:\n\r");
        DinStatus = ReadIO();
        pc.printf("DinStatus == %x\n\r", DinStatus);
        pc.printf("Din4 Din3 Din2 Din1\n\r");
        ConvDecToBin(DinStatus);            

        // CRC calculation
        ValCRC = crcNaive(DinStatus);
        pc.printf("CRC == %d\n\r", ValCRC);

        ONOFF_Flashing = OFF;   // Disable Interrupt of Green LED

        // Start flashing the Green Led (enable Interrupt)
        ONOFF_Flashing = ON;              // Enabling flashing flag
        to1.attach(&IntFlash, DLYFlash);  // Enabling flashing Interrupt

        }


    // Test the char. received from PC - USART2 that is USB Virtual COM
    if (Car == 'E')
        {
            pc.printf("\n\r - Send char. E (received from USB_VirtualCOM PC-USART2) to USART1\n\r");
            pc.printf(" - If there is a jumper from PB_6 to PA_10, you will see the Din4...1 status + CRC\n\r");
            Serial1.putc('E');  // Send char. E to USART1
            Car = '\0';
        }


    if (Car == '?')
        {
            // Send to PC the status of Digital Inputs Din1...4
            SendToPCtheDinStatusAndCRC();   
            Car = '\0';
        }        


    // Test the char. received from AUREL (USART1)
    if (CarSerial1 == 'E')
        {
            pc.printf("RX char. E from USART1\n\r");
            // Send to PC the status of Digital Inputs Din1...4
            SendToPCtheDinStatusAndCRC();
            CarSerial1 = '\0';           
        }
    }
    // END Main infinite loop -------------------------------------------------------
}


void SendToPCtheDinStatusAndCRC(void)
{
    ONOFF_Flashing = OFF;   // Disable Interrupt of Green LED
    pc.printf("\n\r- PC request, to know the Digital Inputs Status\n\r");
    DinStatus = ReadIO();
    pc.printf("DinStatus == %x\n\r", DinStatus);
    pc.printf("Din4 Din3 Din2 Din1\n\r");
    ConvDecToBin(DinStatus);     
    // CRC calculation
    ValCRC = crcNaive(DinStatus);
    pc.printf("CRC related to Din4...1 == %d\n\r", ValCRC);                  
    Car = '\0';
    // Start flashing the Green Led (enable Interrupt)
    ONOFF_Flashing = ON;              // Enabling flashing flag
    to1.attach(&IntFlash, DLYFlash);  // Enabling flashing Interrupt
}


int ReadIO(void)
{
    DigitalIn Din1(PB_8);
    int DinValue=255;

    /* Read all the Digital Inputs (Din1...4) and return a DinValue

        DinValue (bit)             Note
            0               Din1 - 1 == OPEN, 0 == CLOSE
            1               Din2 -     "         "
            2               Din3 -     "         "
            3               Din4 -     "         "
    */

    // Test Din1 status
    if (Din1 == 0)
        DinValue = DinValue & 254; // 0
    else
        DinValue = DinValue & 255; // 1

    // Test Din2 status
    if (Din2 == 0)
        DinValue = DinValue & 253; // 0
    else
        DinValue = DinValue & 255; // 1

    // Test Din3 status
    if (Din3 == 0)
        DinValue = DinValue & 251; // 0
    else
        DinValue = DinValue & 255; // 1

    // Test Din4 status
    if (Din4 == 0)
        DinValue = DinValue & 247; // 0
    else
        DinValue = DinValue & 255; // 1

    return DinValue;
}

//
// Function that convert a Decimal number in Binary
// the original function is here:
// http://www.programmingsimplified ... t-decimal-to-binary
//
void ConvDecToBin(int n)
{
    int c, k;
    for (c = 3; c >= 0; c--)
    {
        k = n >> c;

        if (k & 1)
            pc.printf("  1  ");
        else
            pc.printf("  0  ");
    }
    pc.printf("\n\r");
}


//
// Function that flashing the Green Led
//   
void IntFlash(void)
{
    if (ONOFF_Flashing == ON)
        myled = !myled;
    else
        myled = 0;
    to1.detach();
    to1.attach(&IntFlash, DLYFlash); // this line reload Interrupt
}  


//
// CRC calculation
// Original code is gere: http://www.barrgroup.com/Embedde ... -Calculation-C-Code
//
uint8_t crcNaive(uint8_t const message)
{
    uint8_t  remainder;


    /*
     * Initially, the dividend is the remainder.
     */
    remainder = message;

    /*
     * For each bit position in the message....
     */
    for (uint8_t bit = 8; bit > 0; --bit)
    {
        /*
         * If the uppermost bit is a 1...
         */
        if (remainder & 0x80)
        {
            /*
             * XOR the previous remainder with the divisor.
             */
            remainder ^= POLYNOMIAL;
        }

        /*
         * Shift the next bit of the message into the remainder.
         */
        remainder = (remainder << 1);
    }

    /*
     * Return only the relevant bits of the remainder as CRC.
     */
    return (remainder >> 4);

}

CRC2.jpg


收藏 1 评论6 发布时间:2016-10-21 13:50

举报

6个回答
anywill 回答时间:2016-10-21 13:52:22
占楼备用
zhangdaijin 回答时间:2016-10-21 14:16:35
谢谢分享
xyx365 回答时间:2016-10-21 18:23:35
谢谢分享
slotg 回答时间:2016-10-21 21:29:47
以前没留意过这项功能,感谢分享。
lisingch 回答时间:2016-10-22 09:18:17
谢谢分享!
Stm32McuLover 回答时间:2016-10-22 12:50:06

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版