当前位置:网站首页>[robomaster] a board receives jy-me01 angle sensor data -- Modbus Protocol & CRC software verification
[robomaster] a board receives jy-me01 angle sensor data -- Modbus Protocol & CRC software verification
2022-07-29 08:06:00 【Bug can't be finished】
Angle sensor to be used in new car JY-ME01 It uses modbus Protocol for data transmission , Need to use A The board receives the data and parses the angle data , Record it for future use .
1、cubemax Configure the underlying
1.1 Clock and project configuration
Basic configuration method , It's all universal .



1.2 A serial port dma To configure
1.2.1 Open serial port , This page defaults 
1.2.2 Open serial port interrupt , Just tick it 
1.2.3 Turn on dma
Add one RX Of dma, altogether 3 Step 

After configuration, it can be consistent with the above figure .( Main confirmation The two data widths in the lower right corner are Byte)
2、 Serial port to receive data code
file :main.c
unsigned char RX_BUFFER[20]; // Define global variables to receive arrays
// After serial port initialization
__HAL_UART_ENABLE_IT(&huart8,UART_IT_IDLE);// To interrupt
HAL_UART_Receive_DMA(&huart8,RX_BUFFER,9);// Turn on dma Received receive array , length 9Byte
file :stm32f4xx_it.c
UART8_IRQHandler - Serial interrupt function
uint16_t temp;
if(__HAL_UART_GET_FLAG(&huart8,UART_FLAG_IDLE)==SET){
__HAL_UART_CLEAR_IDLEFLAG(&huart8); // Clear flag bits , Prepare to receive data next time
HAL_UART_DMAStop(&huart8); // stop it dma transmission
temp=9-hdma_uart8_rx.Instance->NDTR; /* Read ndtr In the register dma Number of data bytes sent , Then work out distance 9 How many more bytes are needed */
HAL_UART_Transmit_DMA(&huart8,RX_BUFFER,temp); // Send the remaining bytes to the receive array
}
HAL_UART_Receive_DMA(&huart8,RX_BUFFER,9); // restart dma
3.CRC check
principle
Because it is applied CRC Check algorithm , So don't study the principle too deeply .
Take a rough look at the calculation principle :
1、 preset 1 individual 16 Bit register is hexadecimal FFFF( whole 1), This register is CRC register .
2、 Take the first one. 8 Bit binary data ( That is, the first byte of the communication information frame ) And 16 Bit CRC The lower eight bits of the register are different or , Store the results in CRC register .
3、 hold CRC The contents of the register are shifted one bit to the right ( Low down ) use 0 Fill the top , And detect the shift out position after the right shift .
4、 If the shift out bit is zero , Then repeat step three ( One more right ); If you move out of the position, it's 1,CRC Registers and polynomials A001 To engage in exclusive or .
5、 Repeat step 3 and 4, Until you move right 8 Time , So the whole 8 All bit data is processed .
6、 Repeat step 2 and 5, Process the next byte of communication information frame .
7、 After calculating all bytes of the communication information frame according to the above steps , Got 16 position CRC The height of the register 、 Low byte swapping .
8、 final CRC The contents of the register are :CRC Check code .
a key :stm32 In common use CRC Verification method
1. Hardware CRC
Save computing resources , however F4 Turn on CRC Parameters cannot be configured after , It's very metaphysical , Temporarily abandon
2. Real time computing CRC check
Occupy FLASH Small , But the calculation speed is a little slower
3. Look-up table method CRC check
Look up table calculation speed , But occupation FLASH(A Board memory is large, do whatever you like ), So choose this method .
Code implementation
from CRC The verification principle is known ,CRC One feature of the check is that each eight bit binary byte corresponds to CRC Same check code . So for a byte, you can directly look up the table to get the corresponding verification result value .
The verification result corresponds to the array
It is recommended to put it in the file separately established by the user function
const unsigned char TabH[] = {
//CRC High byte value table
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
};
const unsigned char TabL[] = {
//CRC Low byte value table
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
} ;
float ANGLE; // Define the angle variable
uint16_t GetModbusCRC16_Tab(uint8_t *data, uint32_t len)//Modbus-CRC check ----- Look-up table method
{
unsigned int index;
unsigned char crcH = 0xFF; // high CRC byte
unsigned char crcL = 0xFF; // low CRC byte
while (len--) {
// Calculate the specified length of CRC
index = crcL ^ *data++;
crcL = crcH ^ TabH[ index];
crcH = TabL[ index];
}
return crcL<<8|crcH;// High and low displacement
}
Recommend one that can be used for inspection CRC Whether the result is the right website :http://www.ip33.com/crc.html
Serial port interrupt function is added CRC The process of calculation , Calculate the angle and output
Original calculation formula :Angle = 90063 / 262144 * 360 = 123.682708
crc_val=GetModbusCRC16_Tab(RX_BUFFER,7);
if(crc_val==((RX_BUFFER[7]<<8)|RX_BUFFER[8])){
ANGLE=(float)((RX_BUFFER[3]<<24)|(RX_BUFFER[4]<<16)|(RX_BUFFER[5]<<8)|RX_BUFFER[6]);
ANGLE=ANGLE/0x40000*360;
}
The result of changing the interrupt function .
Running results 
边栏推荐
- [cryptography experiment] 0x00 install NTL Library
- The computer system has no standard tcp/ip port processing operations
- Dynamically load data
- [beauty of software engineering - column notes] 27 | what is the core competitiveness of software engineers? (top)
- Taiyuan bus route crawling
- Crawl expression bag
- Some thoughts on growing into an architect
- 阿里巴巴政委体系-第四章、政委建在连队上
- Do you want to meet all the needs of customers
- 10 common software architecture modes
猜你喜欢

Unity beginner 3 - enemy movement control and setting of blood loss area (2D)

Some thoughts on growing into an architect

Compare three clock circuit schemes of single chip microcomputer

Mysql rownum 实现

Mutationobserver document learning
![[beauty of software engineering - column notes] 22 | how to do a good job in technology selection for the project?](/img/1a/72bfb3fef59c54188a823ead3a5390.png)
[beauty of software engineering - column notes] 22 | how to do a good job in technology selection for the project?

Cyberpunk special effect shader

Data unit: bit, byte, word, word length

Unity beginner 4 - frame animation and protagonist attack (2D)
![[beauty of software engineering - column notes] 25 | what methods can improve development efficiency?](/img/c8/c2d45abbf36b898040f9f1cf6274ff.png)
[beauty of software engineering - column notes] 25 | what methods can improve development efficiency?
随机推荐
An Optimal Buffer Management Scheme with Dynamic Thresholds论文总结
Up sampling deconvolution operation
Compare three clock circuit schemes of single chip microcomputer
Alibaba political commissar system - Chapter 1: political commissars are built on companies
BiSeNet v2
Jianmu continuous integration platform v2.5.2 release
Exercise: store department information
Crawl expression bag
Convert source package to RPM package
torch.Tensor.to的用法
Shell script - global variables, local variables, environment variables
Unicode private use areas
【学术相关】为什么很多国内学者的AI的论文复现不了?
[note] the art of research - (tell a good story and argument)
[note] the art of research (understand the importance of the problem)
[beauty of software engineering - column notes] 23 | Architect: programmers who don't want to be architects are not good programmers
C# 之 volatile关键字解析
Mysql rownum 实现
The new colleague wrote a few pieces of code, broke the system, and was blasted by the boss!
STM32 serial port garbled