在线时间4854 小时
UID3309825
ST金币0
蝴蝶豆17
注册时间2016-9-4
论坛元老
- 最后登录
- 2020-12-9
|
a0a.1 32b0c
本帖最后由 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);
}
|
|