Serial port interrupt (9) real-time analysis of user-defined communication protocol – fixed situation of receiving data

This article is the original csdn first release of the blogger. I hope it will be helpful to you after reading it. Please correct me if I have any shortcomings! Let’s communicate and learn together and make progress together!

> Posted by: @日月同光, symbiotic with me_SCM-CSDN Blog

>You are welcome to like the original blogger Sun and Moon Shine Together, and live with me? + follow + collect + comment?.

Column Series: CSDN-MCU Serial Communication Learning Series

>My motto is: “Try your best and be the best version of yourself!

If you want to reprint, please inform us in advance! ! !

Copyright statement: This article is an original article by the CSDN blogger “The sun and the moon shine together, live with me”, and is the only article on CSDN.

6fc58cb779cf4b1abfd70ea313d654a5.png

Table of Contents

1. System design requirements

2. System design principles

3. Hardware design

3.1 Serial port design

3.2LED circuit design

3.3 Buzzer design

4. Software design

4.1 Serial port initialization

4.2 Receiving interrupt

4.3 Timer T0 initialization

4.4 Timer interrupt

4.5 Send data function

4.6 Main program

4.7uart.h

5. Result display

5.1 Control LED

5.2 Control the buzzer

6. Validation software recommendation

1. System design requirements

Virtual terminal com1 sends data to microcontroller com1, and after receiving it, resends the data to com3.

com3 sends data: frame header (1, 2 frames) + data type (3 frames) + data block (4, 5 frames) + check bit (6, 7 frames)

Frame header: 2 frames in total, 55 AA

Data type: 1 frame in total, control the LED light at 01 and control the buzzer at 02

Data block: 2 frames in total, the first frame is the high 8 bits, the second frame is the low 8 bits, the two frames are combined into a 16-bit binary system, used to control the LED lighting/buzzer sounding time.

Validation bit: 2 frames in total, the first frame is sum validation, and the second frame is XOR validation.

com1 re-writes the data: instead of sending all the received data to com3, com1 sends the 3-5th frame data to com3.

2. System design principles

This experiment adopts the idea of “Receiving and processing at the same time“.

Since serial communication is received frame by frame, we can judge the correctness of the frame header data every time we receive a frame.

As for the data to be resent by com1, you can define an array recv_buf to store the data to be sent by com1.

Use the switch-case statement, branches 0 and 1, and then enter the next branch after judging the frame header data 55 and AA respectively.

Branch 2 receives the type + code block (a total of 3 frames) and stores the 3 frames into the array recv_buf. At the same time, it defines two variables specifically for calculating the validation value (the validation variable sum_check and the XOR validation variable xor_check), which are calculated in branch 2 Output the sum validation value and XOR validation value of frames 3-5.

Then enter branches 3 and 4, which are used to determine whether the calculated sum validation and XOR validation values are the same as the received validation frame data. If the sum check and XOR check bits are correct, the reception completion flag recv_flag is set to 1, which means that the received data is completed and correct.

In the main program, based on recv_flag==1, according to the type of data frame, the switch-case statement is used to process the LED/buzzer respectively.

Duration: high 8 bits shifted left by 8 bits + low 8 bits

LED lighting duration: led_data=recv_buf[1]<<8 + recv_buf[2];

Buzzer sound time: beep_data=recv_buf[1]<<8 + recv_buf[2];

Note: recv_buf[0] is the data type, recv_buf[1] is the upper 8 bits, and recv_buf[2] is the lower 8 bits.

3. Hardware design

3.1 Serial port design

The com1 sending end TXD is connected to the com2 sending end TXD, and the com1 receiving end RXD is connected to the com2 receiving end RXD.

The virtual terminal RXD is connected to TXD (because the microcontroller sends data to com3, and the virtual terminal can be understood as the virtual serial port com3).

d530f4a2d47647dbb61a93cd7d44fab1.png

3.2LED circuit design

The LED lamp adopts the common anode connection method. The left end is connected to the power supply (high level 1), and the right end is connected to P1^0 through a resistor. When P1^0 is low level, the LED is turned on and lights up; P1^0 When the level is high, the LED is not conducting and does not light up (off).

