51单片机串口通信调试程序

请问这段程序是什么意思啊?这个S2CON是多少?S2CON&S2RI是按位与吗?S2CON&=~S2RI又是怎么算呀?

void Uart2() interrupt 8 using 1
{
//    S2RI=0;
    if (S2CON & S2RI)
    {
        S2CON &= ~S2RI;         //清除S2RI位
                num=S2BUF;
                if(num=='$'){P0=0XFE;}
                if(num=='&'){P0=0XFF;}
    }
        if (S2CON & S2TI)
    {
        S2CON &= ~S2TI;         //清除S2TI位
        busy = 0;               //清忙标志
    }
}

完整的程序是这样的

#include <STC15.H>
#include <intrins.H>

#define S2RI  0x01              //S2CON.0
#define S2TI  0x02              //S2CON.1
#define uchar unsigned char 
#define uint unsigned int    
    
uchar flag,num;
bit busy;
void delayms(int ms);
void allinit();
void keyscan();

void UartInit(void);
void SendData(unsigned char dat);
void SendString(char *s);

void main()
{
    allinit();
    UartInit();
    EA=1;
    ES=1;
    SendString("STC15 WIFI TEST\r\n");
    SendString("STC15 WIFI TEST\r\n");
    SendString("STC15 WIFI TEST\r\n");
    P07=0;
    while(1)
    {
        keyscan();
    }
}

//----------------------------
//UART2 中断服务程序
//-----------------------------
void Uart2() interrupt 8 using 1
{
//    S2RI=0;
    if (S2CON & S2RI)
    {
        S2CON &= ~S2RI;         //清除S2RI位
                num=S2BUF;
                if(num=='$'){P0=0XFE;}
                if(num=='&'){P0=0XFF;}
    }
        if (S2CON & S2TI)
    {
        S2CON &= ~S2TI;         //清除S2TI位
        busy = 0;               //清忙标志
    }
}

//----------------------------
//发送串口数据
//----------------------------
void SendData(unsigned char dat)
{
    while (busy);               //等待前面的数据发送完成
    ACC = dat;                  //获取校验位P (PSW.0)
    busy = 1;
    S2BUF = ACC;                //写数据到UART2数据寄存器
}

//----------------------------
//发送字符串
//----------------------------
void SendString(char *s)
{
    while (*s)                  //检测字符串结束标志
    {
        SendData(*s++);         //发送当前字符
    }
}

void UartInit(void)        //9600bps@11.0592MHz
{
    S2CON = 0x50;        //8位数据,可变波特率
    AUXR |= 0x04;        //定时器2时钟为Fosc,即1T
    T2L = 0xE0;        //设定定时初值
    T2H = 0xFE;        //设定定时初值
    AUXR |= 0x10;    //启动定时器2
    IE2 = 0x01;    //使能串口2中断
}

void keyscan()
{
    if(P32==0)
    {
        delayms(5);
        if(P32==0)
        {
            SendString("STC15 WIFI TEST\r\n");
        }
        while(!P32);
    }
 else if(P33==0)
    {
        delayms(5);
        if(P33==0)
        {
            SendString("$");
        }
        while(!P33);
    }
}

void delayms(int ms)
{
    int i,j;
    for(i=ms;i>0;i--)
        for(j=845;j>0;j--);
}

void allinit()
{
    P0M0=0X00;P0M1=0X00;
    P1M0=0X00;P1M1=0X00;
    P2M0=0X00;P2M1=0X00;
    P3M0=0X00;P3M1=0X00;
    P4M0=0X00;P4M1=0X00;
}

因为S2CON这寄存器不可以位寻址所以只能读出整个寄存器,然后做位运算。S2CON&S2RI是判断有没有RI,S2CON&=~S2RI是把RI位置0,这点注释也说了,你找一下S2RI的定义,然后结合寄存器手册就能看懂了。

1.是按位与;
2.先对S2RI取反,再用S2CON按位与。