本帖最后由 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模块的方法非常简单, 用四个开关表示十进制转二进制: #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); } |
占楼备用 |
谢谢分享 |
谢谢分享 |
以前没留意过这项功能,感谢分享。 |
谢谢分享! |