专栏首页緣來來來51单片机采用中断进行串口通信

51单片机采用中断进行串口通信

51单片机采用中断方式的串口通信过程及程序分析:

所谓中断方式,就是串口收/发标志位出发中断后,在中断中执行既定操作,可通过函数调用来实现。

接收数据时: 等待中断->然后在中断中接收数据

发送数据时: 发送数据->等待中断->然后在中断中发送数据

具体步骤如下:

  • 确定T1的工作方式(编程TMOD寄存器);
  • 计算T1的初值,装载TH1、TL1;
  • 启动T1(编程TCON中的TR1位);
  • 确定串行口控制(编程SCON寄存器);
  • 串行口在中断方式工作时,要进行中断设置(编程IE、IP寄存器)。

注:SCON 是一个特殊功能寄存器,用以设定串行口的工作方式、接收/发送控制以及设置状态标志:

有关波特率的计算方法:

在串行通信中,收发双方对发送或接收数据的速率要有约定。通过软件可对单片机串行口编程为四种工作方式,其中方式0和方式2的波特率是固定的,而方式1和方式3的波特率是可变的,由定时器T1的溢出率来决定。

串行口的四种工作方式对应三种波特率。由于输入的移位时钟的来源不同,所以,各种方式的波特率计算公式也不相同。

  • 方式0的波特率 =  fosc/12
  • 方式2的波特率 =(2SMOD/64)· fosc
  • 方式1的波特率 =(2SMOD/32)·(T1溢出率)
  • 方式3的波特率 =(2SMOD/32)·(T1溢出率)

当T1作为波特率发生器时,最典型的用法是使T1工作在自动再装入的8位定时器方式(即方式2,且TCON的TR1=1,以启动定时器)。这时溢出率取决于TH1中的计数值。

  • T1 溢出率 = fosc /{12×[256 -(TH1)]}

注:PCON中只有一位SMOD与串行口工作有关, SMOD(PCON.7)  波特率倍增位。在串行口方式1、方式2、方式3时,波特率与SMOD有关,当SMOD=1时,波特率提高一倍。复位时,SMOD=0。     在单片机的应用中,常用的晶振频率为:12MHz和11.0592MHz。所以,选用的波特率也相对固定。常用的串行口波特率以及各参数的关系如表所示。

80C51串行口的工作方式1:

方式1是10位数据的异步通信口。TXD为数据发送引脚,RXD为数据接收引脚,传送一帧数据的格式如图所示。其中1位起始位,8位数据位,1位停止位。

  • (1) 方式1输出
  • (2) 方式1输入

  用软件置REN为1时,接收器以所选择波特率的16倍速率采样RXD引脚电平,检测到RXD引脚输入电平发生负跳变时,则说明起始位有效,将其移入输入移位寄存器,并开始接收这一帧信息的其余位。接收过程中,数据从输入移位寄存器右边移入,起始位移至输入移位寄存器最左边时,控制电路进行最后一次移位。当RI=0,且SM2=0(或接收到的停止位为1)时,将接收到的9位数据的前8位数据装入接收SBUF,第9位(停止位)进入RB8,并置RI=1,向CPU请求中断。

定时/计数器的结构与原理

定时/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器组成。TMOD是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。

