-
2020-12-22 11:56:18
AT89C52流水灯+外部中断INT0+定时器(汇编语言)
任务要求
用 AT89S52 单片机控制彩灯(流水灯)图形及继电器。即:
①AT89S52 单片机上电时控制由发光二极管组成的图形有规律地不停闪烁(亮、灭的时间不能为 5 秒!);
②当按下按钮(任何时候)时彩灯图形全灭,而继电器工作吸合(控制~220V 30W灯泡亮)5 秒,5 秒后返回彩灯闪烁。思路
中断可采取外部中断INT0方式,定时器可采用模式一(一次定时50ms,循环100次即为5s);
流水灯部分,我们的想法是做一个“CXK”运球的动作,顺序为左——中——右——中——左,并通过换位实现流水灯的变化,具体代码实现如下:汇编代码
ORG 0000H ;单片机上电后从0000H地址执行 AJMP START ;跳转到主程序存放地址处 ORG 0003H ;设置主程序开始地址 AJMP INSER ;设置中断入口地址 ORG 0030H MOV SP,#60H ;设置堆栈起始地址为60H START: SETB TR0 ;允许启动定时器 SETB EX0 ;中断设置优先级 SETB IT0 MOV R3,#32H ;R3初值 SETB EA ;字卸宪开关 MOV A,#0FFH ;灯全灭 MOV P1,A MOV A,#0FEH ;1灯亮 MOV P1,A MOV R2,#08H LOOP1:RL A ;左移,向右流水灯亮(向右流水灯) MOV P1,A ACALL DELAY1 DJNZ R2,LOOP1 MOV R2,#05H LOOP2:MOV A,#0FFH ;灯全灭(外圈灯闪烁5次) MOV P1,A ACALL DELAY1 MOV A,#00H ;灯全亮 MOV P1,A ACALL DELAY1 DJNZ R2,LOOP2 MOV A,#0FFH ;灯全灭 MOV P1,A ACALL DELAY1 MOV A,#0EEH ;0和4灯亮 MOV P1,A MOV R2,#10H LOOP3:RL A ;(流水灯) MOV P1,A ;右移,0和4,1和5,2和6,3和7灯亮 ACALL DELAY1 DJNZ R2,LOOP3 MOV A,#0FFH MOV P1,A ;灯灭 MOV R2,#10H MOV A,#0EEH MOV P1,A ACALL DELAY1 MOV A,#77H LOOP4:RR A ;左移,(流水灯) MOV P1,A ACALL DELAY1 DJNZ R2,LOOP4 MOV R2,#08H MOV A,#0FEH LOOP5:RR A ;左移,向右流水灯亮(向左流水灯) MOV P1,A ACALL DELAY1 DJNZ R2,LOOP5 MOV A,#0FFH MOV P1,A MOV R2,#05H LOOP6:MOV A,#0FFH ;灯全灭(外圈灯闪烁5次) MOV P1,A ACALL DELAY1 MOV A,#00H ;灯全亮 MOV P1,A ACALL DELAY1 DJNZ R2,LOOP6 MOV R0,#05H MOV A,#0F0H ;(运球) MOV P0,A ;身体部位亮 SETB P2.0 SETB P2.1 SETB P2.2 ;三个球都灭 CLR P2.3 CLR P2.4 CLR P2.5 ;CXK亮 LOOP7:CLR P2.0 ;左球亮 CLR P2.3 ;C亮 SETB P2.4 SETB P2.5 ;XK不亮 ACALL DELAY1 SETB P2.0 ;左球灭 SETB P2.3 ;C灭 CLR P2.1 ;中间球亮 CLR P2.4 ;X亮 ACALL DELAY1 SETB P2.1 ;中间球灭 SETB P2.4 ;X灭 CLR P2.2 ;右球亮 CLR P2.5 ;K亮 ACALL DELAY1 SETB P2.2 ;右球灭 SETB P2.5 ;K灭 CLR P2.1 ;中间球亮 CLR P2.3 CLR P2.4 CLR P2.5 ;CXK全亮 ACALL DELAY1 SETB P2.1 ;中间球灭 SETB P2.3 SETB P2.4 SETB P2.5 ;CXK全灭 CLR P2.0 ;左球亮 ACALL DELAY1 DJNZ R0,LOOP7 ;循环5次 MOV R1,#0AH LOOP8:MOV A,0FFH ;(人亮,球不亮,且人闪烁) MOV P0,A ;身体不亮 SETB P2.0 SETB P2.1 SETB P2.2 ;三个球都要不亮 ACALL DELAY1 MOV A,#0F0H MOV P0,A ;身体亮 CLR P2.3 CLR P2.4 CLR P2.5 ;CXK亮 ACALL DELAY1 CPL A MOV P0,A ;身体灭 SETB P2.3 SETB P2.4 SETB P2.5 ;CX灭 ACALL DELAY1 DJNZ R1,LOOP8 MOV R1,#0AH AJMP START HERE:SJMP HERE ;查询中断 ORG 0200H INSER:SJMP MIE ;跳转中断服务程序 MIE:MOV P0,#0FFH ;灯灭 MOV P1,#0FFH ;灯灭 MOV P2,#0FFH ;灯灭 CLR P3.7 ACALL DELAY ;调用定时器 MOV R3,#32H ;循环100次 SETB P3.7 RETI ;中断子程序返回 DELAY:MOV TMOD,#01H ;定时器基础设计,模式1,查询方式 MOV TL0,#0B0H ;每隔50ms定时一次 MOV TH0,#3CH ;同上 JNB TF0,$ ;查询判断TF0的溢出 CLR TF0 ;清0 DJNZ R3,DELAY ;循环 RET DELAY1:MOV R6,#200 ;50ms延时子程序 L1:MOV R7,#200 L2:NOP DJNZ R7,L2 DJNZ R6,L1 RET ;子程序返回 END
仿真电路
硬件电路
一共用了67个灯,大部分灯为并联接到一个口
实际效果
新能源1第一组流水灯
后言
汇编程序不难,难的是焊接工作和排线,焊接大概花费了3-4天的时间,希望这篇文章能给以后学习相关综合实验的师弟师妹一个参考,非专业非科班某单片机课设留。
更多相关内容 -
TMS320F28335外部中断总结
2020-08-19 00:25:11在这里我们要十分清楚DSP的中断系统。C28XX一共有16个中断源,其中有2个不可屏蔽的中断RESET和NMI、定时器1和定时器2分别使用中断13和14。这样还有12个中断都直接连接到外设中断...这样PIE共管理12*8=96个外部中断。 -
外部中断实验(急救车与交通灯)
2020-08-02 00:33:19本文主要介绍了外部中断实验(急救车与交通灯)。 -
6.STC15W408AS单片机外部中断
2021-07-15 09:29:24STC15W408AS单片机有4个外部中断,它们分别是:外部中断0(INT0)、外部中断1(INT1)、外部中断2(INT2)、外部中断3(INT3)。 外部中断0(INT0)和外部中断1(INT1)触发有两种触发方式,上升沿或下降沿均可触发方式 和仅...一、外部中断简介
STC15W408AS单片机有4个外部中断,它们分别是:外部中断0(INT0)、外部中断1(INT1)、外部中断2(INT2)、外部中断3(INT3)。
外部中断0(INT0)和外部中断1(INT1)触发有两种触发方式,上升沿或下降沿均可触发方式
和仅下降沿触发方式。
TCON寄存器中的IT0/TCON.0和IT1/TCON.2决定了外部中断0和1是上升沿和下降沿均可触发还是仅下降沿触发。如果ITx = 0(x = 0,1),那么系统在INTx(x = 0,1)脚探测到上升沿或下降沿后均可产生外部中断。如果ITx = 1(x = 0,1),那么系统在INTx( x= 0,1)脚探测下降沿后才可产生外部中断。外部中断0(INT0)和外部中断1(INT1)还可以用于将单片机从掉电模式唤醒。
外部中断2(INT2)、外部中断3(INT3)都只能下降沿触发。外部中断2~3的中断请求标志位被隐藏起来了,对用户不可见,故也无需用户清"0"。当相应的中断服务程序被响应后或中断允许位EXn (n=2,3)被清零后,这些中断请求标志位会立即自动地被清0。这些中断请求标志位也可以通过软件禁止相应的中断允许控制位将其清"0"(特殊应用)。外部中断2(INT2)、外部中断3(INT3)也可以用于将单片机从掉电模式唤醒。
由于系统每个时钟对外部中断引脚采样1次,所以为了确保被检测到,输入信号应该至少维持2个时钟。如果外部中断是仅下降沿触发,要求必须在相应的引脚维持高电平至少1个时钟,而且低电平也要持续至少一个时钟,才能确保该下降沿被CPU检测到。同样,如果外部中断是上升沿、下降沿均可触发,则要求必须在相应的引脚维持低电平或高电平至少1个时钟,而且高电平或低电平也要持续至少一个时钟,这样才能确保CPU能够检测到该上升沿或下降沿。
二、中断结构图
这里,我们只需要看最上面的部分就可以。
三、中断寄存器
IE寄存器是中断总控制,IP是中断优先级控制寄存器,TCON的低4位是外部中断0和外部中断1控制位。一般情况下我们只需要操作IE和TCON寄存器即可。
四、实验电路图
实验现象是点按一下按钮,LED闪烁一次,和上面的按键输入实验效果是一样的。
五、实验程序
#include "stc15.h" void main() { P11 = 0; // 初始设置P1.1为低电平 熄灭LED IT0 = 1; // 设置INT0的中断类型 (1:仅下降沿 0:上升沿和下降沿) EX0 = 1; // 使能INT0中断 EA = 1; // 打开总中断 while (1); } //外部中断服务程序 void exint0() interrupt 0 //INT0中断入口 { P11 = !P11; //将P1.1口取反 }
这里需要说明的是为什么外部中断服务程序是 interrupt 0。这个后面数字和中断优先级有关。从上面的中断结构图中,我们就可以看出外部中断0的优先级是最高的,所以这里是0,其他的在后面使用到再讲。
更多首发原创,请关注我。
-
快速复习51单片机的外部中断、计数/定时器中断和串行口中断,加代码实现
2021-09-13 15:12:32//在这里等待被外部中断0打断 } void Int0() interrupt 0 //外部中断0的中断函数,函数名可以定义,interrupt 后面的中断号不能出错 { delay(1000);//按键消抖 if(K3==0)// k3被按下 { led = ~led; } } 2.2 ...目录
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单片机的中断优先级有三条原则
- CPU同时接收到几个中断时,首先响应优先级别最高的中断请求。
- 正在进行的中断过程不能被新的同级或低优先级的中断请求所中断。
- 正在进行的低优先级中断服务,能被高优先级中断请求所中断。
为了实现上述后两条原则,中断系统内部设有两个用户不能寻址的优先级状态触发器。其中一个置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
(串行口控制寄存器) 是一个特殊功能寄存器,用以设定串行口的工作方式、接收/发送控制以及设置状态标志这个寄存器完全为串行口服务
SM0
和SM1
为工作方式选择位,可选择四种工作方式
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
、串行口控制
和中断控制
。
具体步骤如下:- 确定T1的工作方式(编程TMOD寄存器);
- 计算T1的初值,装载TH1、TL1;
- 启动T1(编程TCON中的TR1位);
- 确定串行口控制(编程SCON寄存器);
- 串行口在中断方式工作时,要进行中断设置(编程IE、IP寄存器)。
5.参考资料
- 普中科技A2开发板参考资料
- 《单片机原理及应用》(第四版)
- 《新概念51单片机C语言教程》郭天祥编著
- 单片机原理及应用课堂笔记
-
外部中断与内部中断原理与使用
2021-07-26 09:36:51外部中断源2个 1.INT0 — 由P3.2端口控制引入,低水平或者下降沿引起。(下降沿就是给5V后给0V形成下降电压) 2.INT1 —由P3.3端口控制引入,低水平或者下降沿引起。 (这两个中断源标志与中断方式由特殊功能寄存器...1.解释
计算机执行某一程序时,发生了紧急事件或者有特殊请求,CPU暂停某程序的执行,转而去处理上述事件,处理完毕后再重新执行原来被打断的程序。
2.步骤
中断请求>中断响应>中断处理>中断返回
3.51的中断源
有五个中断源
外部中断源2个
1.INT0 — 由P3.2端口控制引入,低水平或者下降沿引起。(下降沿就是给5V后给0V形成下降电压)
2.INT1 —由P3.3端口控制引入,低水平或者下降沿引起。
(这两个中断源标志与中断方式由特殊功能寄存器TCON的低四位控制)
内部中断源3个
1.T0 —定时器/计数器0中断,由T0回0溢出引起。
2.T1 —定时器/计数器1中断,由T1回0溢出引起。
3.T1/RI —串行I/O口中断,串行端口完成一帧字符发送引起。
(由TCON和SCON控制)
4.51内部结构图
要运用那个中断就要打开对应的开关,首先EA(总开关)要打开,假设要打开外部中断0,就需要再控制IT0与EX0与PX0。
5.如何使用中断
(1.打开对应的中断开关)
EA —总开关,EA打开CPU接受中断请求;EA关闭,CPU屏蔽任何中断请求。
外部中断开关
EX1 —EX1打开,外部中断1打开,反之。
EX0 —EX0打开,外部中断0打开,反之。
内部中断打开
ET0打开,T0的溢出中断打开,反之。
ET1 —ET1打开,T1的定时器/计数器溢出中断打开,反之。
ET2 —ET2打开,T2的定时器/计数器溢出中断打开,反之。
ES —ES打开,串行口一中断打开,反之。
也可以按上表,8位2进制赋予IE打开对应开关。
(2.配置中断方式(触发对应中断的条件))
外部中断方式控制
IT0 —IT0为1,为下降沿触发方式。TT0为1,低电平触发方式。(控制在3.2脚)
IT1 —IT1为1,为下降沿触发方式。TT1为1,低电平触发方式。(控制在3.3脚)
内部中断方式控制
TR1 —定时器1的运行控制位。
TR0 —定时器0的运行控制位。
TF0 —T0溢出中断标志,TO被允许开始计数时,从初值加一开始运算,当溢出时,硬件自动命TF0为1,引发T0中断,当执行完,硬件自动清0。
TF1—T1溢出中断标志,T1被允许开始计数时,从初值加一开始运算,当溢出时,硬件自动命TF1为1,引发T1中断,当执行完,硬件自动清0。内部中断模式位
想要打开内部中断0与1什么模式就命对应TMOD为什么值,如果我需要定时器0的定时功能,TMOD=0000 0001=0x01。如果需要定时器0计数,需要把C/T打开,就是TMOD=00000101=0x05。(3.触发优先级)
当多个中断同时发生,按下面顺序
注意:优先级高的中断可以打断优先级低的中断
(4.中断处理函数)
步骤总结
1.打开对应的中断开关
2.控制对应中断执行的条件
3.写中断函数以下是各个中断的函数示例(4个)
外部中断1函数实例(外部中断0同样是这样用)
#include "reg52.h" sbit key1=P3^1; sbit flag = P3^3; void delay(unsigned int i) { while(i--); } void lnt1init() { EA = 1; //总开关打开 EX1 = 1; //外部中断开关打开 IT1 = 1; //触发方式(下降沿) } void int1() interrupt 2 //外部中断函数,interrupt后面的数字根据优先级那个图有个入口数字 { P2 = ~P2; //由亮变无或由无变亮 } void keypros() { if(key1==0) //独立按键被按下 { delay(100); if(key1==0) //按键消抖 { flag = 1;//产生下降沿,就会进入到中断函数 flag = 0; while(!key1); //松手检测 } } } void main() { lnt1init(); P2 = 0x00; //先取全部亮 while(1) { keypros(); } }
内部中断0的软件中断(用作计时器)
注意这里不是中断函数的使用,而是运用定时器0,故它的函数开关不需要打开#include "reg52.h" sbit LA=P2^2; sbit LB=P2^3; sbit LC=P2^4; sbit key2 = P3^0; unsigned char smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; void delay(unsigned int z) { unsigned int x,y; for(x=z;x>0;x--) for(y=120;y>0;y--); } void timefrist() { TR0 = 1; //打开定时器0开关 TMOD = 0x01; //定义模式 TH0 = 0x4B; //定义初始值后不断加1,每加1为1.085us,从到19453到65535共46085次,共50ms TL0 = 0xfd; //前面那个值为19453的16进制的前2位,这个为它的后2位。19453 = 4Bfd } unsigned char miao=0; //秒 unsigned char fen=0; //分 void DigDisplay() { LA=1;LB=1;LC=1; //位选,这里用的是转码器3个2进制可以控制8个七段码那个亮 P0 = smgduan[fen]; //段选,同样是动态规划的思想 delay(5); LA=0;LB=1;LC=1; P0 = smgduan[miao]; delay(5); } void main() { unsigned char text=0; timefrist(); while(1) { if(TF0==1) //当定时器0溢出了,即经过50ms,TF0自动设置为1; { TF0 = 0; //归0 TH0 = 0x4B; //每次使用都要重新定义为50ms TL0 = 0xfd; text++; if(text==20) //当它进行了20次,20*50ms=1s { text =0; //归0,之后继续加 miao++; //秒加1 } if(miao==10) //秒为10的时候就可以进位了 { miao = 0; //归0 fen++; //秒十位+1 } } DigDisplay(); //上面执行很快,所以一直都是动态显示 } }
内部中断定时器0与按键
独立按键1可以实现数值+1,独立按键2实现数值-1
解释:因为按键有个按键消抖与松手检测会影响动态显示。特别是松手检测,如果你不松手会一直停在那里,不松手就无法动态显示。所有我们用定时器0直接控制,当经过5ms就用一次显示函数,就算不松手也是有中断自动执行显示函数。#include "reg52.h" sbit LA=P2^2; sbit LB=P2^3; sbit LC=P2^4; sbit key1 = P3^0; //按键1 sbit key2 = P3^1; //按键2 unsigned char smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; void delay(unsigned int z) { unsigned int x,y; for(x=z;x>0;x--) for(y=120;y>0;y--); } void timefrist() { EA = 1; //打开总开关 ET0 = 1; //中断函数0的开关 TR0 = 1; //打开定时器0开关 TMOD = 0x01; //模式一,定时模式 TH0 = 0xED; //这里改值了,到上限就5ms TL0 = 0xFF; } unsigned char miao=0; void DigDisplay(unsigned char h) { unsigned char a=h%10; //个位 unsigned char b=h/10; //十位 static unsigned char wei=0; //静态变量,就是函数执行完也不会抹去这个变量的值,在次使用函数值可以用 switch(wei) //这里重新布局,我们这里不断交换显示,用一次函数就显示一个,当快速多显示就动态显示 { case 0: LA=1;LB=1;LC=1;P0 = smgduan[b];break; //wei值0与1不断交换,就动态显示 case 1: LA=0;LB=1;LC=1;P0 = smgduan[a];break; } wei++; //用过之后++ if(wei==2) //我们只要1与0不断交换,为2时就重新回0 { wei = 0; } } void timer0() interrupt 1 { TH0 = 0xED; //重新定义5ms初始值 TL0 = 0xFF; DigDisplay(miao); //显示,不断5ms显示就是动态显示 } void main() { timefrist(); while(1) { if(key1==0) //为0,按键被按下 { delay(20); if(key1==0) //按键消抖 { miao++; //全局miao加1,显示就会加1了 while(!key1); //松手检测 } } if(key2==0) //同理 { delay(5); if(key2==0) { miao--; while(!key2); } } } }
内部中断定时器与计数器同时使用
内部中断0用作计数(就是3.4口有电压波动TH0与TL0的总值就会加1,由于TH0为后2位,加不到,后面就为TL0加一),内部中断1用作定时器
思想:定时器1到时间就使LED电压反转(亮与不亮),然后该LED的与P3.4口连在一起,当LED灯不断闪烁,电压不断变化,3.4口就会感受电压波动自动使TL0加1,然后把TL0值传递显示,就可以观察TL0变化。#include "reg52.h" sbit LA=P2^2; sbit LB=P2^3; sbit LC=P2^4; sbit key2 = P3^0; sbit LED = P2^0; unsigned char code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; void delay(unsigned int z) { unsigned int x,y; for(x=z;x>0;x--) for(y=120;y>0;y--); } void timefrist0() { TR0 = 1; //打开计数器1 TMOD |= 0x05; //模式值为5 TH0 = 0; //计数功能,设为0 TL0 = 0; } void timefrist1() { EA = 1; TR1 = 1; //中断1的开关 TMOD |= 0x10; //0001 0000 TH1 = 0x4b; //铁打的50ms TL1 = 0xfd; } void DigDisplay(unsigned char miao) { LA=1;LB=1;LC=1; //8动态显示函数 P0 = smgduan[miao]; delay(5); LA=0;LB=1;LC=1; //6 P0 = smgduan[miao/10]; delay(5); } void main() { unsigned char text=0; timefrist0(); //中断0与1的初始定义 timefrist1(); LED = 0; while(1) { if(TF1 == 1) //定时器0溢出,50ms过 { TF1 = 0; TH1 = 0x4b; TL1 = 0xfd; text++; if(text==10) //经过 0.5s { text = 0; LED = ~LED; //变化一次,形成电压给P3.4 } } DigDisplay(TL0); //上面动作很快,动态显示一直在执行 } }
-
【51单片机——外部中断应用】哪些I/O口可以用外部中断?
2020-04-11 22:17:0451单片机具有5个中断源,其中有两个外部中断INT0、INT1。 1、外部中断0:INT0,其对应的引脚为P3^2。 #include "reg52.h" typedef unsigned int u16; typedef unsigned char u8; sbit k3=P3^2; //定义按键... -
外部中断初始化配置
2021-06-02 09:55:35timer_ISR.c /*********************... *输入:uchar mode 0为外部中断0低电平触发,1为外部中断0下降沿触发 *返回:无 *************************************************/ void int0_Init(uchar mode) { IE0 = 0; -
单片机原理及其应用——单片机外部中断实验(八段数码管通过按键依次显示0~9数字)
2021-12-09 16:08:46目录一、实验要求二、分析(一)数码管(二...2、掌握外部中断的中断初始化和中断服务函数的程序编写方法,编程实现实现数码管上显示外部中断计数。 【实验内容】 1、用Proteus绘制硬件原理图,并设置元件参数; 2、用 -
外部中断
2020-11-20 12:41:42文章目录外部中断硬件控制外部中断矢量外部中断控制寄存器外部中断控制位软件控制外部中断0初始化方法外部中断1初始化方法外部中断程序框架示例P3.2口脉冲输入计数 硬件控制 外部中断矢量 中断源名称 中断源地址... -
8051单片机实战分析(以STC89C52RC为例) | 10 - 外部中断的使用
2021-06-05 10:22:20各寄存器位的作用如下: IP寄存器位 作用 PS 串行口RX/TX中断优先 PT1 定时器T1中断优先 PX1 外中断INT1中断优先 PT0 定时器T0中断优先 PX0 外部中断INT0中断优先 2 原理图 下面我们进行例子来学习外部中断INT0与... -
单片机—外部中断与定时器 学习笔记
2021-03-16 19:33:458051定时/计数器由定时器0(T0)、定时器1(T1)、定时器方式寄存器TMOD和定时器控制寄存器TCON组成。 二、定时的原理——计数周期 当定时/计数器设置为定时工作方式时,计数器对内部机器周期进行计数,每过一个... -
AVR单片机中断实现 ATmega16 INT ISR(INT0_vect)
2021-01-17 19:07:382.21实例功能前面例子中分别介绍了按键控制发光二极管的亮灭,但是我们注意到,在程序中需要一直检测按键的状态,这样明显的浪费了单片机的资源,...在本例中,通过利用外部中断实现单片机对按键事件的响应和处理... -
51单片机之外部中断应用实例(电平触发、边沿触发)
2019-05-15 15:10:32硬件:STC89C52RC 开发工具:Keil uVision4 前言:8051是一款很经典的、历史悠久的单片机,作为一款入门级的...下面详细讲述外部中断功能的使用。 外部中断:单片机提供的系统紧急事件的输入控制。事件触发的方式... -
C51教程 第四个51程序:中断控制--外部中断0
2020-02-18 20:31:52单片机中断是指CPU在正常执行程序的过程中,由于计算机内部或外部发生了另一...今天要做的一个实验叫做外部中断,按下按键,停止主程序中的内容,立即转去执行中断服务函数。 我们主要看到原理图与代码,了解中断是什... -
80C51单片机外部中断的应用及其程序调试 (2010年)
2021-05-07 06:19:39分析了80C51单片机的2个对外中断入口INT0和INT1的结构、功能,讨论了通过控制机构的合理设置、编程,实现单片机对外中断功能的控制问题。 -
单片机实验报告,存储器读写,IO端口操作,定时中断,外部中断等.pdf
2022-06-23 03:40:56单片机实验报告,存储器读写,IO端口操作,定时中断,外部中断等.pdf单片机实验报告,存储器读写,IO端口操作,定时中断,外部中断等.pdf单片机实验报告,存储器读写,IO端口操作,定时中断,外部中断等.pdf单片机实验报告,... -
c8051之外部中断实验
2022-03-20 15:00:12在聊到外部中断之前我们首先要理解中断的概念: 中断是指计算机运行过程中...此次实验我们用到的是外部中断INT0,可以看出外部中断0可以配置为低电平触发,和下降沿触发,本次我们用到下降沿触发。 下面我们看一下配置 -
51单片机的中断源入口地址是程序存储器空间的5个单元
2020-04-08 00:44:33(2) 0003H——外部中断 0 的中断服务子程序入口地址。 (3) 000BH——定时/计数器 0 的中断服务子程序入口地址。 (4) 0013H——外部中断 1 的中断服务子程序入口地址。 (5) 001BH——定时/计数器 1 的中断服务子程序... -
单片机外部中断.ppt
2022-06-19 21:33:07单片机外部中断.ppt该文档详细且完整,值得借鉴下载使用,欢迎下载使用,有问题可以第一时间联系作者~ -
外部中断(数码骰子)
2022-04-10 10:47:44按键作为外部中断,每按一次按键后,首先控制数码管从a段到f段循环跑2圈,然后生成一个随机点数并在数码管上显示。 实验工具、器材:keil、proteus、AT89C51芯片、共阳数码管、按键 实验原理: 1、外部中断 ... -
S3C6410外部中断设置步骤
2014-04-15 12:29:28详细介绍S3C6410外部中断的设置步骤,适合除学者。 -
STM32(六)-------中断(外部中断)
2020-06-25 10:24:46F103 在内核水平上搭载了一个异常响应系统, 支持为数众多的系统异常和外部中断。 其中系统异常有 8 个(如果把 Reset 和 HardFault 也算上的话就是 10 个),外部中断有 60个。除了个别异常的优先级被定死外,其它... -
单片机外部中断实验报告 (3).pdf
2022-06-22 01:56:39单片机外部中断实验报告 (3).pdf单片机外部中断实验报告 (3).pdf单片机外部中断实验报告 (3).pdf单片机外部中断实验报告 (3).pdf单片机外部中断实验报告 (3).pdf单片机外部中断实验报告 (3).pdf单片机外部中断实验... -
单片机外部中断实验报告 (2).pdf
2022-06-22 00:47:26单片机外部中断实验报告 (2).pdf单片机外部中断实验报告 (2).pdf单片机外部中断实验报告 (2).pdf单片机外部中断实验报告 (2).pdf单片机外部中断实验报告 (2).pdf单片机外部中断实验报告 (2).pdf单片机外部中断实验... -
单片机外部中断实验报告 (3).docx
2022-06-22 00:29:45单片机外部中断实验报告 (3).docx单片机外部中断实验报告 (3).docx单片机外部中断实验报告 (3).docx单片机外部中断实验报告 (3).docx单片机外部中断实验报告 (3).docx单片机外部中断实验报告 (3).docx单片机外部中断... -
单片机外部中断实验报告 (2).docx
2022-06-22 00:29:06单片机外部中断实验报告 (2).docx单片机外部中断实验报告 (2).docx单片机外部中断实验报告 (2).docx单片机外部中断实验报告 (2).docx单片机外部中断实验报告 (2).docx单片机外部中断实验报告 (2).docx单片机外部中断... -
某外部可屏蔽中断的类型吗为08H,它的中断服务程序的入口地址为1020H:0040H,请用8086汇编语言编程,将该...
2020-07-21 18:09:58某外部可屏蔽中断的类型吗为08H,它的中断服务程序的入口地址为1020H:0040H,请用8086汇编语言编程,将该中断的入口地址填入中断向量表中。 方法一 MOV AX,0 MOV ES,AX MOV SI,20H MOV ES:[SI],0040H MOV ES:[SI+2]... -
外部中断使用指南(寄存器设置)
2021-05-23 08:28:58(寄存器:GPxxCON)例:②配置外部中断触发模式,上升沿触发,下降沿触发,双边触发,高电平触发,低电平触发(寄存器:EXT_INT_x_CON)例:③取消屏蔽外部中断(寄存器:EXT_INT_x_MASK)例:④通过向量中断控制器(VI... -
外部中断(CC2530)
2020-08-30 23:07:43(3)通过按键S1产生外部中断改变LED 二 中断概念 1.CPU在执行当前程序时,由于系统出现了某急需处理的的情况,CPU暂停正在执行的程序,转而去执行另外一段特殊程序来处理出现的紧急事务,处理结束后,CPU自动返回到...