Introduction to the method of realizing serial port simulation by microcontroller software

Publisher:VolareLatest update time:2011-12-09 Keywords:MCU Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Introduction to three methods of simulating serial ports using single-chip microcomputers

The analog serial port uses the two input and output pins of 51, such as P1.0 and P1.1, to set 1 or 0 to represent high and low levels, which is the bit in serial communication. If the start bit is low level, it is set to 0, and if the stop bit is high level, it is set to 1. Various data bits and check bits are set to 1 or 0 according to the situation. As for the baud rate of serial communication, it is just the duration of each bit level. The higher the baud rate, the shorter the duration. If the baud rate is 9600BPS, 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 microcontroller is achieved by executing several instructions, because each instruction is 1-3 instruction cycles, that is, the delay is carried out through several instruction cycles. The microcontroller often uses a crystal oscillator of 11.0592M. Now I want to tell you the origin of this strange number. With this frequency, the time of each instruction cycle is (12/11.0592)us. So how many instruction cycles are needed for each bit of 9600BPS?
Instruction cycle s = (1000000/9600)/(12/11.0592) = 96, which is exactly an integer. If it is 4800BPS, it is 96x2=192, and if it is 19200BPS, it is 48. Other baud rates are not counted, and they are all exactly integer instruction cycles. Isn't it wonderful? As for
other crystal oscillator frequencies, you can calculate them by yourself.

Now let's take the 11.0592M crystal oscillator as an example to discuss three methods of simulating serial ports.

Method 1: Delay method

Through the above calculation, we know that each bit of the serial port needs a delay of 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-bit data bit
while(i--)
{
TXD=(bit)(input&0x01); //Transmit low bit first
Delay2cp(36);
input=input>>1;
}
//Send check bit (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-bit data
Delay2cp(RDDYN*1.5); //Note here, wait for the start bit
while(i--)
{
Output >>=1;
if(RXD) Output =0x80; //Receive the low bit first
Delay2cp(35); //(96-26)/2, the loop
takes up 26 instruction cycles in total
}
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 method has certain difficulties in receiving, mainly because the sampling positioning needs to be more accurate, and the number of instruction cycles for each statement

must also be known .
This method can simulate several serial ports, and many people use it in practice. However, if you use Keil
C, I do not recommend this method. The above program has been tested on three single-chip computers: P89C52, AT89C52, and W78E52.

Method 2: Counting

method The counter of 51 increases by 1 in each instruction cycle until it overflows, and the hardware sets the overflow flag. In this way, we can
use the method of presetting the initial value to make the machine overflow once every 96 instruction cycles, and the program constantly queries 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; //Pre-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-bit data
while(i--)
{
TXD=(bit)(input&0x01); //Transmit low bit first
WaitTF0();
input=input>>1;
}
//Send check bit (none)
//Send end bit
TXD=(bit)1;
WaitTF0();
TR0=0;
}
//Query counter overflow flag
void WaitTF0( void )
{
while(!TF0);
TF0=0;
}
For the receiving program, you can refer to the next method and will not write it out. I personally feel that this method is good. Both receiving and sending
are very accurate. In addition, there is no need to calculate the number of instruction cycles for each statement.

Method 3: Interrupt method The

interrupt method is similar to the counter method, except that an interrupt is generated when the counter overflows. The user can
set a flag in the interrupt program, and the program continuously queries the flag to decide whether to send or receive the next bit. Of course, the interrupt needs to be initialized in the program
, and the interrupt program is written at the same time. This program uses the Timer0 interrupt.
#define TM0_FLAG P1_2 //Set the transmission flag
//Initialize the counter and interrupt
void S2INI(void)
{
TMOD =0x02; //Counter 0, mode 2
TH0=0xA0; //Preset value is 256-96=140, hexadecimal A0
TL0=TH0;
TR0=0; //
Start using it when sending or receiving
TF0=0;
ET0=1; //Enable
timer 0 interrupt
EA=1; //Interrupt enable
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; //Receive 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 flag.
}
//Query transmission flag
void WaitTF0( void )
{
while(!TM0_FLAG);
TM0_FLAG=0; //Clear flag
}
The interrupt method is also the method I recommend, which is similar to the counting method. The sending program refers to the counting method, which is believed to be a very easy
task.
It should also be noted that the serial port mentioned in this article is the usual three-wire asynchronous communication serial port (UART), which only uses RXD, TXD, and GND.
//****************************************************************

[page]

AVR software simulation serial port program

Source: coldra data room Author: coldra


