51 MCU common IO port simulates serial port query method

Publisher:EtherealBeautyLatest update time:2012-08-04 Source: 61ic Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

New and old friends in the forum. I wish you all a happy new year. At the beginning of the new year, I will give you a little trick. Engineers often encounter situations where they need multiple serial ports for communication, but most low-end microcontrollers only have one serial port or even no serial port. At this time, whether it is to choose a high-end chip or change the system design, it is a relatively troublesome thing. I took out the program that used ordinary I/O ports to simulate serial port communication for your reference. I hope you brothers will not criticize it. Basic principle: We simulate serial port mode 1. It is the most common mode. One start bit, 8 data bits, and one stop bit. The most important thing to simulate the serial port is to calculate the time of each bit. Taking the baud rate of 9600 as an example, 9600 bits are sent per second, and each bit is 1/9600 seconds, about 104 microseconds. We need to make a precise delay, delay time + time to set the IO port = 104 microseconds. The start bit is in a low state, and then delay one bit time. The stop bit is in a high state, and it is also a bit time. The data bit is 8 bits. When sending, the low bit is sent first, and when receiving, the low bit is received first. After understanding these, it is very easy to make an IO simulation serial port program. Let's start. First, a simple schematic diagram: there is only a MAX232 chip, nothing to say, you can understand it at a glance. Use the ordinary I/O port of the microcontroller, and the 232 data input end uses the P3.2 port of the 51 microcontroller (external interrupt port 1, it can also be connected to the ordinary port, and the serial port with simulated interrupt mode will be useful. Haha). The data output is P0.4 (any port will do).
Click to browse the next page


In the following program, you only need to use P0.4 and P3.2 as serial ports directly. After testing, there is no problem at all.
2. The underlying function code is as follows:

sbit TXD1 = P0^4; //define analog output pin
sbit RXD1 = P3^2; //define analog input pin

bdata unsigned char SBUF1; //define a bit operation variable
sbit SBUF1_bit0 = SBUF1^0;
sbit SBUF1_bit1 = SBUF1^1;
sbit SBUF1_bit2 = SBUF1^2;
sbit SBUF1_bit3 = SBUF1^3;
sbit SBUF1_bit4 = SBUF1^4;
sbit SBUF1_bit5 = SBUF1^5;
sbit SBUF1_bit6 = SBUF1^6;
sbit SBUF1_bit7 = SBUF1^7;

void delay_bps() {unsigned char i; for (i = 0; i < 29; i++); _nop_();_nop_();} //Baud rate 9600 Simulate a 9600 baud rate

unsigned char getchar2() //Simulate receiving a byte of data
{
	while (RXD1);
    _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
    delay_bps();
    SBUF1_bit0 = RXD1; //0       
    delay_bps();
    SBUF1_bit1 = RXD1; //1       
    delay_bps();
    SBUF1_bit2 = RXD1; //2       
    delay_bps();
    SBUF1_bit3 = RXD1; //3       
    delay_bps();
    SBUF1_bit4 = RXD1; //4       
    delay_bps();
    SBUF1_bit5 = RXD1; //5       
    delay_bps();
    SBUF1_bit6 = RXD1; //6       
    delay_bps();
    SBUF1_bit7 = RXD1; //7       
	delay_bps();
    return(SBUF1); //Return the read data
}

void putchar2(unsigned char input) //Simulate sending a byte of data
{
    SBUF1 = input;
    TXD1 = 0; //Start bit
    delay_bps();    
    TXD1 = SBUF1_bit0; //0
    delay_bps();    
    TXD1 = SBUF1_bit1; //1
    delay_bps();    
    TXD1 = SBUF1_bit2; //2
    delay_bps();    
    TXD1 = SBUF1_bit3; //3
    delay_bps();    
    TXD1 = SBUF1_bit4; //4
    delay_bps();    
    TXD1 = SBUF1_bit5; //5
    delay_bps();    
    TXD1 = SBUF1_bit6; //6
    delay_bps();    
    TXD1 = SBUF1_bit7; //7
    delay_bps();    
    TXD1 = 1; //Stop bit
    delay_bps();    
}

3. Implement serial communication. Directly call the getchar2() and putchar2() functions above in the main program file, and cooperate with the computer's serial port to implement the serial communication function.
Click to browse the next page
4. Please refer to the complete program file, but this serial communication is a program query method. If there is an interrupt program in the program, it is likely to cause the received data to be lost. I will continue to post a thread later and send the serial communication program using the interrupt method to everyone to see. Note: 1. The baud rate can have errors, but the error of each bit cannot be greater than 3%. 2. Interrupts may change the delay time. If the program in your interrupt is long, interrupts should be disabled when simulating serial port reception and transmission. 3. When receiving, delay 1.5 bit times (one start bit + half a data bit). Try to place the sampling point of the data bit in the middle of the data bit. [page]

