使用51单片机中的串口与外部进行数据传输

240 阅读4分钟

串口的作用

我们使用的单片机能力,需要与其他设备相互连接,传递数据,这样才能扩展单片机的使用场景,而单片机与其他设备传递数据就需要使用串口,串口是一种可以接收来自其他设备的数据字符,同时可以发送的数据流的器件。

串口的应用

在使用单片机的某个器件时,首先要通过原理图查看它有哪些寄存器组成 b2a9b862e79e8f5fcd1850bf64f2d042fb1306fac2574dad.png PCON为电源控制寄存器(不可位寻址) 最高位SMOD为波特率选择位,用于设置方式,当SMOD=0时各工作方式的波特率加倍 B6位SMOD0为帧错误检测有效位,可以用于改变寄存器SCON的B7位的功能

SCON为串行口控制寄存器(可位寻址) 最高位B7有SM0和FE两种状态,由PCON寄存器的SMOD0(B6)决定,当SMOD0位1时,该位含义为FE,用于检测帧错误;当SMOD0位0时,该位含义为SM0,和SM1(B6)一起指定串行通信的工作方式:SM0和SM1一起组合可以确定串行口的工作方式,通常只用00和01的工作方式,分别为同步移位串行方式和8位UART波特率可变,前者的波特率为SYSclk/12,后者为(2^SMOD / 32)*(定时器1的溢出率) B4为REN,为串行接收控制的使能位,当REN=1时才允许串行接收,REN=0时禁止接收 B0为RI,中断请求标识位,在方式0中,串行接收数据完毕后内部硬件就会自动置位RI=1,向主机请求中断,中断完毕后需由软件进行复位使RI=0

SBUF为数据缓存处理器,用于缓冲将要收发的数据,因此无需对其配置

在初始化配置PCON和SCON时一般模块化为

SCON=0x40;      //初始化配置SCON串行口控制寄存器
PCON |= 0x80;   //电源控制寄存器PCON,SMOD用于控制波特率是否加倍
                //串行口数据缓存寄存器SBUF无需配置

在使用串口进行数据传输时一定会进行中断操作,所以我们还需要对中断系统进行配置,而51单片机中,专门使用定时器1来对串口进行定时,所以我们需要设置好定时器1,根据系统频率,UART数据位数,定时器时钟,所需的对应的波特率,计算出所需配置的参数(烧录软件STC-ISP有计算器,输入对应参数可直接得到配置文件)

TMOD &= 0x0F;           //设置定时器模式
TMOD |= 0x20;           //设置定时器模式
TL1 = 0xF3;             //设置定时初始值
TH1 = 0xF3;             //设置定时重载值
ET1 = 0;                //禁止定时器中断
TR1 = 1;                //定时器1开始计时

综上,想实现使用串口向电脑发送数据,只需要

#include <REGX52.H>
#include "Delay.h"
​
void UART_Init()
{
    SCON=0x40;
    PCON |= 0x80;
    TMOD &= 0x0F;
    TMOD |= 0x20;
    TL1 = 0xF3;
    TH1 = 0xF3;
    ET1 = 0;
    TR1 = 1;
}
​
void UART_SendByte(unsigned char Byte)
{
    SBUF=Byte;//将Byte的值写入SBUF中,写入后定时器、波特率配置好了他就会自动发出
    while(TI==0);
    TI=0;
}
​
unsigned char Sec=0;
void main()
{
    UART_Init();                    //初始化串口
    while(1)
    {
        UART_SendByte(Sec++);       //使用串口传输函数传输数据
        Delay(1000);    //传输后需要延迟一会儿,最低延迟时间与波特率有关
    }
}

用电脑通过串口控制LED

电脑向串口发送数据的时候,一定需要配置中断,一旦串口检测到有数据输入,就会对CPU请求中断,而后进入UART_Routine(),令寄存器P2与单片机收到的SBUF中的数据相同,并且再次将收到的数据返回电脑

一旦检测到SCON中的RI位RI=1,代表数据接收完成,响应中断,在进行想要完成的操作后,手动复位令RI=0

#include <REGX52.H>
#include "Delay.h"
#include "UART.h"void main()
{
    UART_Init();
    while(1)
    {
        
    }
}
​
void UART_Routine() interrupt 4
{
    if(RI==1)
    {
        P2=SBUF;
        UART_SendByte(SBUF);
        RI=0;
    }
}