With the increasingly frequent use of single chip microcomputers, it is also common in various applications to use it as a front-end processor for collection and communication. Generally, the front-end processor is used to collect various terminal data for processing and storage, and then actively or passively reported to the management station. . In this case, one serial port is needed for acquisition, and another serial port is needed for reporting. This requires the MCU to have the function of dual serial ports, but we know that the general 51 series only provides one serial port, so the other serial port can only be simulated by the program. .

With the increasingly frequent use of single chip microcomputers, it is also common in various applications to use it as a front-end processor for collection and communication. Generally, the front-end processor is used to collect various terminal data for processing and storage, and then actively or passively reported to the management station. . In this case, one serial port is needed for acquisition, and another serial port is needed for reporting. This requires the MCU to have the function of dual serial ports, but we know that the general 51 series only provides one serial port, so the other serial port can only be simulated by the program. .

The analog serial port mentioned in this article is to use the two input and output pins of 51 such as P1.0 and P1.1. Set 1 or 0 to represent high and low levels respectively, which is the bit in serial communication, such as the start bit. If low level is used, set it to 0; if the stop bit is high level, set it to 1, and various data bits and parity bits are set to 1 or 0 according to the situation. As for the baud rate of serial communication, after all, it is only the duration of each bit level. The higher the baud rate, the shorter the duration. For example, the baud rate is 9600BPS, that is, the transmission time of each bit is 1000ms/9600=0.104ms, that is, the delay between bits is 0.104 milliseconds. The delay of the single-chip microcomputer is achieved by executing several instructions, because each instruction is 1-3 instruction cycles, but it is delayed by several instruction cycles. The single-chip microcomputer usually uses the 11.0592M crystal oscillator. I want to tell you the origin of this strange number. Using this frequency, the time of each instruction cycle is (12/11.0592) us, so how many instruction cycles does each bit of the baud rate need to be integrated? Instruction cycle s=(1000000/9600)/(12/11.0592)=96, which is just an integer, if it is 4800BPS, it is 96×2=192, if it is 19200BPS, it is 48, other baud rates are ignored , They all happen to be an integer number of instruction cycles, wonderful. As for other crystal frequencies, let’s calculate it by yourself. Now take the 11.0592M crystal oscillator as an example to talk about three methods of simulating the serial port.

Analysis of Design Schemes of Three Analog Serial Ports of 51 Single-chip Microcomputer

Method 1: Delay method

Through the above calculations, we all know that each bit of the serial port needs to be delayed by 0.104 seconds, and 96 instruction cycles can be executed in the middle.

#define uchar unsigned char
sbit P1_0 = 0x90;
sbit P1_1 = 0x91;
sbit P1_2 = 0x92;
#define RXD P1_0
#define TXD P1_1
#define WRDYN 44 //write delay
#define RDDYN 43 //Read delay
//Write a byte to the serial port
void WByte (uchar input)
{
uchar i=8;
TXD=(bit)0; //Send start bit
Delay2cp(39);
//Send 8 data bits
while (i–)
{
TXD=(bit)(input&0x01); //The low bit is transmitted first
Delay2cp(36);
input=input》》1;
}
//Send check digit (none)
TXD=(bit)1; //Send end bit
Delay2cp(46);
}
//Read a byte from the serial port
uchar RByte(void)
{
uchar Output=0;
uchar i=8;
uchar
temp=RDDYN; //Send 8 data bits
Delay2cp(RDDYN*1.5); //Note here, wait for the start bit while(i–)
{
Output 》》=1;
if (RXD) Output |=0x80; //Close the low bit first
Delay2cp(35); //(96-26)/2, the loop occupies a total of 26 instruction cycles}
while (-temp) //Search for the end bit within the specified time.
{
Delay2cp(1);
if (RXD) break; //Exit after receiving the end bit
}
return Output;
}
//Delay program*
void Delay2cp (unsigned char i)
{
while(–i); //Exactly two instruction cycles.
}
This kind of method has certain difficulty in receiving, mainly because the sampling location needs to be more accurate, and the number of instruction cycles of each sentence must be known. This method may simulate several serial ports, and many people use it in practice, but if you use Keil C, I do not recommend this method. The above program has passed the experiment on P89C52, AT89C52, and W78E52 microcontrollers.

Method two: counting method

The counter of 51 is incremented by 1 in every instruction cycle until it overflows, and the hardware sets the overflow flag at the same time. In this way, we can make the machine overflow every 96 instruction cycles by presetting the initial value, and the program will constantly query the overflow flag to decide whether to send or receive the next bit.

//Counter initialization
void S2INI (void)
{
TMOD |=0x02; //Counter 0, Mode 2
TH0=0xA0; //The preset value is 256-96=140, hexadecimal A0
TL0=TH0;
TR0=1; //Start counting
TF0=0;
}
void WByte (uchar input)
{
//Send start bit
uchar i=8;
TR0=1;
TXD=(bit)0;
WaitTF0();
//Send 8 data bits
while (i–)
{
TXD=(bit)(input&0x01); //The low bit is transmitted first
WaitTF0();
input=input》》1;
}
//Send check digit (none)
//Send end bit
TXD=(bit)1;
WaitTF0();
TR0=0;
}
//Query counter overflow flag
void WaitTF0 (void)
{
while(!TF0);
TF0=0;
}
For the received program, you can refer to the next method and not write it out again. This method personally feels good, receiving and sending are very accurate, and there is no need to calculate the number of instruction cycles for each statement.

Method 3: Interruption method

The interrupt method is similar to the counter method, except that an interrupt is generated when the calculator overflows. The user can set a flag in the interrupt program, and the program constantly queries the flag to determine whether to send or receive the next bit. Of course, the program needs to correct The interrupt is initialized and the interrupt program is written at the same time. This program uses Timer0 interrupt.

#define TM0_FLAG P1_2 //Set the transmission flag bit
//Counter and interrupt initialization
void S2INI (void)
{
TMOD |=0x02; //Counter 0, Mode 2
TH0=0xA0; //The preset value is 256-96=140, hexadecimal A0
TL0=TH0;
TR0=0; //Start using when sending or receiving
TF0=0;
ET0=1; //Enable timer 0 interrupt
EA=1; //Interrupt allow master switch
}
//Receive a character
uchar RByte()
{
uchar Output=0;
uchar i=8;
TR0=1; //Start TImer0
TL0=TH0;
WaitTF0(); //Wait for the start bit
//Send 8 data bits
while (i–)
{
Output 》》=1;
if (RXD) Output |=0x80; //Close the low bit first
WaitTF0(); //Inter-bit delay
}
while (! TM0_FLAG) if (RXD) break;
TR0=0; //Stop TImer0
return Output;
}
//Interrupt 1 handler
void IntTImer0() interrupt 1
{
TM0_FLAG=1; //Set the flag bit.
}
//Query transmission flag
void WaitTF0 (void)
{
while(!TM0_FLAG);
TM0_FLAG=0; //Clear the flag bit
}

The interrupt method is also the method I recommend, which is similar to the counting method. It is easy to refer to the counting method for the sending procedure. In addition, it should be noted that the serial port mentioned in this article is the usual three-wire asynchronous communication serial port (UART), and only RXD, TXD, and GND are used.

The Links:   2MBI150TA-060 TRF7960RHBR LCD-PANEL