Complete program engineering source code: click to download

Main program:

#include 
#include "delay.h"
#include "sub4094.c"
#include 
sbit spk = P2^5; //Define the I/O port P2.5 used by the buzzer
sbit LED = P2^7;
#include "subuart2.c"


void main (void)
{
unsigned char first,zjgs,order,zhen_xh,jym,end; //Define the start word, number of bytes, command code, frame number, check code, end word
unsigned char i; //define a random variable
unsigned char sum; //Define the checksum used by the microcontroller for calculation
unsigned char LED_contrl; //Indicator light control word
unsigned contrl_1,contrl_2; //shift variable
//unsigned int delay_counter;
P5=0xEF; // Enable the running light and shield the digital tube
P4=0x00; //All running lights are on	
update4094(); //Refresh the status of the running light
delay_ms(300);
P4=0xFF; //All running lights are off
update4094(); //Refresh the status of the running light
while(1)
{
	first=getchar2(); //Read 6 data for processing.
	zjgs=getchar2();
	order=getchar2();
	zhen_xh=getchar2();
	jym=getchar2();
	end=getchar2();
	if(0xfa != first) goto end;
	sum=zjgs+order+zhen_xh;
	if(sum != jym)
	{
		putchar2(0xfa); //Starting word
		putchar2(0x07); //Number of bytes
		sum=0x07;
		putchar2(order); //Received command code
		sum+=order;
		putchar2(zhen_xh); //Received frame number
        putchar2(0x00); //Command check error flag
		sum+=zhen_xh;
		putchar2(sum); //check code
		putchar2(0xfb);
		//The buzzer sounds an alarm and the indicator light flashes
		for(i=0;i<8;i++)  
		{
		    LED=~LED; //Reverse indicator light
			spk=~spk; //Invert the buzzer
			delay_ms(200);
		}
		goto end;
	}
	if(0xfb != end) goto end;
	switch(order)
	{
		case 1: //Return the received command to the serial port
				LED = 0;
				putchar2(first); //Starting character  
				putchar2(zjgs); //Number of bytes
				putchar2(order); //command code
				putchar2(zhen_xh); //frame number
				putchar2(jym); //check code
				putchar2(end); //End character
				delay_ms(50);
				LED=1;
				//The water light effect moves right in a loop
				P4=0xff; //Turn off all indicator lights
				update4094();
   				LED_contrl=0x01; //Initialize indicator light control byte
 				delay_ms(50); //delay 300MS
 				for(i=0;i<8;i++)
        		{
            	    P4=~LED_contrl; //Light up the corresponding indicator light of the control byte
            		update4094();
					delay_ms(50);
					LED_contrl<<=1;
        		}
				P4=0xff; //Turn off all indicator lights
				update4094();
				break;
		case 2: //Return the received command to the serial port
				putchar2(first); //Starting character  
				putchar2(zjgs); //Number of bytes
				putchar2(order); //command code
				putchar2(zhen_xh); //frame number
				putchar2(jym); //check code
				putchar2(end); //End character
				//The running light effect lights up one by one from left to right
				P4=0xff; //Turn off all indicator lights
    			update4094();
				LED_contrl=0xff; //Initialize indicator light control byte
 				delay_ms(50);
  				for(i=0;i<8;i++)
     			{
   				    LED_contrl<<=1;
		    		P4=LED_contrl;
					update4094();
					delay_ms(50);
                }
				break;
		case 3: //Return the received command to the serial port
				putchar2(first); //Starting character  
				putchar2(zjgs); //Number of bytes
				putchar2(order); //command code
				putchar2(zhen_xh); //frame number
				putchar2(jym); //check code
				putchar2(end); //End character
				//Flowing light effect loop collision
				P4=0xff; //Turn off all indicator lights
				update4094();
				contrl_1=0x02; //Initialize shift variable 1
 				contrl_2=0x80; //Initialize shift variable 2
 				delay_ms(50);
  				for(i=0;i<8;i++)
    			{
		            LED_contrl=contrl_1|contrl_2;
  					P4=~LED_contrl; //Light up the corresponding indicator light of the control byte
     				update4094();
					delay_ms(50);
  					contrl_1<<=1; //Shift variable 1 left by 1 bit
   					contrl_2>>=1; //Shift variable 2 right by 1 bit
     			}
                P4=0xff; //Turn off all indicator lights
				update4094();
                break;
		default:break;
	}
	end:;

}
}
Reference address:51 MCU common IO port simulates serial port query method

Previous article:ATMEGA16 read and write 24C02 C51 program
Next article:LCD1602 LCD screen + DS1302 clock chip electronic clock

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号