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

查看: 1989|回复: 6

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

[复制链接]

61

主题

1071

回帖

17

蝴蝶豆

论坛元老

最后登录
2020-12-9
发表于 2016-10-21 13:50:29 | 显示全部楼层 |阅读模式
本帖最后由 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


<
回复

使用道具 举报

61

主题

1071

回帖

17

蝴蝶豆

论坛元老

最后登录
2020-12-9
 楼主| 发表于 2016-10-21 13:52:22 | 显示全部楼层
占楼备用
回复 支持 反对

使用道具 举报

31

主题

1951

回帖

0

蝴蝶豆

论坛元老

最后登录
2020-12-4
发表于 2016-10-21 14:16:35 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

0

主题

159

回帖

0

蝴蝶豆

高级会员

最后登录
2017-3-9
发表于 2016-10-21 18:23:35 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

26

主题

1984

回帖

6

蝴蝶豆

论坛元老

最后登录
2020-12-9
发表于 2016-10-21 21:29:47 | 显示全部楼层
以前没留意过这项功能,感谢分享。
回复 支持 反对

使用道具 举报

16

主题

3009

回帖

2

蝴蝶豆

论坛元老

最后登录
2020-11-30
发表于 2016-10-22 09:18:17 | 显示全部楼层
谢谢分享!
回复 支持 反对

使用道具 举报

64

主题

744

回帖

23

蝴蝶豆

实习版主

最后登录
2020-12-8
发表于 2016-10-22 12:50:06 | 显示全部楼层
回复 支持 反对

使用道具 举报

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版