精华内容
下载资源
问答
  • 2019-10-05 15:35:57

    中断源        中断入口地址

    外部中断0       0003H

    定时器/计数器T0   000BH

    外部中断1       0013H

    定时器/计数器T1   001BH

    串行口中断        0023H

    转载于:https://www.cnblogs.com/lzh-Linux/p/4008315.html

    更多相关内容
  • 中断服务程序举例这里先举一个完整的自己能上机练习的中断服务程序例子。在第六章中介绍完可编程计数器/定时器8253后再举一例(在Pc系列机中加入一个用户中断源——可编程定时中断),说明在PC系列机中加入一个用户...

    编中断服务程序举例

    这里先举一个完整的自己能上机练习的中断服务程序例子。在第六章中介绍完可编程计数器/定时器8253后再举一例(在Pc系列机中加入一个用户中断源——可编程定时中断),说明在PC系列机中加入一个用户中断源应做的工作。

    例 利用1CH软中断作定时处理——每次进入1CH中断时显示一个“*”,18次后显示一个字符串“second”(秒)。

    关于1CH软中断,前面已经介绍,是留给用户进行定时处理的“软接口”。在软时钟中断(中断类型号为08H)处理过程中,要调用一次INT 1CH软中断。系统本身(指DOS)在1cH中断服务程序中仅安排了一条中断返回指令,即什么也没有做,直接返回。所以,用户可重新编写1CH的中断服务程序,在其中加入自己所需的定时处理。下面是用Turbo C编写的1CH中断服务程序以及对1CH中断进行设置的主程序的清单。编译、连接,形成可执行文件后便可运行(DOS环境下)。

    #include

    union REGS in,out;

    int U=0;

    char fg=0;

    void interrupt(*old intlc)(void); /*定义old_intlc为中断函数指针*/

    void interrupt new_intle() /*自编的1CH中断服务程序*/

    {in.h.ah=OxOe; /*调用BIOS功能显示字符'*'*/

    in.h.al='*':

    in.h.bh=0;

    int86(0x10,&in,&out);

    n++;if(n>=18){n=0;fg=1;}

    }

    main()

    {old_intle=getvect(Oxlc); /*取原ICH中断向量*/

    setveet(0xlc,new_intlc); /*置新的1CH中断向量*/

    for(;;)

    {if(fg==1){pfinff("second");fg=0;}

    if(bioskey(1)!=0) /*按任一键,恢复原1CH中断向量,程序结束*/

    {setvect(0xlc,old_intle);exit(O);{

    }

    程序中已作了一些注解,但还需要说明几点:

    ①程序的第二行定义in,out为union(联合)REGS类型的变量,一个用作C语言BIOS功能调用(int86)的输入变量,另一个作输出变量。联合REGS在头文件dos.h中作了定义(所以要引用DOS.H),定义如下:

    struct WORDREGS

    {unsigned int ax,bx,cx,dx,si,di,cflag,flags;}

    struct BYTEREGS

    {unsigned char al,ah,bl,bh,cl,ch,dl,dh;

    union REGS

    {struct WORDREGS x;

    struct BYTEREGS h;

    }

    可见,REGS是结构WORDREGS和结构BYTEREGS的联合。这样,在c语言中可直接对寄存器进行操作。例如,通过in.x.ax可引用16位寄存器Ax,通过in.h.ah可引用8位寄存器AH。

    ②在turbo c中,中断服务程序是用类型为interrupt的函数表示的,函数名即为中断服务程序入口地址。所以在Turbo c中编写中断服务程序是相当方便的。

    ③在上述程序清单中没有见到保护现场和恢复现场,实际上这是由 Turbo C编译程序自动安排的(从编译的目标代码中可看到保护现场和恢复现场,且现场考虑得较全)。

    ④自编的中断服务程序开始的4行为调用BIOS功能显示字符“*”,这相当于下面的汇编语言程序段:

    MOV AH,OEH

    MOV AL.'*'

    MOV BH,O

    INT 10H ;在当前光标处显示一个字符

    ⑤软中断服务结束不需要发中断结束命令。中断结束命令只有外部可屏蔽硬中断才需要。

    这个是 你需要的么?

    展开全文
  • 串行口中断 4.1串行口中断通信 代码示范 4.2串行口中断通信分析 4.2.1 80C51串行口的结构 4.2.2 使用到的新寄存器 4.2.3 波特率的设置 4.3串口如何使用 5.参考资料 1.中断系统的概念 1.1中断的概念 CPU在处理某一...

    1.中断系统的概念

    1.1中断的概念

    CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理(中断发生);

    CPU暂时中断当前的工作,转去处理事件B(中断响应中断服务);

    待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A(中断返回),这一过程称为中断

    图片来自普中科技

    1.2中断系统的概念

    引起CPU中断的根源,称为中断源

    中断源向CPU提出的中断请求。CPU暂时中断原来的事务A,转去处理事件B。对事件B处理完毕后,再回到原来被中断的地方(即断点),称为中断返回。实现上述中断功能的部件称为中断系统

    1.3中断系统的优点

    • 解决了快速主机与慢速I/O设备的数据传送问题
    • 分时操作。CPU可以分时为多个I/O设备服务,提高了计算机的利用率;
    • 实时响应。CPU能够及时处理应用系统的随机事件,系统的实时性大大增强;
    • 可靠性高。CPU具有处理设备故障及掉电等突发性事件能力,从而使系统可靠性提高。

    1.4我们要说的三种中断源

    89C51/52的中断系统有5个中断源 ,2个优先级,可实现二级中断嵌套 。

    分别是外部中断0、计数/定时器中断0、外部中断1、计数/定时器中断1、串行通信中断。

    我们以外部中断0、计数/定时器中断0和串口通信中断来说说。

    下面这张图很关键,无论是那个中断都要走这个流程
    在这里插入图片描述

    TCON 定时/计数器控制寄存器
    在这里插入图片描述

    • IT0(TCON.0),外部中断0触发方式控制位
      当IT0=0时,为电平触发方式。
      当IT0=1时,为边沿触发方式(下降沿有效)。

    • IE0(TCON.1),外部中断0中断请求标志位

    • IT1(TCON.2),外部中断1触发方式控制位

    • IE1(TCON.3),外部中断1中断请求标志位

    • TF0(TCON.5),定时/计数器T0溢出中断请求标志位

    • TF1(TCON.7),定时/计数器T1溢出中断请求标志位

    IE 中断允许控制寄存器,CPU对 中断系统 所有中断以及某个中断源的开放和屏蔽是由中断允许寄存器IE控制的。
    在这里插入图片描述

    • EX0(IE.0),外部中断0允许位;
    • ET0(IE.1),定时/计数器T0中断允许位;
    • EX1(IE.2),外部中断0允许位;
    • ET1(IE.3),定时/计数器T1中断允许位;
    • ES(IE.4),串行口中断允许位;
    • EA (IE.7), CPU中断允许(总允许)位。

    IP 中断优先级控制寄存器
    这个我们一般不改,用缺省值,
    外部中断0 > 计数/定时器中断0 > 外部中断1 > 计数/定时器中断1 > 串行通信中断
    为什么是这样的排序呢?因为在单片机的ROM他们的入口地址也是按照这个顺序排序的。
    在这里插入图片描述

    要记住的是中断号,这在后面很重要
    在这里插入图片描述
    所以如果要有一个中断产生,要符合这样的顺序,以下三条同时满足时,CPU才有可能响应中断。

    在这里插入图片描述

    51单片机的中断优先级有三条原则

    1. CPU同时接收到几个中断时,首先响应优先级别最高的中断请求。
    2. 正在进行的中断过程不能被新的同级或低优先级的中断请求所中断
    3. 正在进行的低优先级中断服务,能被高优先级中断请求所中断

    为了实现上述后两条原则,中断系统内部设有两个用户不能寻址的优先级状态触发器。其中一个置1,表示正在响应高优先级的中断,它将阻断后来所有的中断请求;另一个置1,表示正在响应低优先级中断,它将阻断后来所有的低优先级中断请求。

    2.外部中断

    2.1 外部中断0 代码示范

    /* 用外部中断0来控制led灯闪烁 */
    #include<reg51.h>
    
    typedef unsigned char u8;
    typedef unsigned int u16;
    
    sbit led = P2^0;
    sbit K3 = P3^2;
    
    void delay(u16 i)
    {
    	while(i--);
    }
    
    void Int0Init() //初始化函数,你也可以写在主函数里面
    {
    	IT0 = 1; //TCON寄存器中,IT0是外部中断0 的触发方式控制位,ITO = 1,下降沿有效触发
    	EX0 = 1; //IE寄存器中,外部中断0允许位置1
    	EA = 1;  //IE寄存器中,CPU中断允许总开关
    }
    
    void main()
    {
    	Int0Init();//初始化函数
    	while(1); //在这里等待被外部中断0打断
    }
    
    void Int0() interrupt 0   //外部中断0的中断函数,函数名可以定义,interrupt 后面的中断号不能出错
    {
    	delay(1000);//按键消抖
    	if(K3==0)// k3被按下
    	{
    		led = ~led;
    	} 
    }
    

    2.2 外部中断 分析

    在这里插入图片描述
    可以看到,外部中断是非常符合上面这个中断流程的

    打个比方,我要在床上吹风扇,我自己的电线不够长,我要用我室友的插排。首先我先要和室友请求,室友同意我就插上去了,最后需要室友把总开关打开,我才能吹到风扇。

    3.计数/定时器中断

    3.1 计数/定时器中断0 代码示范

    #include<reg51.h>
    
    typedef unsigned char u8;
    typedef unsigned int u16;
    
    sbit led = P2^0;
    static u16 i;
    
    void Time0Init() //初始化函数,你也可以写在主函数里面
    {
    	TMOD|=0x01; //工作方式寄存器TMOD 
    	TH0 = 0xFC;  //给寄存器赋值 
    	TL0 = 0x66;
    	TR0 = 1;    //中断请求标志,置位1,启动定时/计数器工作 (控制寄存器TCON) 
    	ET0 = 1;    //计数器中断0允许控制位置1(中断允许寄存器IE) 
    	EA = 1;		//IE寄存器中,CPU中断允许总开关EA置1.
    	
    } 
    
    void main()
    {
    	Time0Init(); //初始化函数
    	while(1)
    	{
    		if(i == 1000)//每1000ms led状态翻转一次
    		{
    			i = 0;
    			led = ~led;
    		}
    	}
    	
    }
    
    void Time0() interrupt 1
    {
    
    	TH0 = 0xFC; //给寄存器赋值
    	TL0 = 0x66;
    	i++;  //每次加1,一次是 1ms
    }
    

    3.2 计数/定时器 分析

    其实根据我们上面的分析,我们只要知道下面这段初始化代码的含义就可以了

    TMOD|=0x01; //工作方式寄存器TMOD 
    TH0 = 0xFC;  //给寄存器赋值 
    TL0 = 0x66;
    

    在这里插入图片描述

    3.2.1 计数/定时器的概念

    定时器/计数器和单片机的CPU是相互独立的。定时器/计数器工作的过程是自动完成的,不需要CPU的参与。

    51单片机中的定时器/计数器是根据机器内部的时钟或者是外部的脉冲信号对寄存器中的数据加1。

    有了定时器/计数器之后,可以增加单片机的效率,一些简单的重复加1的工作可以交给定时器/计数器处理。CPU转而处理一些复杂的事情。同时可以实现精确定时作用。

    3.2.2 计数/定时器的工作原理

    定时/计数器实质上是一个加1计数器。它随着计数器的输入脉冲进行自加1,也就是每来一个脉冲,计数器就自动加1,,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使相应的中断标志位置1,向CPU发出中断请求(定时/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。

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

    这个原理决定了我们给计数/定时器的16位寄存器赋值的问题。

    3.2.3 计数/定时器的结构

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

    在这里插入图片描述

    TMOD 定时/计数器工作方式寄存器, 低四位用于T0,高四位用于T1.
    在这里插入图片描述
    GATE是门控位, 通常我们让GATE等于0,这样方便一些。

    • GATE=0时,用于控制定时器的启动是否受外部中断源信号的影响。只要用软件使TCON中的TR0或TR1为1,就可以启动定时/计数器工作;

    • GATA=1时,要用软件使TR0或TR1为1,同时外部中断引脚INT0/1也为高电平时,才能启动定时/计数器工作。即此时定时器的启动条件,加上了INT0/1引脚为高电平这一条件。

      C/T :定时/计数模式选择位。C/T =0为定时模式;C/T =1为计数模式。
      M1M0:工作方式设置位。定时/计数器有四种工作方式。
      在这里插入图片描述

    TIP:主要需要掌握方式1和方式2

    • 方式1一般是我们定时/计数器中断常用的。
    • 方式2一般是我们在串口通信时使用,用来计算频率。

    TCON 定时/计数器控制寄存器
    TCON的低4位用于控制外部中断,已在前面介绍。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
    方式1
    方式1的计数位数是16位,由TL0作为低8位,TH0作为高8位,组成了16位加1计数器 。
    TL0的8位溢出时向TH0进位,TH0溢出时,置位TCON中的TF0标志,向CPU发出中断请求。

    在这里插入图片描述

    在这里插入图片描述
    方式2
    方式2为自动重装初值的8位计数方式。
    计数个数与计数初值的关系为:X=2^8-N
    工作方式2特别适合于用作较精确的脉冲信号发生器。

    3.2.4 计数/定时器初值的设置

    51单片机内部时钟频率是外部时钟的12分频。也就是说当外部晶振的频率输入到单片机里面的时候要进行12分频。比如说你用的是12MHZ的晶振,那么单片机内部的时钟频率就是12/12MHZ,当你使用12MHZ的外部晶振的时候。

    机器周期=1/1M=1us。而我们定时1ms的初值是多少呢,1ms/1us=1000

    也就是要计数1000个数,初值=65535-1000+1(因为实际上计数器计数到66636才溢出)=64536=FC18H

    我们一般使用定时器工具,比较轻松就可以设置初值了。(需要这个工具的朋友可以在评论区留下邮箱)

    在这里插入图片描述

    3.3 小练笔

    用 定时计数器中断 和 动态八段数码管 做一个两位秒表:https://blog.csdn.net/m0_50679156/article/details/120097808

    4.串行口中断

    4.1串行口中断通信 代码示范

    /*pc连接51单片机,用串口助手发送一个数字会加1返回*/
    #include<reg52.h>
    
    typedef unsigned char u8;
    typedef unsigned int u16;
    
    void UstartInit()//串口初始化设置 
    {
    	TMOD = 0x20; //确定T1的工作方式(设置GATE,C/T非,M1M0 = 10 方式2 ,高四位用于T1) 
    	TH1 = 0xF4;  //高8位 
    	TL1 = 0xF4;  //低8位 
    	PCON = 0x80; //PCON中只有一位SMOD(最高位)与串行口工作有关 ,SMOD为1是波特率提高一倍 
    	TR1 = 1;     // 启动定时/计数器T1 定时或计数 
    	SCON = 0x50; // 0101 0000 设置串行口工作方式,方式1(10位异步收发器(8位数据)) 
    	ES = 1;     // 串行口中断允许 (IE寄存器)
    	EA = 1;     // CPU 中断总允许位 (IE寄存器)
    }
    
    void main()
    {
    	UstartInit();
    	while(1);
    }
    
    void startInit() interrupt 4
    {
    	u8 ReceiveData;
    	ReceiveData = SBUF;
    	RI = 0; //准备下次接受 
    	SBUF = ReceiveData + 1;
    	while(!TI);
    	TI = 0; //准备下次发送 
    } 
    

    在这里插入图片描述

    4.2串行口中断通信分析

    对于串口通信不是我们这篇博客分析的重点,主要说一下串行口中断

    4.2.1 80C51串行口的结构

    在这里插入图片描述

    有两个物理上独立的接收、发送缓冲器SBUF,它们占用同一地址99H
    这个概念很重要,SBUF是像是李信,光信和暗信是一个英雄,但是有不同的技能和外观。

    下面代码中的SBUF,一个是光信,一个是暗信,你懂了么?会心一笑的请点赞。

    void startInit() interrupt 4
    {
    	u8 ReceiveData;
    	ReceiveData = SBUF;
    	RI = 0; //准备下次接受 
    	SBUF = ReceiveData + 1;
    	while(!TI);
    	TI = 0; //准备下次发送 
    } 
    

    接收器是双缓冲结构 ;发送缓冲器,因为发送时CPU是主动的,不会产生重叠错误。

    4.2.2 使用到的新寄存器

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

    这个寄存器完全为串行口服务

    在这里插入图片描述

    SM0SM1为工作方式选择位,可选择四种工作方式
    在这里插入图片描述

    • SM2多机通信控制位,主要用于方式2和方式3
      当接收机的SM2=1时可以利用收到RB8来控制是否激活RI(RB8=0时不激活RI,收到的信息丢弃;RB8=1时收到的数据进入SBUF,并激活RI,进而在中断服务中将数据从SBUF读走)。
      当SM2=0时,不论收到的RB8为0和1,均可以使收到的数据进入SBUF,并激活RI(即此时RB8不具有控制RI激活的功能)。通过控制SM2,可以实现多机通信。
      在方式0时,SM2必须是0。在方式1时,如果SM2=1,则只有接收到有效停止位时,RI才置1。
    • REN允许串行接收位。由软件置REN=1,则启动串行口接收数据;若软件置REN=0,则禁止接收。
    • TB8在方式2或方式3中,是发送数据的第九位,可以用软件规定其作用。可以用作数据的奇偶校验位,或在多机通信中,作为地址帧/数据帧的标志位。
      在方式0和方式1中,该位未用。
    • RB8在方式2或方式3中,是接收到数据的第九位,作为奇偶校验位或地址帧/数据帧的标志位在方式1时,若SM2=0,则RB8是接收到的停止位。
    • TI发送中断标志位在方式0时,当串行发送第8位数据结束时,或在其它方式,串行发送停止位的开始时,由内部硬件使TI置1,向CPU发中断申请。在中断服务程序中,必须用软件将其清0,取消此中断申请
    • RI接收中断标志位。在方式0时,当串行接收第8位数据结束时,或在其它方式,串行接收停止位的中间时,由内部硬件使RI置1,向CPU发中断申请。也必须在中断服务程序中,用软件将其清0,取消此中断申请

    PCON 电源控制寄存器,中只有一位SMOD与串行口工作有关

    在这里插入图片描述
    SMOD(PCON.7) 波特率倍增位。在串行口方式1、方式2、方式3时,波特率与SMOD有关,当SMOD=1时,波特率提高一倍。复位时,SMOD=0。


    我们主要使用方式1来进行串口通信,所以我们就主要讲讲方式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请求中断。

    4.2.3 波特率的设置

    在串行通信中,收发双方对发送或接收数据的速率要有约定。通过软件可对单片机串行口编程为四种工作方式,其中方式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运行控制位)=1,以启动定时器)。
    这时溢出率取决于TH1中的计数值。T1 溢出率 = fosc /{ 12×[256 -(TH1)]}
    在单片机的应用中,常用的晶振频率为:12MHz和11.0592MHz。所以,选用的波特率也相对固定。常用的串行口波特率以及各参数的关系如表所示。

    在这里插入图片描述

    4.3串口如何使用

    串行口工作之前,应对其进行初始化,主要是设置产生波特率的定时器1串行口控制中断控制
    具体步骤如下:

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

    5.参考资料

    1. 普中科技A2开发板参考资料
    2. 《单片机原理及应用》(第四版)
    3. 《新概念51单片机C语言教程》郭天祥编著
    4. 单片机原理及应用课堂笔记
    展开全文
  • 在第一篇到第九篇博文中,我们认识到了一些基于IO输入与输出的基础电子器件使用: 《8051单片机实战分析(以STC89C52RC为例) | 01 - 点亮一个LED》 《8051单片机实战分析(以STC89C52RC为例) | 02 - LED延时约5s...

    在第一篇到第九篇博文中,我们认识到了一些基于IO口输入与输出的基础电子器件使用:
    8051单片机实战分析(以STC89C52RC为例) | 01 - 点亮一个LED
    8051单片机实战分析(以STC89C52RC为例) | 02 - LED延时约5s闪烁
    8051单片机实战分析(以STC89C52RC为例) | 03 - LED流水灯
    8051单片机实战分析(以STC89C52RC为例) | 04 - 蜂鸣器驱动
    8051单片机实战分析(以STC89C52RC为例) | 05 - 静态数码管驱动
    8051单片机实战分析(以STC89C52RC为例) | 06 - 动态数码管驱动
    8051单片机实战分析(以STC89C52RC为例) | 07 - 独立按键驱动
    8051单片机实战分析(以STC89C52RC为例) | 08 - 矩阵按键驱动
    8051单片机实战分析(以STC89C52RC为例) | 09 - LED点阵显示数字
    但现在我们要开始回到8051单片机内部,通过实战来认识它们的工作原理,你会发现通过它们可以去开发一些更有意思的东西!

    这篇博文带领大家认识一下STC89C52RC单片机定时器中断的使用。

    如果你不了解什么是中断,建议你先看这篇:
    STC89C52RC单片机额外篇 | 01 - 认识中断、中断源以及中断优先级

    如果你不了解什么是串口通信,建议你先看这篇:
    STC89C52RC单片机额外篇 | 02 - 认识串行通信、波特率以及数据包

    1 中断系统结构

    以下这张图是从中断引脚到中断入口所经过的通道:

    从图中不难看出RXTX引脚经过了SCON、IE、IP这些寄存器,因此我们在写程序时得把这些寄存器功能配置好,CPU才会按照我们的想法只执行!下面分别对这些寄存器进行介绍(稍微了解一下即可,忘记的时候再查)。

    1.1 SCON寄存器

    SCON(Serial Control Register),中文叫串行口控制寄存器,SCON寄存器是用于控制串行通信的方式选择、接收和发送,指示串口的状态。

    首先介绍SCON寄存器位SM0/SM1,它们用于设置工作方式:

    其余SCON寄存器位的用途:

    SCON寄存器位作用
    SM2多机通信控制位。多机通信是工作于方式2和方式3,SM2位主要用于方式2和方式3。接收状态,当串行口工作于方式2或3,以及SM2=1时,只有当接收到第9位数据(RB8)为1时,才把接收到的前8位数据送入SBUF,且置位RI发出中断申请,否则会将接收到的数据放弃。当SM2=0时,就不管第9位数据是0还是1,都会将数据送入SBUF,并发出中断申请。工作于方式0时,SM2必须为0。
    REN允许接收位。REN用于控制数据接收的允许和禁止,REN=1时,允许接收,REN=0时,禁止接收。
    TB8发送数据位8。在方式2和方式3中,TB8是要发送的——即第9位数据位。在多机通信中同样亦要传输这一位,并且它代表传输的地址还是数据,TB8=0为数据,TB8=1时为地址。
    RB8接收数据位8。在方式2和方式3中,RB8存放接收到的第9位数据,用以识别接收到的数据特征。
    TI发送中断标志位,它是可寻址标志位。方式0时,发送完第8位数据后,由硬件置位,其它方式下,在发送或停止位之前由硬件置位,因此,TI=1表示帧发送结束,TI可由软件清“0”。
    RI接收中断标志位,它是可寻址标志位。接收完第8位数据后,该位由硬件置位,在其他工作方式下,该位由硬件置位,RI=1表示帧接收完成。

    要注意的是在串口中断处理时,TI,RI都需要软件清"0",硬件置位后不可能自动清0,此外,在进行缓冲区操作时,需要ES=0,以防止中断出现。ES寄存器位位于接下来介绍的IE寄存器。

    1.2 IE寄存器

    IE(Interrupt Enable),中文叫中断允许寄存器,它的作用是控制所有中断源的开放或禁止,以及每个中断源是否被允许。

    各寄存器位的作用如下:

    IE寄存器位作用
    EAEA = 0时,所有中断禁止(即不产生中断);EA = 1时,各中断的产生由个别的允许位决定
    ES串行口RX/TX中断允许
    ET1定时器T1中断允许
    EX1外中断INT1中断允许
    ET0定时器T0中断允许
    EX0外部中断INT0中断允许

    1.3 IP寄存器

    IP(Interrupt Priority),中文叫中断优先级寄存器,它是用来设定各个中断源属于两级中断中的哪一级。

    各寄存器位的作用如下:

    IP寄存器位作用
    PS串行口RX/TX中断优先
    PT1定时器T1中断优先
    PX1外中断INT1中断优先
    PT0定时器T0中断优先
    PX0外部中断INT0中断优先

    除此之外,还有一个波特率有关的PCON寄存器,当然这里只用到它其中的一位。

    1.4 PCON寄存器

    PCON全称Power Control Register,即功率控制寄存器

    系统复位默认为SMOD=0。当SMOD=0时,串口方式1,2,3时,波特率正常;当SMOD=1时,串口方式1,2,3时,波特率加倍。

    2 串行口结构

    注意这里的SBUF寄存器只是逻辑上同名,但是它们物理上是分开的!另外,还需要用到TH1TL1这种属于定时器T1的寄存器,后面会了解到它们的作用!

    下面列出各个工作方式的数据传输:

    ① 工作方式0:

    ② 工作方式1:

    ③ 工作方式2与工作方式3:

    3 波特率计算

    如果你不了解什么是波特率,建议你先看这篇:
    STC89C52RC单片机额外篇 | 02 - 认识串行通信、波特率以及数据包

    下面列出基于各个工作方式的波特率计算公式,对于可变波特率的设置需要用到TH1寄存器:

    当然,对于波特率,一般有几种是可供选择的,因为我们通常使用标称值:

    这里我们好奇为什么晶振频率选择11.0592MHz就能减小计算误差,下面我们以9600波特率,分别代入11.0592MHz与12MHz计算一下:

    我们设置定时器T1为工作模式2,SMOD 设为1,分别看看那所要求的TH1为何值。代入公式:

    • 11.0592MHz

              9600=(2÷32)×((11.0592M/12)/(256-TH1)) 
              =》TH1=250 
      
    • 12MHz

              9600=(2÷32)×((12M/12)/(256-TH1)) 
              =》TH1≈249.49 
      

    4 代码

    ① 中断服务函数:

    我们知道我们编写的C程序,函数的执行是从main主函数开始执行,现在有了中断,自然就产生一个中断服务函数:

    从图中我们可以知道单片机在发生中断的时候,程序的执行过程会从主程序A跳到中断服务程序B,在执行完中断服务程序B后,会返回到之前主程序A被中断打断处继续执行程序。

    那么我们如何指定中断服务程序?具体参考以下模板(对于函数名你可以随便写,当然最好贴近有意义的命名)。

    外部中断0的中断服务函数:

    void Int0()	interrupt 0
    {
    	... // 中断服务程序中要执行内容
    }
    

    定时器0的中断服务函数:

    void Timer0()	interrupt 1
    {
    	... // 中断服务程序中要执行内容
    }
    

    外部中断1的中断服务函数:

    void Int1()	interrupt 2
    {
    	... // 中断服务程序中要执行内容
    }
    

    定时器1的中断服务函数:

    void Timer1()	interrupt 3
    {
    	... // 中断服务程序中要执行内容
    }
    

    串行口的中断服务函数:

    void Serial()	interrupt 4
    {
    	... // 中断服务程序中要执行内容
    }
    

    ② 下面我们写个程序,将波特率设置为4800,把发送的数据字符"1"显示到串口调试助手SSCOM:

    #include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器
    
    typedef unsigned int u16;	  //对数据类型进行声明定义
    typedef unsigned char u8;
    
    /*******************************************************************************
    * 函数名         :UartInit()
    * 函数功能		 :设置串口
    * 输入           : 无
    * 输出         	 : 无
    *******************************************************************************/
    void UartInit()
    {
    	SCON=0x50;			//设置为工作方式1
    	TMOD=0x20;			//设置计数器工作方式2
    	PCON=0x80;			//波特率加倍
    	TH1=0xF3;			//计数器初始值设置,注意波特率是4800
    	TL1=0xF3;
    	ES=1;				//打开接收中断
    	EA=1;				//打开总中断
    	TR1=1;				//打开计数器
    }
    
    /*******************************************************************************
    * 函 数 名       : main
    * 函数功能		 : 主函数
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void main()
    {	
    	UartInit();  //	串口初始化
    	while(1);		
    }
    
    /*******************************************************************************
     * 函数名         : Serial() interrupt 4
     * 函数功能		 : 串口通信中断函数
     * 输入           : 无
     * 输出          : 无
    *******************************************************************************/
    void Serial() interrupt 4
    {
    	u8 receiveData;
    
    	receiveData=SBUF; //出去接收到的数据
    	RI = 0;			  //清除接收中断标志位
    	SBUF=receiveData; //将接收到的数据放入到发送寄存器
    	while(!TI);		  //等待发送数据完成
    	TI=0;			  //清除发送完成标志位
    }
    

    简要分析:

    • 代码中设置波特率为4800,根据前面的表格不是应该设置TH1=0xFA;吗?根据前面的介绍,我们不难发现此处用到晶振频率肯定不是11.0592MHz,明显是使用12MHz。
    • 注意这里把定时器T1设置为工作方式2——8 位自动重装模式,因此寄存器TH1TL0的值是一样的。
    • 最后附上串口调试助手的操作:
    展开全文
  • (2) 0003H——外部中断 0 的中断服务子程序入口地址。 (3) 000BH——定时/计数器 0 的中断服务子程序入口地址。 (4) 0013H——外部中断 1 的中断服务子程序入口地址。 (5) 001BH——定时/计数器 1 的中断服务子程序...
  • MCS-51单片机提供了4种串口的方式,但是我们只有方式1最常用(可变的10位串行通讯方式),下面就方式1的使用进行讲解。...通过中断向量,可以知道串行通讯只有一个中断号4,也就是说当进入无论是发送或...
  • 51汇编练习——串行口的传输

    千次阅读 2020-12-05 19:20:56
    串行口中断入口地址 LJMP INT_T0 ORG 0030H MAIN:MOV SCON,#50H ;串行口工作方式1 MOV PCON,#00H ; SMOD置0 MOV TMOD,#20H ;定时计数器工作方式2 MOV TH1,#0FDH ;设置溢出率初值 MOV TL1,#0FDH
  • 中断指令“RETI”作为中断跳出指令,除了将堆栈中保存着的地址取出,送回PC,使程序从主程序的中断处继续往下执行的作用外,还有将“优先级生效”触发器清零的功能。 2、中断请求标志寄存器 1)TC
  • 51单片机串行口的使用与串行通信串行通信:俩个概念:RS232接口标准:串行口的使用:串行口的结构:串行口相关寄存器:串行口的工作方式:方式0:同步移位寄存器方式利用方式0扩展并行I/O口:方式1:8位异步通信方式...
  • 《单片机原理及应用》试题库第四章定时器、串行口中断系统一、判断题()1.在MCS—51单片机内部结构中,TMOD为模式控制寄存器,主要用来控制定时器的启动与停止。×()2.在MCS—51单片机内部结构中,TCON为控制...
  • 51单片机学习 串行口通信实验

    千次阅读 2021-01-19 19:27:20
    51单片机学习 串行口通信实验
  • 串行口扩展并行输出口 一、实验目的 二、实验内容 三、实验步骤 四、C代码如下 五、实验结果 六、实验体会 一、实验目的 掌握AT89C52串行口方式0的工作方式和编程 掌握利用串行口和移位寄存器扩展并行...
  • 51单片机中断系统

    2021-01-14 19:23:10
    51单片机有5个中断源,分别是外部中断0,定时/计数器T0中断,外部中断1,定时/计数器T1中断,串行口中断,对应地址如下表: 中断源 中断矢量地址 外部中断0 0003H 定时/计数器T0中断 000BH 外部中断1 ...
  • 51单片机定时器、串口、中断

    千次阅读 2021-01-05 19:08:46
    串行口三、中断系统 MCS-51功能单元 一、定时器&计数器 数量:两个可编程的16位的定时器/计数器T0和T1;都是16位加法计数结构;分为高8位和低8位;TH0、TL0,TH1、TL1; 定时器/计数器T0、T1是80C51的中断源之...
  • 单片机--串行口实验

    千次阅读 2019-11-30 16:10:40
    目的:利用“模块化单片机教学实验平台”,加深对单片机的串行口的理解。 任务:利用单片机的串行口完成程序设计。 实验内容 使用AT89S52单片机的串行口通过RS232通信接口与PC机进行通信,让单片机把接收到的每一...
  • 中断程序的入口地址被编译器放在中断向量中,中断向量位于程序代码段的地址处,注意这里的串口输入/输出中断共用一个中断向量。8051的中断向量表如下:  中断中断向量  ---------------------------  上电...
  • (九)串口中断

    2022-02-28 19:34:49
    这些协议都是从最基础的串口的协议进行封装而成的,而我们在51单片机上只需要了解最基本的串口中断的内容就好了。 1. 关于串口 首先要了解的就是什么是串口通信,要了解串口通信就要先了解串行通信和并行通信,...
  • 52单片机共有6个中断源,分别如下:INT0——外部中断0,由P3^2端口引入,低电平或者下降沿引起;中断级别最高;C语言使用序号为0;本文引用地址:http://www.eepw.com.cn/article/201611/315423.htmT0——定时器/...
  • 对于单片机处理串口通信发送和接收完时候的中断请求标志位都需要软件置位的,而不是硬件自动置位呢,是否有想过呢? 因为串口通信的中断请求是这样子的,当一帧发送完成,内部硬件自动置位TI=1,而当接收完一帧信息...
  • C系列单片机有一个全双工的串行口.ppt80C51系列单片机有一个全双工的串行口,这个口既可以用于网络通信,也可以实现... 串行口作为并行输入口使用时,要有“并入串出”的移位寄存器配合。 LIGHT:MOV SCON,#00H ;串...
  • 51单片机学习——中断

    千次阅读 2021-05-23 14:27:24
    1、中断源及其中断标志 ... 串行口中断号为4;中断标志为R1或T1;中断服务程序入口为0023H; 2、中断允许控制 CPU对中断系统所有中断及其某个中断源的开放和屏蔽是由中断允许寄存器IE控制的。IE的状态可
  • 51单片机中断控制.pdf

    2022-06-19 12:08:51
    中断入口 高 级 低 级 中断源 中断源 中断名称 中断号 中断入口地 址 外部中断0 INT0 0 0003H 定时/计数器0 T1 1 000BH 外部中断1 INT1 2 0013H 定时/计数器1 T1 3 001BH 串行口中 RI/TI 4 0023H 定时/计数器2(仅...
  • 内容概要 本章介绍MCS-51片内中断系统的硬件结构和工作原理。 7.1.1 MCS-51中断技术概述 ...共有5个中断请求源(简称中断源),2个中断优先级,可实现2级中断服务程序嵌套。每一中断源可用软件独立地
  • 51单片机中断

    2021-10-02 18:09:52
    51单片机中断机制 单片机的中断简介 52单片机一个有6个中断源,它们的符合,名称以及触发方式如下:
  • MCS-51单片机的特殊功能寄存器 ... 地址 功能介绍 B F0H B寄存器 ACC E0H 累加器 PSW D0H 程序...
  • 中断

    2017-04-03 20:04:36
    有5个固定的中断源,其中3个在片内,2个在片外,它们在程序存储器ROM中都分别有各自固定的中断入口地址,由此进入中断服务程序(ISR);这5个固定的中断源都分别有两级中断优先级:高优先级和低优先级;可形成中断嵌套;有2个...
  • 一、中断的概念:  (1)CPU 在处理某一事件 A 时,发生了另一事件 B 请求 CPU 迅速去处理(中断发生);  (2)CPU 暂时中断当前的工作,转去处理事件 B(中断响应和中断服务);  (3)待 ...
  • 外部0中断触发:(P3.2触发;P3.2触发;P3.2触发) 若IT0=0,则为低电平触发 若IT0=1,则为下降沿触发 外部中断0初始化: 初始化方法一: void Init_INT0() { IT0=1;//设置外部中断0;下降沿触发 EX0=1;//开启...
  • MCS-51单片机的中断系统

    千次阅读 2020-10-19 14:07:26
    一、基本概念 (一)中断的概念 中断是通过硬件来改变CPU的运行方向的。当CPU正在执行主程序的时,外部或内部发生的...1.分时操作:单片机有了中断功能,使CPU与外设由串行工作变成分时并行工作,实现了CPU和外设的同步
  • C51单片机中断

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,751
精华内容 1,500
关键字:

串行口中断的入口地址