The previous section talked about the program framework for judging the data tail, but in most projects, data is received by judging the data header. This section will teach you two knowledge points:
The first one is how to parse the data header protocol and extract valid data from a string of data that has been received.
Second: Whether judging the data header or the data tail, whether it is a single-chip microcomputer or a host computer, it is best to send an extra padding invalid byte 0x00 before the fixed protocol, because due to hardware reasons, the first byte is often easily lost.
For details, please see the source code.
(1) Hardware platform:
Based on Zhu Zhaoqi 51 single-chip microcomputer learning board.
(2) Functions to be implemented:
The baud rate is: 9600.
Communication protocol: EB 00 55 XX YY
After adding invalid padding bytes, the host computer should actually send: 00 EB 00 55 XX YY
The first bit 00 is an invalid fill byte to prevent the first byte from being lost due to hardware reasons.
The 2nd, 3rd and 4th digits EB 00 55 are the data header.
The last two digits XX YY are valid data.
At any time, in a string of data received by the MCU from the computer "Serial Port Debug Assistant" host computer, as long as the data contains the keyword EB 00 55, and the two bytes of data XX YY after this keyword are 01 02 respectively, the buzzer will beep once to indicate that the received data header and valid data are correct.
(3) The source code is explained as follows:
#include "REG52.H"
#define const_voice_short 40 //Duration of the buzzer short call
#define const_rc_size 10 //Buffer array size for receiving serial port interrupt data
#define const_receive_time 5 //If no serial data comes in after this time, it is considered that a string of data has been received. This time can be adjusted according to the actual situation
void initial_myself(void);
void initial_peripheral(void);
void delay_long(unsigned int uiDelaylong);
void T0_time(void); //Timer interrupt function
void usart_receive(void); //Serial port receive interrupt function
void usart_service(void); //Serial port service program, in the main function
sbit beep_dr=P2^7; //Buzzer driver IO port
unsigned int uiSendCnt=0; //Timer used to identify whether the serial port has received a string of data
unsigned char ucSendLock=1; //Self-locking variable of the serial port service program. Each time a string of data is received, it is processed only once.
unsigned int uiRcregTotal=0; // represents how much data the current buffer has received
unsigned char ucRcregBuf[const_rc_size]; //Buffer array for receiving serial port interrupt data
unsigned int uiRcMoveIndex=0; //Intermediate variable used to parse data protocol
unsigned int uiVoiceCnt=0; //Buzzer beeping duration counter
void main()
{
initial_myself();
delay_long(100);
initial_peripheral();
while(1)
{
usart_service(); //Serial port service program
}
}
void usart_service(void) //Serial port service program, in the main function
{
/* Note 1:
* The principle of identifying whether a string of data has been completely received:
* If no byte of data is received within the specified time, it is considered that a string of data has been received, and then the data protocol is entered.
* Parsing and processing stage. The implementation of this function should be read together with the timing interrupt and serial port interrupt programs to understand the relationship between them.
*/
if(uiSendCnt>=const_receive_time&&ucSendLock==1) //Indicates that no new data is coming from the serial port after a certain period of time.
{
ucSendLock=0; //Lock after processing once, no need to come in every time unless there is new data to be received
//The following code enters the stage of data protocol parsing and data processing
uiRcMoveIndex=0; //Since it is to judge the data head, the subscript movement variable starts from 0 of the array and moves to the end
/* Note 2:
* To judge the data header and enter the loop to parse the data protocol, two conditions must be met:
* First: The maximum receive buffer data must be greater than the length of a string of data (here is 5. Including 2 valid data and 3 data headers)
* Second: The cursor uiRcMoveIndex must be less than or equal to the maximum receive buffer data minus the length of a string of data (here is 5. Including 2 valid data and 3 data headers)
*/
while(uiRcregTotal>=5&&uiRcMoveIndex<=(uiRcregTotal-5))
{
if(ucRcregBuf[uiRcMoveIndex+0]==0xeb&&ucRcregBuf[uiRcMoveIndex+1]==0x00&&ucRcregBuf[uiRcMoveIndex+2]==0x55) //judgment of data header eb 00 55
{
if(ucRcregBuf[uiRcMoveIndex+3]==0x01&&ucRcregBuf[uiRcMoveIndex+4]==0x02) //Judgement of valid data 01 02
{
uiVoiceCnt=const_voice_short; //The buzzer makes a sound, indicating that the data header and valid data are received correctly
}
break; //Exit the loop
}
uiRcMoveIndex++; //Because it is to judge the data head, the cursor moves towards the end of the array
}
uiRcregTotal=0; // Clear the buffer index to facilitate receiving new data from index 0 next time
}
}
void T0_time(void) interrupt 1 //Timer interrupt
{
TF0=0; //Clear interrupt flag
TR0=0; //Disable interrupt
if(uiSendCnt
{
uiSendCnt++; //On the surface, the data is continuously accumulated, but in the serial port interrupt, it will be cleared every time a byte is received, unless there is no serial port data in the middle
ucSendLock=1; //Open the self-locking flag
}
if(uiVoiceCnt!=0)
{
uiVoiceCnt--; //Every time the timer interrupt is entered, it will be decremented by 1 until it is equal to zero. Then the beeping will stop.
beep_dr=0; //The buzzer is controlled by a PNP transistor and starts beeping when the voltage level is low.
}
else
{
; //Add an extra empty instruction here to maintain symmetry with the number of if bracket statements, both are two instructions. It is also OK not to add it.
beep_dr=1; //The buzzer is controlled by a PNP transistor, and it stops beeping when the level is high.
}
TH0=0xfe; //Reinstall initial value (65535-500)=65035=0xfe0b
TL0=0x0b;
TR0=1; //Open interrupt
}
void usart_receive(void) interrupt 4 //Serial port receiving data interrupt
{
if(RI==1)
{
RI = 0;
++uiRcregTotal;
if(uiRcregTotal>const_rc_size) //Exceeds the buffer
{
uiRcregTotal=const_rc_size;
}
ucRcregBuf[uiRcregTotal-1]=SBUF; //Cache the data received by the serial port into the receiving buffer
uiSendCnt=0; // Feed the dog in time. Although the main function keeps accumulating, it will never grow as long as the serial port data has not been sent out, because each interrupt is cleared.
}
else //I don't use this code on other MCUs. Maybe adding "TI = 0;" on 51 MCU will improve stability.
{
TI = 0;
}
}
void delay_long(unsigned int uiDelayLong)
{
unsigned int i;
unsigned int j;
for(i=0;i
{
for(j=0;j<500;j++) //Number of empty instructions in the embedded loop
{
; //A semicolon is equivalent to executing an empty statement
}
}
}
void initial_myself(void) //Initialize the MCU in the first zone
{
beep_dr=1; //Use PNP transistor to control the buzzer, it will not sound when the output is high level.
//Configure the timer
TMOD=0x01; //Set timer 0 to working mode 1
TH0=0xfe; //Reinstall initial value (65535-500)=65035=0xfe0b
TL0=0x0b;
//Configure the serial port
SCON=0x50;
TMOD=0X21;
TH1=TL1=-(11059200L/12/32/9600); //I am not sure what this configuration code means, but it is related to the baud rate of the serial port.
TR1=1;
}
void initial_peripheral(void) // Initialize the periphery of the second zone
{
EA=1; //Open the general interrupt
ES=1; //Enable serial port interrupt
ET0=1; //Enable timer interrupt
TR0=1; //Start timing interrupt
}
Closing remarks:
This section describes the commonly used program framework for judging the data header to receive a string of data. However, in many projects, it is not enough to just judge the data header. A more detailed communication protocol is required, such as a communication protocol that can include data type, valid data length, valid data, and data verification. How to write such a program? For details, please listen to the next analysis - commonly used custom serial port communication protocols.
Previous article:Section 38: Determine the end of the data to receive a string of data serial port general program framework
Next article:Section 40: Commonly used custom serial communication protocols
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- Sn-doped CuO nanostructure-based ethanol gas sensor for real-time drunk driving detection in vehicles
- The "three major operators" are gone? The fourth giant emerges!
- [GD32L233C-START Review] Part 2: Porting RTThread from Scratch
- Wuhan ADAS Company Gaoxin is recruiting MCU/embedded driver/FPGA development engineers
- CircuitPython now supports STM32
- [Evaluation of Anxinke Bluetooth Development Board PB-02-Kit] AT command test
- [National Technology M4 core hot-selling N32G45XVL evaluation] Part 4 Three-phase BLDC motor "six-step" control waveform generation
- Use two ultrasonic modules to compare the signal distance from another ultrasonic module
- 【Guess the topic with prizes】Guess the topic of this year’s TI provincial competition?
- How is this LED lamp made?
- C6678 Network port initialization failed