Output: Use timer to control the output bit of ordinary IO port
Input: Use external interrupt + timer to determine the width of the bit

I haven't rested for several days. I wrote it in my spare time. I didn't find other people's reference programs, but it is finally stable. In fact, there should be many other methods to try, such as using PWM to output serial data, using input to capture received data, or timing query, or using any IO port interrupt, then each pin may be There are

still some problems now. When full-duplex is sending and receiving at the same time, the sending occasionally fails. It is a bit wasteful to occupy two timers. I will modify it later. It is best to add various wave rates

This program is directly extracted and the irrelevant parts are deleted. Some variables may be useless or paragraphs may be omitted. Please forgive me

#
include #include
#include
#include

#define Sbit1() PORTD =1<#define Sbit0() PORTD&=~(1<

volatile unsigned int
eep_ms,//millisecond timing
keytime, //wait time
SoundOnTime; ////
volatile unsigned char
rdata,
key,
start=0,
keycode, //
*TxPoint,
rtime,
INT0_time, //interrupt times

RxLength=0, //receive length
RUDR, //simulate serial port received data
TxLength, //serial port send data length
SUDR; //serial port send data

unsigned char arr[10],DispBuff[10];


void Initial_IO(void)//IO port initialization
{
DDRD = 0X82; //PD1 serial port output, PD0 serial port input, PD2 simulate serial port input (INT0)
PORTD = 0X82; //PD1 output high level
}