加1计数器输入的计数脉冲有两个来源,一个是由系统的时钟振荡器输出脉冲经12分频后送来;一个是T0或T1引脚输入的外部脉冲源。每来一个脉冲计数器加1,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使TCON中TF0或TF1置1,向CPU发出中断请求(定时/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。

可见,由溢出时计数器的值减去计数初值才是加1计数器的计数值。

设置为定时器模式时,加1计数器是对内部机器周期计数(1个机器周期等于12个振荡周期,振荡周期也叫时钟周期,时钟周期即晶振的单位时间发出的脉冲数,如12MHZ=12×10的6次方,即每秒发出12000000个脉冲信号,那么发出一个脉冲的时间就是时钟周期,即1/12微秒;如11.0592MHZ=11.0592×10的6次方,即每秒发出11059200个脉冲信号,那么发出一个脉冲的时间就是时钟周期,即1/11.0592微秒)。计数值N乘以机器周期Tcy就是定时时间t 。

定时/计数器的控制

80C51单片机定时/计数器的工作由两个特殊功能寄存器控制。TMOD用于设置其工作方式;TCON用于控制其启动和中断申请。

  • 工作方式寄存器TMOD 工作方式寄存器TMOD用于设置定时/计数器的工作方式,低四位用于T0,高四位用于T1。其格式如下: M1M0:工作方式设置位。定时/计数器有四种工作方式,由M1M0进行设置:

控制寄存器TCON

TCON的高4位用于控制定时/计数器的启动和中断申请。其格式如下:

  • TF1(TCON.7):T1溢出中断请求标志位。T1计数溢出时由硬件自动置TF1为1。CPU响应中断后TF1由硬件自动清0。T1工作时,CPU可随时查询TF1的状态。所以,TF1可用作查询测试的标志。TF1也可以用软件置1或清0,同硬件置1或清0的效果一样。
  • TR1(TCON.6):T1运行控制位。TR1置1时,T1开始工作;TR1置0时,T1停止工作。TR1由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。
  • TF0(TCON.5):T0溢出中断请求标志位,其功能与TF1类同。
  • TR0(TCON.4):T0运行控制位,其功能与TR1类同。

定时器1的工作方式2

方式2为自动重装初值的8位计数方式。

计数个数与计数初值的关系为:X = 2^8 - N

其中:X为要装的初值 N为要定时/记数的次数。

注:工作方式2特别适合于用作较精确的脉冲信号发生器。所以在进行串口通信时一般选用定时器1工作在方式2 这种经典模式。

  程序:

/*51单片机采用中断方式的串口通信程序分析:
接收数据时 等待中断->然后在中断中接收数据
发送数据时 发送数据->等待中断->然后在中断中发送数据
具体步骤如下:
确定T1的工作方式(编程TMOD寄存器);
计算T1的初值,装载TH1、TL1;
启动T1(编程TCON中的TR1位);
确定串行口控制(编程SCON寄存器);
串行口在中断方式工作时,要进行中断设置(编程IE、IP寄存器)。
*/

#include <reg52.h>
#define uchar unsigned char

uchar Temp,RIflag,TIflag;

//串口初始化函数

void serialportinit() {

    TMOD=0x20;//设置定时器1为工作方式2 8位自动重装载 作用是产生波特率
    TH1=0xfd;//设置波特率位9600bps
    TL1=0xfd;
    TR1=1;//开启定时器1

    //设置串口工作在方式1
    //方式1: 8位异步收发 波特率可变(由定时器控制) 收发一帧的数据为10位 一个起始位(0)8个数据位 1个停止位(1)
    //先发送或接收最低位
    SCON=0x50;//等价于 SM0=0; SM1=1; REN=1;

    //SM0=0;
    //SM1=1;
    //REN=1;//允许串行接收位 允许串行口接收数据
    PCON=0x00;//SMOD=0 波特率不加倍

    EA=1;//开总中断
    ES=1;//开串口中断  注意:如果使用查询方式进行串口通信时,要把串口中断ES关闭、
}



//定义数据发送函数
void sentTemp() {

    SBUF=Temp;//把Temp接收的数据再发送到发送缓冲器SBUF中

    //注意:51单片机内部有两个物理上独立的接收、发送缓冲器SBUF(属于特殊功能寄存器) 两个缓冲器共用一个特殊功能寄存器 字节地址(99H?
    while(!TI);//等待从机向主机发送数据完成
    TI=0;//若发送完成 把发送中断标志位软件清0 因为TI必须由软件清零
}

void main() {
 serialportinit();

 while(1) {

    if(RIflag==1) {
            ES=0;//关串口中断
            RIflag=0;//接收标志位清0
            sentTemp();//调用数据发送函数
            ES=1;//开串口中断
        }
    }
}

//串口中断服务函数
void serialportint() interrupt 4 { //串口中断函数

  if(RI) {
        RI=0;//接收中断标志位RI必须由软件清0
        Temp=SBUF;//把接收缓冲器中收到的数据赋值给led
        P1=Temp;//通过开发板监测是否接收到主机发送的数据
        RIflag=1;//接收标志位置1 表示从机接收收据完成
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 申请Let's Encrypt通配符证书

    Let's Encrypt支持通配符证书了,也就是说你只需要为你的网站申请*.example.com这样一个证书,所有的子域名都可以支持,下面介绍下申请方法:

    緣來
  • Markdown的安装以及简单使用教程

    st= start: Start io= inputoutput: verification op= operation: Your Operation ...

    緣來
  • Python爬虫 --- 2.2 Scrapy 选择器的介绍

    Scrapy提取数据有自己的一套机制,被称作选择器(selectors),通过特定的Xpath或者CSS表达式来选择HTML文件的某个部分 Xpath是专门在X...

    緣來
  • hadoop使用(六)

    第1章 引言 1.1 编写目的 介绍pig,一个不得不说的hadoop的扩展。 1.2 什么是pig Pig是一个基于Hadoop的大规模数据分析平台,它提供的...

    cloudskyme
  • 负载均衡策略

    1. HTTP重定向 当用户发来请求的时候,Web服务器通过修改HTTP响应头中的Location标记来返回一个新的url,然后浏览器再继续请求这个新url,...

    dys
  • Android Volley完全解析(二),使用Volley加载网络图片

    在上一篇文章中,我们了解了Volley到底是什么,以及它的基本用法。本篇文章中我们即将学习关于Volley更加高级的用法,如何你还没有看过我的上一篇文章的话,建...

    用户1158055
  • 大型网站的可伸缩性架构如何设计?

    将不同功能分离部署可以实现一定程度的伸缩性,但是随着网站的访问量逐步增加,即使分离到最小粒度的独立部署,单一的服务器也不能满足业务规模的要求。因此必须使用服务器...

    李红
  • 亿级Web系统负载均衡几种实现方式

    负载均衡(Load Balance)是集群技术(Cluster)的一种应用技术。负载均衡可以将工作任务分摊到多个处理单元,从而提高并发处理能力。目前最常见的负载...

    黄泽杰
  • 如何正确地做误差分析,NLP研究人员们需要学习一下

    尝试分析机器学习模型在什么时候、以什么方式、由于什么原因失效,我们把这称为「误差分析(error analysis)」。对科研人员来说,他们需要通过误差分析选择...

    AI科技评论
  • 字节数组和short,int,float,double等类型的相互转换

    在进行Modbus协议通信和网络编程时,有时需要将从串口或者网络中接收的数据从字节数组转换成对应的int,float,double等数据,有时还要考虑大小端字节...

    ccf19881030

扫码关注云+社区

领取腾讯云代金券