5086ca43e8d248269ac4b0f196b9d4ec.png

3.3 Buzzer design

The right end of R2 is connected to P1^7. When P1^7 is low level, the transistor is turned on, and the +5V power supply (which provides voltage and current) is connected to the buzzer. The positive of the buzzer is high voltage. flat; P1^7 is high level, the transistor is not conducting, and the buzzer positive is low level.

4b3aaaa7758a4a07bf8557137f7c498b.png

4. Software design

4.1 Serial port initialization

The baud rate is 9600b/s, the crystal oscillator frequency is 11.0592Mhz, the serial port working mode 1 (8-bit asynchronous communication, variable baud rate), and the timer T1 working mode 2 (8-bit automatic reload).

void UartInit(void) //[email protected]
{
PCON &= 0x7F; //The baud rate is not doubled
SCON = 0x50; //8-bit data, variable baud rate
TMOD &= 0x0F; //Set timer mode
TMOD |= 0x20; //Set timer mode
TL1 = 0xFD; //Set the timing initial value
TH1 = 0xFD; //Set the timed reload value
ET1 = 0; //Disable timer interrupt
ES=1; //Serial port interrupt is turned on
TR1 = 1; //Timer 1 starts timing
}

4.2 Receiving Interrupt

Frame header judgment 55 AA==>Compute 3 frames (1 frame type + 2 frame data blocks), calculate the sum validation value, XOR validation value==>Judge whether the sum validation and XOR validation are correct==>If correct, the reception is completed The flag bit recv_flag is set to 1.

Do not directly use the array recv_buf to store the received data, because the data stored in recv_buf is used to send to com3, and the microcontroller only sends part of the data to com3, and cannot store all the received data in recv_buf. You need todefine recv_data (intermediate value), which is used to receive data from com3.

void ES_timers() interrupt 4 //Receive interrupt
{
static unsigned char machine_step=0;//branch variable
static unsigned char sum_check;//sum validation
static unsigned char xor_check;//XOR effect
if(RI)
{
RI=0; //RI clear to 0
recv_data=SBUF; //Receive data
switch(machine_step)
{
case 0:
if(recv_data==0x55)//Frame header: 55
{
machine_step=1;
}
else
{
machine_step=0;
}
break;
case 1:
if(recv_data==0xAA)//Frame header: AA
{
machine_step=2;
recv_cnt=0;
}
else
{
machine_step=0;
}
break;
case 2:
recv_buf[recv_cnt]=recv_data;//Storage the data to be sent by the microcontroller com1 to the array recv_buf
recv_cnt + + ;
sum_check + =recv_data; //Calculation and validation
xor_check^=recv_data; //Calculate XOR effect
if(recv_cnt>2) //Enter the next branch after storing 3 data (type 01/02 + code fast)
{
machine_step=3;
}
else
{
machine_step=2;
}
break;
case 3:
if(sum_check==recv_data) //sum verification is correct
{
machine_step=4;
}
else
{
machine_step=0;
}
break;
case 4:
if(xor_check==recv_data) //The XOR effect is correct
{
recv_flag=1;//Received correctly
\t\t\t\t\t\t
}
machine_step=0;
sum_check=0; //Sum check variable cleared to 0
xor_check=0; //XOR check variable is cleared to 0
recv_cnt=0;
break;
default:break;
}
   }
}

4.3 Timer T0 initialization

void Timer0_Init(void) //1 millisecond @11.0592MHz
{
TMOD &= 0xF0; //Set timer mode
TMOD |= 0x01; //Set timer mode
TL0 = 0x66; //Set the timing initial value
TH0 = 0xFC; //Set the initial value of the timing
TF0 = 0; //Clear the TF0 flag
ET0=1; //Timer 0 interrupt is turned on
TR0 = 1; //Timer 0 starts timing
}

4.4 Timer interrupt

