51 microcontroller serial port

51 microcontroller serial port

1. Serial communication

1.1 Serial port wiring method

  • RXD: data input pin, data acceptance; STC89 series corresponds to P3.0 port, Shangguan No. 1 has a separate pin

  • TXD: data transmission pin, data transmission; STC89 series corresponds to P3.1 port, Shangguan No. 1 has a separate pin

  • Wiring

    [External link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-FMY5yTZI-1690308835514) (C:\Users\xie19\Pictures\Camera Roll\Screenshot 2023-07-25 185225.png)][External link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-xUfBzHGK-1690308835515) (C:\Users\xie19\Pictures\Camera Roll\Screenshot 2023-07-25 185247.png)]

2. Serial port programming elements

  • The input/output data buffers are both called SBUF , and both use the 99H address code, but they are two independent 8-bit registers.

  • The code is reflected as follows: Want to receive data char data = SBUF Want to send data SBUF = data

  • Recall that UART is an asynchronous serial interface. The two parties in communication use different clocks because the hardware configurations of both parties are different. However, the communication speed needs to be agreed upon, which is called the baud rate .

For computers, others have made the software and can configure it with just a few clicks of the mouse. However, the baud rate configuration of the hard-working microcontroller requires us to write code to configure something bit by bit, and our code must also configure the corresponding parameters.

3. Send a character to PC

#include "reg52.h"
#include "intrins.h"

sfr AUXR=0x8e;	

/*
void UartInit(void)		//[email protected]
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}
*/

void UartInit(void)
{
     AUXR=0x01;
     SCON=0x40; //配置串口工作方式1,REN使能不接收
     TMOD&=0x0F; //配置定时器工作模式
     TMOD|=0x20;
     TL1=0xFD; //配置定时器初值
     TH1=0xFD;
     TR1=1; 
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}



void main()
{
	char data_msg='a';
    UartInit();//C51串口通信初始化	
    //每隔1s发送一次
	while(1)
    {
        Delay1000ms();
        SBUF=data_msg;
        //发送数据往寄存器SBUF写数据就ok        
    }    
}

4. Send a string to PC

#include "reg52.h"
#include "intrins.h"

sfr AUXR=0x8e;	

/*
void UartInit(void)		//[email protected]
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}
*/

void UartInit(void)
{
     AUXR=0x01;
     SCON=0x40; //配置串口工作方式1,REN使能不接收
     TMOD&=0x0F; //配置定时器工作模式
     TMOD|=0x20;
     TL1=0xFD; //配置定时器初值
     TH1=0xFD;
     TR1=1; 
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void sendByte(char data_msg)
{
   SBUF=data_msg;
   while(!TI);
   TI=0;    
}

void sendString(char *str)
{
    while(*str)
   {
        sendByte(*str);
        str++;
   }       
}

void main()
{
	
    UartInit();//C51串口通信初始化	
    //每隔1s发送一次
	while(1)
    {
        Delay1000ms();
        sendString("nihao pc\r\n");       
    }    
}

5.PC lights up the LED through the serial port

#include "reg52.h"
#include "intrins.h"

sbit D5=P3^7;
sfr AUXR=0x8e;	

/*
void UartInit(void)		//[email protected]
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}
*/

void UartInit(void)
{
     AUXR =0x01;
     SCON =0x50; //配置串口工作方式1,REN使能不接收
     TMOD&=0x0F; //配置定时器工作模式
     TMOD|=0x20;
     TL1  =0xFD; //配置定时器初值
     TH1  =0xFD;
     TR1  =1; 
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void sendByte(char data_msg)
{
   SBUF=data_msg;
   while(!TI);
   TI=0;    
}

void sendString(char *str)
{
    while(*str)
   {
        sendByte(*str);
        str++;
   }       
}

void main()
{  
    char cmd; 
    D5=1;//一上电让D5灭    
  	
    UartInit();//C51串口通信初始化	
    //每隔1s发送一次
	while(1)
    {
        Delay1000ms();
        sendString("nihao pc\r\n");  
        //怎么知道收到了数据,打开RI中断,有硬件置1(RI=1) 
        if(RI==1)
        {
           RI=0;
           cmd=SBUF;//从寄存器接收数据
           if(cmd=='o')
           {
              D5=0;
           }
           if(cmd=='c')
           {
              D5=1;
           }               
        }            
    }    
}

6. PC interrupts the LED through the serial port

#include "reg52.h"
#include "intrins.h"

sbit D5=P3^7;
sfr AUXR=0x8e;	
char cmd;

/*
void UartInit(void)		//[email protected]
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}
*/

void UartInit(void)
{
     AUXR =0x01;
     SCON =0x50; //配置串口工作方式1,REN使能不接收
     TMOD&=0x0F; //配置定时器工作模式
     TMOD|=0x20;
     TL1  =0xFD; //配置定时器初值
     TH1  =0xFD;
     TR1  =1;
     EA=1;//打开总中断
     ES=1;//打开串口中断    
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void sendByte(char data_msg)
{
   SBUF=data_msg;
   while(!TI);
   TI=0;    
}

void sendString(char *str)
{
    while(*str)
   {
        sendByte(*str);
        str++;
   }       
}

void main()
{  
    D5=1;//一上电让D5灭    
  	
    UartInit();//C51串口通信初始化	
    //每隔1s发送一次
	while(1)
    {
        Delay1000ms();
        sendString("nihao pc\r\n");  //心跳包;作用:有数据,说明单片机正常
    }    
}

void uart_handler()  interrupt 4
{
   if(RI)
   {
       RI=0;
       cmd=SBUF;//从串口寄存器SBUF接收数据
       if(cmd=='o')
       {
          D5=0;
       }
       if(cmd=='c')
       {
          D5=1;
       }       
   }    
   
   if(TI);
}

7. Send a string through the serial port to light up the LED

#include "reg52.h"
#include "intrins.h"
#include<string.h>

#define SIZE 12
sbit D5=P3^7;
sfr AUXR=0x8e;	
char cmd[SIZE];

/*
void UartInit(void)		//[email protected]
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}
*/

void UartInit(void)
{
     AUXR =0x01;
     SCON =0x50; //配置串口工作方式1,REN使能不接收
     TMOD&=0x0F; //配置定时器工作模式
     TMOD|=0x20;
     TL1  =0xFD; //配置定时器初值
     TH1  =0xFD;
     TR1  =1;
     EA=1;//打开总中断
     ES=1;//打开串口中断    
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void sendByte(char data_msg)
{
   SBUF=data_msg;
   while(!TI);
   TI=0;    
}

void sendString(char *str)
{
    while(*str)
   {
        sendByte(*str);
        str++;
   }       
}

void main()
{  
    D5=1;//一上电让D5灭    
  	
    UartInit();//C51串口通信初始化	
    //每隔1s发送一次
	while(1)
    {
        Delay1000ms();
        sendString("nihao pc\r\n");  //心跳包;作用:有数据,说明单片机正常
    }    
}

void uart_handler()  interrupt 4
{
   static int i=0; 
   if(RI)
   {
       RI=0;
       cmd[i]=SBUF;//从串口寄存器SBUF接收数据
       i++;
       if(i==SIZE)
       {
          i=0;
       }           
       if(strstr(cmd,"op"))
       {
          D5=0;
          i=0;
          memset(cmd,0,SIZE);           
       }
       if(strstr(cmd,"cl"))
       {
          D5=1;
          i=0;
          memset(cmd,0,SIZE);           
       }       
   }    
   
   if(TI);
}

Guess you like

Origin blog.csdn.net/qq_47944751/article/details/131929751