C51单片机之串口

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/plm199513100/article/details/79410823

/*
名称:C51单片机之串口
说明:在计算机之间进行通讯的时候,有两种方式,一个是串行通信,一个是并行通信。对于前者适合长距离通信、有一定的纠错能力。对于后者,适合短距离通信,速度较快。

对于C51单片机来说,其内部集成有一个功能很强的全双工通信口。设有两个相互独立的接受、发送缓冲器,可以同时发送数据和接收数据。发送缓冲器只能发送不能读出。接收缓冲器只能接收不能发送,而且两个缓冲器共用一个物理地址(0X99)。在编程时由编译器进行区分。还有,C51单片机的串口有4种工作方式,其中两种波特率时刻变的,另外两种是不可变的。

对于具体的使用来说,首先也是需要进行一系列初始化设置(包括工作方式设置、波特率设置等)。然后可以通过轮询或者中断的方式,检查TI或者RI是否被硬件置1来判断数据是否发送完毕或者有新的数据产生。

还有一点需要说明的是,在串口工作的4中方式中,有两种波特率可变的方式,其波特率设置是根据定时器的溢出来设置的。这么说,从某种程度上说,定时器还可以为串口提供时钟信息。

*/

实验主要代码如下:

int sen_flag = 0,rec_flag = 0;

//串口初始化
void UartInit()
{
    //串行口波特率设置:模特率9600(定时器1)
        TMOD = 0x20;        //定时器1选择工作方式1(8位定时,自动重载)    
        TL1 = 0xFD;         //设置初始值
        TH1 = 0xFD;

        //串口工作方式设置
        SCON = 0x50;        //  串行口工作方式1,允许接收
        PCON = 0;

        TR1 = 1;        //启动定时器
        ES = 1;         //开串行中断
        EA = 1;         //开总中断



}



//发送一个字符
void SendChar(char c)
{
    SBUF = c;
    sen_flag = 1;               //设置标志位
    while(1 == sen_flag )   ;           //等待串口发送完毕
    //while(0 == TI) ;                  
}


//发送16进制数据(0-FF)
void SendNum(unsigned char num)
{
    unsigned char temp_fir = num&0x0F;
    unsigned char temp_sec = num>>4;

    if(temp_fir > 9)
        temp_fir = temp_fir-10+'A';
    else
        temp_fir = temp_fir+'0';

    if(temp_sec > 9)
        temp_sec = temp_sec-10+'A';
    else
        temp_sec = temp_sec+'0';



    SendChar(temp_sec);
    SendChar(temp_fir);


}

//发送一个字符串
void SendStr(char * str)
{
    while((*str) != '\0')
    {
        SendChar(*str);
        str++;
    }
}


//接收一个字节
char RecChar()
{

    while(0 == rec_flag )   ;       //等待数据

    rec_flag = 0;           //取消接收标志位
    return SBUF;
}

串口中断服务函数如下:

//引进外部变量
extern rec_flag;
extern sen_flag;

void Uart(void) interrupt 4
{

    if(1 == TI)         //发送中断
    {
        TI = 0;     //发送完一个数据

        sen_flag = 0;       //取消标志位
    }

    if(1 == RI)         //接收中断
    {
        RI = 0;                     //清除中断
        rec_flag = 1;           //设置接收标志位

    }


}



猜你喜欢

转载自blog.csdn.net/plm199513100/article/details/79410823