51单片机之串口通信

2019-09-26  本文已影响0人  David_Rao

串行通信原理
并行通信[多条数据线同时传输一条数据(1字节)]

串行通信[一条数据线同时传输一条数据(1字节)]

相互进行传输



串行通信又分为异步通信和同步通信

同步通信

数据(1字节)与数据(1字节)之间的传输时间间隔是相同的,每隔一个时间周期就发送一次,源源不断地发送

同步通信分为外同步和自同步

外同步,每一个时钟脉冲(波峰)传输一个byte 自同步,双方时钟相同

异步通信

数据(1字节)与数据(1字节)之间的传输时间间隔可以任意

由于异步通信的数据间传输时间间隔是任意的,所以要告诉传输设备,数据是从哪里开始的,哪里结束的。所以传输的数据的最前面要加上起始位,最后面要加上停止位



传输速率



串行接口的结构

//SBUF寄存器既可以用于存放要发送的数据,也可以用于存放要接收的数据
//接收数据,设需要把接收进来的数据放在变量a中
a = SBUF;  //把接收到的放在SBUF的数据用变量a记录
//发送数据,设需要发送变量a
SBUF = a;   //把a交给SBUF发送



51单片机串口相关的寄存器

IE寄存器

串行口控制寄存器SCON(可位寻址)


SM0、SM1专门用于设置工作模式,下面讨论 主要用到方式1 SMOD默认等于0 SMOD默认等于0,fosc是外部晶振频率,为11.0592MHz。T初是TH1的初值
//操作IE寄存器设置中断
//设置串口的工作方式
//配置允许接收位
//接收标志位和请求标志位软件清零
//用定时器1产生波特率
//定时器的配置,1打开定时器开关,2设置工作模式,3配置TH,TL初值

//串口初始化函数
void UARTInit()
{
    EA = 1;  //打开总中断
    ES = 1;  //打开串口中断
    SM0 = 0;  SM1 = 1;  //串口工作方式1,8位UART波特率可变
    REN = 1;  //串口允许接收
    //用定时器1产生波特率,控制每个传送数据中每个“位”的间隔
    TR1 = 1;  //启动定时器
    TMOD |= 0x20;  //定时器1工作模式2,8位自动重装;或运算符“|”可以与其它TMOD的值进行求和
    TH1 = 0xfd;  //重装数
    TL1 = 0xfd;  //253
}

以下是完整程序

#include <reg52.h>

#define uint unsigned int
#define uchar unsigned char

sbit DU = P2^6;  //数码管段选
sbit WE = P2^7;  //数码管位选
uchar num = 0;

 //数码管段选码表
uchar code SMGduan[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f} ;
//数码管位选码表
uchar code SMGwei[] = {0xfe, 0xfd, 0xfb};

void display(uchar i)
{
    static uchar wei;  //退出函数后变量得到保留
    /*******************************************************/
    P0 = 0xff;  //清除断码
    WE = 1;  //打开位选
    P0 = SMGwei[wei]; 
    WE = 0;  //锁住位选数据
    switch(wei)
    {
        case 0 : DU = 1; P0 = SMGduan[i / 100]; DU = 0; break;
        case 1 : DU = 1; P0 = SMGduan[i / 10 % 10]; DU = 0; break;
        case 2 : DU = 1; P0 = SMGduan[i % 10]; DU = 0; break;
    }
    wei++;
    if(wei == 3)
        wei = 0;
}
//定时器0初始化
void timer0Init()
{
    EA = 1;  //打开总中断
    ET0 = 1;  //允许T0中断
    TR0 = 1;  //启动定时器0
    TMOD |= 0x01;  //定时器0工作模式1,16位定时模式;或运算符“|”可以与其它TMOD的值进行求和
    TH0 = 0xed;
    TL0 = 0xff;  //5ms
}

//串口初始化函数
void UARTInit()
{
    EA = 1;  //打开总中断
    ES = 1;  //打开串口中断
    SM0 = 0;  SM1 = 1;  //串口工作方式1,8位UART波特率可变
    REN = 1;  //串口允许接收
    //用定时器1产生波特率,控制每个传送数据中每个“位”的间隔
    TR1 = 1;  //启动定时器
    TMOD |= 0x20;  //定时器1工作模式2,8位自动重装;或运算符“|”可以与其它TMOD的值进行求和
    TH1 = 0xfd;  //重装数
    TL1 = 0xfd;  //253
}

void main()
{
    timer0Init();  //定时器0初始化
    UARTInit();  //串口初始化
    while(1);
}

// 定时器0中断函数
void timer0() interrupt 1
{
    TH0 = 0xed;//重放初值
    TL0 = 0xff; 
    display(num);
}

//串口中断函数
void UART() interrupt 4
{
    uchar temp;
    if(RI)  //判断接收是否完成
    {
        num = SBUF;  //读SBUF,读出串口接收到的数据
        RI = 0;  //软件清零接收标志位
        temp = num;  
        SBUF = ++temp;  //写SBUF,向上位机发送+1后的数
    }
    if(TI)  //判断是否发送完成
    {
        TI = 0;  //软件清零发送完成标志位
    }
}
上一篇 下一篇

猜你喜欢

热点阅读