void Initial_INT0(void)
{
EICRA =(1< EIMSK =1< }

void Initial_timer0(void) //Timer0 initialization
{
TCCR0B =(1< TIMSK0 =(1< }

void Initial_timer1(void)
{
TCCR1A=(1< TCCR1B=(1< ICR1=1000;
TIMSK1 =(1< }

void Initial_timer2(void)
{
TCCR2B=(1< TIMSK2 =(1< }


void Initial_WDR(void) //Watchdog initialization
{
wdt_enable(WDTO_1S);
wdt_reset();
}


void Initial(void)
{
Initial_IO();
Initial_timer0(
);
Initial_timer1( );
Initial_timer2(); Initial_INT0();
Initial_WDR();
sei(); }
/ * Start serial


port sending*/ void SendData
(unsigned char *P,unsigned char DataLength) { TxLength =
DataLength
; if((rdata)&&(eep_ms>10))//Start sending after receiving data with a delay of 10ms, and send back verification data { key=0; SendData(&DispBuff[0],9);//Send 9 bits of data of DispBuff[0]

















while(TxLength);//Wait for sending to complete
rdata=0;
eep_ms=0;
}
}

[page]

/*Timer 0, 100us overflow interrupt*/
SIGNAL(SIG_OVERFLOW0)
{
TCNT0=151;//Reload data, timing interval is 151---255, a total of 104uS, one bit time
if(TxLength)//
{
if(start==0)
{
Sbit0();//Start bit
SUDR=*(TxPoint++);
}
else
{
if((start<=8))
{
if(SUDR&(1<<(start-1)))Sbit1();//Data 1
else Sbit0();//Data 0
}
else Sbit1();//Stop bit
}
if(start<10)start++;
else
{
TxLength--;//One byte sent, the number of bytes minus 1
start=0;
}//
}
}

/*Timer 1, 1ms overflow interrupt*/
SIGNAL(SIG_OVERFLOW1)
{
eep_ms++;
}
/*Timer 2*/
SIGNAL(SIG_OVERFLOW2)
{
sei();
if(INT0_time)//There is data
{
INT0_time=0;//The number of interrupts is cleared to 0
rdata=1;//Set the data flag
eep_ms=0;
if(RxLength<10)DispBuff[RxLength++]=RUDR;

}
if(rtime<4)rtime++;//Byte interval time, restart a frame after 3 bytes
else RxLength=0;
}

SIGNAL(SIG_INTERRUPT0)//INT0, edge triggered interrupt
{
unsigned char temp,temp2=0;
static unsigned char pre_TCNT2,j=0;
if(INT0_time==0)//The first falling edge interrupt of a byte, starts from the start bit
{
TCNT2=130;
pre_TCNT2=130;
RUDR=0xff;//Initial value of received data
j=0; //The number of bits is cleared
INT0_time++; //The number of interrupts is increased by one
}
else
{
temp=TCNT2;
if(temp>pre_TCNT2)temp2=temp-pre_TCNT2; //Take a high/low level width
if(temp2>10) //Filter narrow level (interference signal)
{
pre_TCNT2=temp; //Record the previous time value
temp=0;
while(temp2>13) //Calculate the number of bits, about 13 is one bit (8*13=104uS)
{
temp2-=13; //
temp++;
}
if(temp2>6)temp++; //Calculate the number of bits, generally 13 is one bit
if(INT0_time==1)temp-=1;
if(INT0_time&1) //Odd number of interrupts
{
while(temp) //Number of bit 0s
{
RUDR&=~(1< temp--;
j++;
}
}
else j+=temp; //even number, number of 1 bits, skip
INT0_time++; //interrupt count plus one
}
}
rtime=0;
}

Keywords:MCU Reference address:Introduction to the method of realizing serial port simulation by microcontroller software

Previous article:Using 51 single chip microcomputer to realize serial port-Ethernet converter
Next article:A brief discussion on the application of single chip microcomputer in temperature control system

Recommended ReadingLatest update time:2024-11-16 19:39

About 51 single chip microcomputer digital tube image elimination
Take a look at the schematic: Baidu Encyclopedia: 74HC573 digital tube ----------------------------------------------------------------------------------------------------------- The 74HC573 is a transparent latch with eight outputs. The outputs are tri-state gates and it is a high performance silicon gate CMOS devi
[Microcontroller]
About 51 single chip microcomputer digital tube image elimination
Design of piezoelectric jacquard control system based on ATmega128 microcontroller
0 Introduction Since its introduction in 1884, the Jacquard device of the Jacquard warp knitting machine has developed from mechanical to electromagnetic and now piezoelectric, namely the Piezo Jacquard system, which has completely changed the characteristics of the Jacquard device that requires complicated component
[Microcontroller]
Design of piezoelectric jacquard control system based on ATmega128 microcontroller
CEVA Expands Sensor Fusion Portfolio with New Sensor Hub MCU for High-Precision Motion Tracking and Orientation Detection
CEVA Expands Sensor Fusion Portfolio with New Sensor Hub MCU for High-Precision Motion Tracking and Orientation Detection The FSP201 provides excellent orientation and heading accuracy, providing a high-quality, low-cost, sensor-agnostic solution for robotics, 3D audio, Metaverse hardware, and general
[sensor]
CEVA Expands Sensor Fusion Portfolio with New Sensor Hub MCU for High-Precision Motion Tracking and Orientation Detection
NRF24L01 wireless receiving and transmitting program based on 51 single chip microcomputer
The reception and transmission of data are judged by the flashing of the light. There are programs for the receiving end and the transmitting end.     If 24L01 uses reg51, then both devices must use reg51. If reg52 is used, then both must use reg52!     PC sends commands to the microcontroller through the serial port
[Microcontroller]
NRF24L01 wireless receiving and transmitting program based on 51 single chip microcomputer
IAR has reached a strategic cooperation with Xianji Semiconductor to fully support the development of Xianji Semiconductor’s high-performance RISC-V MCUs.
(China | Shanghai) June 14, 2023 - During the first exhibition of Embedded World China, IAR, a global leader in embedded development software and services, and HPMicro, a leading domestic high-performance MCU manufacturer, jointly announced a strategic cooperation Agreement: IAR’s latest Embedded Workbench for RISC
[Embedded]
IAR has reached a strategic cooperation with Xianji Semiconductor to fully support the development of Xianji Semiconductor’s high-performance RISC-V MCUs.
Simple STC15F104E MCU Timing Alarm Production
In an extraordinary period, children can't go to school, adults are not at home, and they sleep until 10 o'clock every morning, which is a bit too much, so I made a simple timer alarm as an alarm clock, mainly to cooperate with the network timing function of Xiaomi smart socket. It's just my own small creation for ref
[Microcontroller]
Simple STC15F104E MCU Timing Alarm Production
MCU ADC sampling algorithm-limiting filter method
The limiting filter method is to limit the deviation of the current sampling value from the previous sampling value through software. If the deviation between the current sampling value and the previous sampling value exceeds the set maximum deviation value, the current sampling value is discarded. Let's look at the
[Microcontroller]
MCU ADC sampling algorithm-limiting filter method
PIC microcontroller advertising light program
Program introduction: The light moves left and right and flashes. The program uses the subroutine function. //** Date: Wednesday, November 21, 2012 21:51:18 #define MX_PIC   //Defines for microcontroller #define P16F690 #define MX_EE #define MX_EE_SIZE 256 #define MX_SPI #define MX_SPI_BCB #define MX_S
[Microcontroller]
PIC microcontroller advertising light program
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号