void T0_timer() interrupt 1 //Use 1ms to count to determine whether the reception is completed
{
TR0=0;
if(led_cnt<led_data)//LED lights up
{
LED=0;
led_cnt + + ;
}
else //LED light off
{
LED=1;
}
if(beep_cnt!=0) //Buzzer sounds
{
Beep=~Beep;
beep_cnt--;
}
TL0 = 0x66; //Set the timing initial value
TH0 = 0xFC; //Set the initial value of the timing
TR0=1;
}

4.5 Send data function

void sendByte(unsigned char dat) //Send one frame of data function
{
SBUF=dat;
while(!TI);
TI=0;
}

void sendString(unsigned char *dat)//Send string function
{
while(*dat != '\0')
{
sendByte(*dat + + );
}
}

4.6 Main Program

#include <reg51.h>
#include "uart.h"

void Timer0_Init(); //Timer 0 function declaration

sbit LED=P1^0;//Bit definition
sbit Beep=P1^7;

void main()
{
UartInit(); //Call the serial port initialization function
Timer0_Init();
EA=1; //Total interrupt enabled
while(1)
{
if(recv_flag==1)//reception completed
{
recv_flag=0;
sendString(recv_buf);//Send buffer data
switch(recv_buf[0])//Determine whether to process LED or buzzer based on type
{
case 0x01:
led_data=recv_buf[1]<<8;//The high 8 bits recv_buf[1] shift left by 8 bits
led_data=led_data + recv_buf[2];//Calculate LED control time
led_cnt=0;
break;
case 0x02:
beep_data=recv_buf[1]<<8;//The high 8 bits recv_buf[1] shift left by 8 bits
beep_data=beep_data + recv_buf[2];//Calculate the buzzer control time
beep_cnt=beep_data;
break;
default:clr_recvbuffer(recv_buf);//Clear cache
break;
}
}
}
}

4.7uart.h

#ifndef __UART_H__
#define __UART_H__

#include <reg51.h>
#include <stdio.h>

#defineMAX_REX_NUM 20
#define MAX_timer_cnt 5

extern unsigned char recv_buf[MAX_REX_NUM];
extern unsigned char recv_cnt;
extern unsigned char start_timer;
extern unsigned char recv_timer_cnt;
extern unsigned char recv_flag;
extern unsigned int led_data;
extern unsigned int beep_data;
extern unsigned int led_cnt;
extern unsigned int beep_cnt;

void UartInit(void);
void sendByte(unsigned char dat);
void sendString(unsigned char *dat);
char putchar(char c);
void clr_recvbuffer(unsigned char *buf);

#endif

5. Result display

5.1 Control LED

Data sent from com3 to com1: 55 AA 01 20 20 41 01

Data sent back by com1 to com3: 01 20 20

Result: The LED lights up for 2020ms and goes off after 2020ms.

c7a62e12be0b478ca077b210ca92f679.png

e4922b820c124eedb1ef586a15da24ec.png

5.2 Control buzzer

Data sent by com3 to com1: 55 AA 02 20 20 42 02

Data sent back by com1 to com3: 02 20 20

Result: The buzzer sounds for 2020ms and stops after 2020ms.

855db8ca351b49368636bf5dc079fb3a.png

cfaf9f643bfc44adb59cd93c79ee8c16.png

6. Validation software recommendations

In order to facilitate readers to learn serial communication, we recommend effectiveness calculation tools.

Link:

XOR check/BCC check calculation-ME2 online tool (metools.info)

efec006f52274022b2e648d12348a47e.png

5f9e2d7f48cc4eab92c1302d326b0a9d.png

Dear readers, please stay tuned, the next article will be more exciting! ! !

If you don’t study for a day, you will have no good ideas. My name is no free food. If you like me, you can support me. The blogger’s name is @日月同光, symbiotic with me.

@日月同光,symbiosis with me_Basics of single-chip microcomputer, single-chip serial communication-CSDN blog@日月同惠,symbiosis with me. Good at basics of single-chip microcomputer, single-chip serial communication, and other aspects of knowledge,@日月同光,symbiosis with me Pay attention to stm32, c language, 51 single chip microcomputer, proteus, single chip microcomputer field.https://blog.csdn.net/LIN___IT?spm=1000.2115.3001.5343

syntaxbug.com © 2021 All Rights Reserved.