51单片机第七讲(串口)

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

一.相关概念
计算机通信是指计算机与外部设备或计算机与计算机之间的信息交换。
通信有并行通信和串行通信两种方式。在多微机系统以及现代测控系统中信息的交换多采用串行通信方式。

二.并行通信和串行通信
并行通信通常是将数据字节的各位用多条数据线同时进行传送 。
并行通信特点:控制简单、传输速度快;但传输线较多,长距离传送时成本高且接收方的各位同时接收存在困难。
这里写图片描述

串行通信是将数据字节分成一位一位的形式在一条传输线上逐个地传送。
串行通信的特点:传输线少,长距离传送时成本低,且可以利用电话网等现成的设备,但数据的传送控制比并行通信复杂。
这里写图片描述

三.单工,半双工和全双工通信
1、单工
单工是指数据传输仅能沿一个方向,不能实现反向传输。
2、半双工
半双工是指数据传输可以沿两个方向,但需要分时进行。
3、全双工
全双工是指数据可以同时进行双向传输。

四.异步通信和同步通信
1.异步通信
异步通信是指通信的发送与接收设备使用各自的时钟控制数据的发送和接收过程。为使双方的收发协调,要求发送和接收设备的时钟尽可能一致。
异步通信是以字符(构成的帧)为单位进行传输,字符与字符之间的间隙(时间间隔)是任意的,但每个字符中的各位是以固定的时间传送的,即字符之间不一定有“位间隔”的整数倍的关系,但同一字符内的各位之间的距离均为“位间隔”的整数倍。
这里写图片描述
异步通信的特点:不要求收发双方时钟的严格一致,实现容易,设备开销较小,但每个字符要附加2~3位用于起止位,各帧之间还有间隔,因此传输效率不高。

五.串行口控制寄存器
这里写图片描述
①SM0和SM1(SCON.7,SCON.6)——串行口工作方式选择位。两个选择位对应4种通信方式,如表7-1所示。其中,fosc是振荡频率。
这里写图片描述
一般选择方式1
③REN(SCON.4)——允许接收控制位。由软件置1或清0,只有当REN=1时才允许接收,相当于串行接收的开关;若REN=0,则禁止接收。在串行通信接收控制过程中,如果满足RI=0和REN=1(允许接收)的条件,就允许接收,一帧数据就装载入接收SBUF中。

⑥TI(SCON.1)——发送中断标志。在一帧数据发送完时被置位。在方式0串行发送第8位结束或其他方式串行发送到停止位的开始时由硬件置位,可用软件查询。它同时也申请中断,TI置位意味着向CPU提供“发送缓冲器SBUF已空”的信息,CPU可以准备发送下一帧数据。串行口发送中断被响应后,TI不会自动清0,必须由软件清0。

⑦RI(SCON.0)——接收中断标志。在节收到一帧有效数据后由硬件置位。在方式0中,第8位数据发送结束时,由硬件置位;在其他三种方式中,当接收到停止位中间时由硬件置位。RI=1,申请中断,表示一帧数据接收结束,并已装入接收SBUF中,要求CPU取走数据。CPU响应中断,取走数据。RI也必须由软件清0,清除中断申请,并准备接收下一帧数据。

六.波特率
在串行通信中,收发双方对发送或接收的数据速率有一定的约定,通过软件对89C51串行口编程可约定四种工作方式。其中,方式0和方式2的波特率是固定的;而方式1和方式3的波特率是可变的,由定时器T1的溢出率来决定。
这里写图片描述
SMOD(PCON.7)——波特率倍增位。
在串行口方式1、方式2和方式3时,波特率和SMOD成正比,亦即当SMOD=1时,波特率提高一倍。
复位时,SMOD=0。一般情况下SMOD为0。

串口的初始化

void bsp_InitSerial(void)
{
    //1.SCON
    SCON = 0x50;     //一般情况下选择方式1
    //2.波特率
    TMOD |= 0x20;   //选择定时器1的方式2
    TH1 = 0xfd;     //SMOD=0时的初值
    TL1 = 0xfd;     //方式2自动重装初值
    //3.开中断
    EA = 1;         //开总中断
    ES = 1;         //开串口中断
    TR1 = 1;        //开定时器1中断
}
void bsp_SerialSendData(unsigned char dat)
{
    SBUF = dat;
    while(!TI);     //等待发送完成
    TI = 0;
}

void bsp_SerialSendString(unsigned char *s)
{
    while(*s)
    {
         bsp_SerialSendData(*s);
         s++;
    }       
}

void ISR_Serial(void) interrupt 4
{
    if(RI)  //接收数据
    {
        rev = SBUF;
        RI = 0;   //接收完成
    }   
}

发送不定长数据

void ISR_Serial(void) interrupt 4  //每发一个字节进入串口中断一次,比如hujunhua这一帧数据是8个字节,
//每发一个就进入串口中断,直到最后发送完,过了5ms之后没有字节发送了认为这一帧数据发送完成
{
    if(RI)  //接收数据
    {
        TL0 = T0MS;  //装初值,低8位
        TH0 = T0MS>>8;  //高8位
        rev[index++] = SBUF;
        RI = 0;   //接收完成
        TR0 = 1;
    }   
}

void Timer0_Init(void)
{
    TMOD |= 0x01;//设置定时器为工作方式1  C/T位为1的时候是计数器模式,为0的时候是定时器模式,前四位是定时器1,后四位是定时器0
    TL0 = T0MS;  //装初值,低8位
    TH0 = T0MS>>8;  //高8位
    ET0 = 1;    //开定时器的中断
    TR0 = 1;    //开定时器
    EA = 1;     //开总中断
}

void Timer0(void) interrupt 1        //当过了5ms之后认为一帧数据已经发送完了
{
    TL0 = T0MS;
    TH0 = T0MS>>8;
    rev[index] = '\0';
    index = 0;
    TR0 = 0;
    revok = 1;
} 

猜你喜欢

转载自blog.csdn.net/hu_junhua/article/details/79270742
今日推荐