51单片机外部中断与定时器的实用
51单板机定时和外部中断用到的寄存器说明
51单板机定时和外部中断用到的寄存器说明1.TMOD:定时器设置寄存器,不可按位寻址,0x89TMOD=0x01;//初始化定时器0, 根据晶振频率计算定时时间//假设晶振频率12MHz, 则时钟频率1/12 微秒,一个机器周期(访问一次存储器的时间)是12个时钟周期=1微秒。
//下面设置延时50ms。
TH0=(65535-50000)/256 ;TL0=(65535-50000)%256 ;2.TCON:定时器控制寄存器,可按位寻址0X88//启动定时器0,开始计数TR0=1;3.IE:中断允许寄存器,可按位寻址0XA8//开启定时器0中断ET0=1;//开启总中断控制EA=1;4.IP:中断优先控制寄存器,0XB85. SCON:串口控制寄存器,0X98//模式1波特率计算公式://fosc=晶振频率//SMOD=PCON 寄存器D7,当SMOD=1时,频率倍增//T1定时/计数器,TH1=计数器高8位,TL1=计数器低8位//BaudRate=((2^SMOD)/32)*(T1的溢出率);//T1的溢出率=fosc/(12*(256-TH1));//所以可以根据需要设置的波特率反向推导TH1/TL1//TH1=TL1=256-(fosc*2^SMOD)/(baudrate*12*32);//以下设置一个9600bps 波特率,并开始外部中断PCON=0X00; //SMOD=0TH1=0XFD; // 波特率9600bpTL1=0XFD;SCON = 0x50; // 工作方式1ES = 0; // 关闭串口中断IT0 = 0; // 外部中断0使用电平触发模式TMOD = 0x01;EX0 = 1;EA = 1;6. PCON: 0X87,51单片机借用SMOD 位作为波特率系数7.中断和定时器C例程//使用外部中断,当中断发生时向串口发送特定数据#include <reg51.h>#define uchar unsigned char#define uint unsigned intvoid GetTrigger(); //获取外部中断状态void Ex0Init();void SendBuff(uchar *buf,uchar len);void SendByte(uchar da);void main(void){Ex0Init();while(1);}void GetTrigger(void) interrupt 0{//当外部中断发生(如地感触发,ALARM IN 短接),向串口发送一个状态数据SendByte(0xdd);}void Ex0Init(){//初始化外部中断PCON = 0x00; // SMOD = 1TH1=0XFD; // 波特率9600bp=256-(FOSC*2^SMOD)/(baudrate*12*32)TL1=0XFD;SCON = 0x50; // 工作方式1ES = 0; // 关闭串口中断IT0 = 0; // 外部中断0使用电平触发模式TMOD = 0x01;EX0 = 1;EA = 1;}/* send one byte, no verify*/void SendByte(uchar da){TI=0;SBUF=da;while(!TI);TI=0;}/* to send a data buffer*/void SendBuff(uchar *buf,uchar len){uchar i;for(i=0;i<len;i++){SendByte(*buf);buf++;}while(!TI);TI = 0;}//使用定时器T0#include <at89x51.h>#define HI ((65536 - 50000) / 256)#define LO ((65536 - 50000) % 256)#define _TH0_TL0_ (65536 - 50000)#define M 20 //(1000/25)unsigned hou = 12, min = 0, sec = 0;//0-9数字unsigned char SEG_TAB_B[ ] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0.-9.数字unsigned char SEG_TAB_A[ ] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; void Delay(unsigned char a)//延时程序a*1MS{unsigned char j;while(a-- != 0){for (j = 0; j < 125; j++);}}//数码管显示void Disp(void){P2_0 = 1;P1 = SEG_TAB_B[ hou / 10 ];Delay(5);P2_0 = 0;P2_1 = 1;P1 = SEG_TAB_A[ hou % 10 ];Delay(5);P2_1 = 0;P2_2 = 1;P1 = SEG_TAB_B[ min / 10 ];Delay(5);P2_2 = 0;P2_3 = 1;P1 =SEG_TAB_A[ min % 10 ];Delay(5);P2_3 = 0;P2_4 = 1;P1 = SEG_TAB_B[ sec / 10 ];Delay(5);P2_4 = 0;P2_5 = 1;P1 = SEG_TAB_B[ sec % 10 ];Delay(5);P2_5 = 0;}//定时中断函数50msvoid IsrTimer0(void) interrupt 1 using 1{static unsigned char count = 0; //定义静态变量count count++;if(count == M){count = 0;sec++;if(sec == 60){min++;sec = 0;if(min == 60){hou++;min = 0;if(hou == 24){hou = 0;}}}}}void Timer0Init(void) //定时器0 {TMOD = 0x01;TH0 = HI;TL0 = LO;TR0 = 1;ET0 = 1;EA = 1;}//主函数void main(void){Timer0Init();while(1){Disp();}}。
51单片机串口中断与定时器中断共存同时使用
51单片机串口中断与定时器中断共存同时使用#include#include#define uchar unsigned char#define uint unsigned intsbit led1=P2^0;uchar SerialV alue; //串口接收到的值;uchar i;void main(){smglk=0;smgbitlk=0;ledlk=1;//----- Serial Port Setting -----TMOD=0x21; //设定定时器为方式2 可自动再装入的定时器SM0=0; //设定串口工作方式1 10位异步收发器8位数据SM1=1; //设定串口工作方式1 10位异步收发器8位数据TH1=0xfd;//装入初值TL1=0xfd; //装入初值PCON=0x00; //设定串行口波特率REN=1; //允许串行接收位。
REN=1,启动接收数据;REN=0,禁止接收。
IP=0x10;TH0=(65535-50000)/256;TL0=(65535-50000)%256;TR0=1; //启用T0定时器/计数器ET0=1; //T0定时器中断开关;(开)TR1=1; //启用T1定时器/计数器ET1=1; //T1定时器中断开关;(开)ES=1; //串行中断开关;(开) EA=1; //总中断开关;(开) SerialV alue=0x02;while(1){}}//串口中断void serial() interrupt 4 {SerialV alue=SBUF;RI=0;}void timer0() interrupt 1 {TH0=(65535-50000)/256; TL0=(65535-50000)%256; i++;if(i>SerialV alue){i=0;led1=!led1;}}。
第05章 MCS-51单片机的中断与定时(1-4)
2
1
TH0
;P1.0输出“0” ;P1.0输出“1”
5.2 MCS-51单片机的中断系统
五、外中断应用举例
1. 中断初始化程序
设置外中断源的触发方式 设置中断允许寄存器IE 设置中断优先级寄存器IP
2. 中断服务程序
保护现场 中断处理 恢复现场
23/65
5.2 MCS-51单片机的中断系统
【例5-3】 设外部中断0为下降沿触发方 式,高优先级,试编写中断初始化程序
5.2 MCS-51单片机的中断系统
【例5-4】 将单脉冲接到外中断0(INT0)引脚,利 用P1.0作为输出,经反相器接发光二极管。编写程 序,每按动一次按钮,产生一个外中断信号,使发 光二极管的状态发生变化,由亮变暗,或反之
P1.0 单脉冲 发生器 INT0
1
+5V
8031
26/65
5.2 MCS-51单片机的中断系统
串口:0023H
20/65
5.2 MCS-51单片机的中断系统
四、中断请求的撤除
1.定时/计数器中断请求标志TF0/TF1会自动撤除 2.串行口中断请求标志TI/RI要用指令撤除
CLR TI ;清TI标志位 CLR RI ;清RI标志位
3.负脉冲触发的外中断请求标志IE0/IE1会自动撤除 4.低电平触发的外中断请求信号需要外加电路撤除
下次课前请预习5.3节
30/65
5.3 51单片机的定时器/计数器
MCS-51单片机内部有两个16位定时/计数器 T0和T1,简称定时器0和定时器1
在特殊功能寄存器TMOD和TCON的控制下, 它们既可以设定成定时器使用,也可以设定 成计数器使用
定时/计数器有4种工作方式,具有中断功能, 可以完成定时、计数、脉冲输出等任务
51单片机实验——单片机定时与外部中断
实验题目:单片机定时与外部中断的作用1 一、实验目的1)熟悉单片机定时功能的使用2)熟悉外部中断的使用3)熟悉一些常用的C语言编程语句4)熟练单片机的一些使用及操作方法二、实验原理工作原理框图7_SEG_LED:8_BI Ts_LED:三、参考程序#include <reg51.h>#define FOSC 11059200L#define BAUD 9600#define TRUE 1#define FALSE 0int CmpCnt;int T0IntCnt;bit FlagTimerOk;unsigned char LedVal;sbit HC373_CLK = P3^6;sbit Int0=P3^2;sbit P1_4=P1^4;sbit P1_5=P1^5;sbit P1_6=P1^6;sbit P1_7=P1^7;unsigned char code a[10]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x19};void Init_T0(void){TMOD = 0x01; //T0 方式1TH0 = (65536-(FOSC)/1200)/256;TL0 = (65536-(FOSC)/1200)&0xff;ET0 = 1;TR0 = 1;}void Init_Uart(void){SCON = 0x50; //UART设置PCON = 0x80;TMOD = 0x21;TH1=0xfa; //定时器1设置TL1=0xfa;TR1=1;ES=1;EA=1;}void Init_INT0(void) interrupt 0 {int s;s=0;while(Int0==0)s++; //防抖设置if(s>100){if(CmpCnt>1)CmpCnt=CmpCnt-1;elseCmpCnt=50;s=0;}}void Init_Ram(void){T0IntCnt = 0;FlagTimerOk = FALSE;CmpCnt = 50;LedVal = 0xff;}void T0_ISR(void) interrupt 1{if(++T0IntCnt >= CmpCnt){T0IntCnt = 0;FlagTimerOk = TRUE;}TH0 =(65536-(FOSC)/1200)/256;TL0 =(65536-(FOSC)/1200)&0xff;TR0 = 1;ET0 = 1;EA = 1;}void LedCtrl(void){static int j=0;LedVal = 0xff & (~(1<<j));if(++j >= 8){j = 0;}P0 = LedVal;HC373_CLK = 1;HC373_CLK = 0;}void delay() //延时函数{int x,y;for(x=0;x<2;x++)for(y=0;y<120;y++);}void main(void){Init_Ram();Init_Uart();Init_T0();EX0=1;IT0=0;EA = 1;while(1){if(FlagTimerOk){FlagTimerOk = FALSE;LedCtrl();}P1_7=1;P1_5=0;P1_6=0;P1_4=0;P0=0x02;delay(); //七段数码管显示 P1_6=1;P1_4=0;P1_5=0;P1_7=0;P0=a[CmpCnt%10];delay(); P1_5=1;P1_4=0;P1_6=0;P1_7=0;P0=a[CmpCnt/10];delay();}}四、实验步骤1、启动Keil C,新建project;2、将写好的文件保存为.c文件;3、译生成hex文件后,用flash magic烧录到单片机中;4、片机复位上电,运行;5、按住INT0键,观察不同的数字显示对应LCD显示的变化;实验结果每按下INT0一次,数码管的显示示数减少10,从启动时的500一直减小到10,然后又恢复500,并且发光二极管的点亮时间和显示的一致,频率越高,LCD跑马灯跑得越快。
单片机中的中断与定时器的原理与应用
单片机中的中断与定时器的原理与应用在单片机(Microcontroller)中,中断(Interrupt)和定时器(Timer)是重要的功能模块,广泛应用于各种嵌入式系统和电子设备中。
本文将介绍中断和定时器的基本原理,并探讨它们在单片机中的应用。
一、中断的原理与应用中断是指在程序执行过程中,当发生某个特定事件时,暂停当前任务的执行,转而执行与该事件相关的任务。
这样可以提高系统的响应能力和实时性。
单片机中的中断通常有外部中断和定时中断两种类型。
1. 外部中断外部中断是通过外部触发器(如按钮、传感器等)来触发的中断事件。
当外部触发器发生状态变化时,单片机会响应中断请求,并执行相应的中断服务程序。
外部中断通常用于处理实时性要求较高的事件,如按键检测、紧急报警等。
2. 定时中断定时中断是通过定时器来触发的中断事件。
定时器是一种特殊的计时设备,可以按照设定的时间周期产生中断信号。
当定时器倒计时完成时,单片机会响应中断请求,并执行相应的中断服务程序。
定时中断常用于处理需要精确计时和时序控制的任务,如脉冲计数、PWM波形生成等。
中断的应用具体取决于具体的工程需求,例如在电梯控制系统中,可以使用外部中断来响应紧急停车按钮;在家电控制系统中,可以利用定时中断来实现定时开关机功能。
二、定时器的原理与应用定时器是单片机中的一个重要模块,可以用于计时、延时、频率测量等多种应用。
下面将介绍定时器的工作原理和几种常见的应用场景。
1. 定时器的工作原理定时器是通过内部时钟源来进行计时的。
它通常由一个计数器和若干个控制寄存器组成。
计数器可以递增或递减,当计数值达到设定值时,会产生中断信号或触发其他相关操作。
2. 延时应用延时是定时器最常见的应用之一。
通过设定一个合适的计时器参数,实现程序的精确延时。
例如,在蜂鸣器控制中,可以使用定时器来生成特定频率和持续时间的方波信号,从而产生不同的声音效果。
3. 频率测量应用定时器还可以用于频率测量。
51单片机中断程序例子
51单片机中断程序例子
1. 外部中断:当外部信号引脚检测到高电平时,单片机会触发外部中断服务程序。
可以利用外部中断实现按键扫描功能,当按键按下时,触发中断程序对按键进行处理。
2. 定时器中断:利用定时器中断可以实现精确的时间控制。
例如,我们可以设置定时器中断为1秒,当定时器溢出时,触发中断程序,实现1秒钟执行一次的任务。
3. 串口中断:当接收到串口数据时,单片机会触发串口中断服务程序,可以利用串口中断实现串口通信功能。
4. ADC中断:当模数转换器完成一次转换时,单片机会触发ADC中断服务程序,可以利用ADC中断实现模拟信号的采集和处理。
5. 看门狗中断:看门狗定时器溢出时,单片机会触发看门狗中断服务程序,可以利用看门狗中断实现系统复位或其他相关功能。
6. 外部中断优先级:当多个外部中断同时触发时,可以通过设置外部中断的优先级来确定触发的顺序和优先级。
7. 定时器中断优先级:当多个定时器中断同时触发时,可以通过设置定时器中断的优先级来确定触发的顺序和优先级。
8. 中断嵌套:单片机支持中断嵌套,即在一个中断服务程序中触发
另一个中断服务程序,可以通过中断嵌套实现复杂的任务处理。
9. 中断屏蔽:单片机支持对中断的屏蔽,即可以通过设置中断屏蔽标志位来屏蔽某些中断,使其暂时不被触发。
10. 中断标志位:单片机提供中断标志位,用于标识中断是否被触发。
在中断服务程序中,可以通过读取和清除中断标志位来判断中断是否发生。
以上是根据51单片机中断程序的例子进行的描述,这些例子涵盖了常见的中断类型和相关功能。
通过学习和理解这些例子,可以更好地掌握51单片机中断编程的原理和方法。
51单片机中断总结
51单片机中断总结:1. 查询优先级为固定的(外部中断0>定时器0>外部中断1>定时器1>串行中断)。
2. 执行优先级可以通过IP寄存器进行设置(高/低)。
3. CPU同时收到多个中断请求时,首先响应优先级较高者,然后相应优先级较低者;如果优先级相同,则按照查询优先级顺序依次响应。
4. 正在执行的中断服务,不能被同级或更低级的中断请求打断,但会被更高级的中断请求打断。
推论(1)高优先级的中断不能被任何其它中断所打断(2)低优先级的中断只能在没有任何中断服务运行时得到响应。
5. 对于定时器和外部中断,在进入中断服务后,其中断标志位会自动清零;对于串行中断,由于有两个中断源,需要手动查询并清零RI或/和TI。
if (RI) {// processingRI = 0;}if (TI) {// processingTI = 0;}6. 如果是使用汇编写中断服务,需要保护累加器、状态寄存器、寄存器组等8051 Tutorial: Interrupts/tutint.phpAs the name implies, an interrupt is some event which interrupts normal program execution.As stated earlier, program flow is always sequential, being altered only by those instructions which expressly cause program flow to deviate in some way. However, interrupts give us a mechanism to "put on hold" the normal program flow, execute a subroutine, and then resume normal program flow as if we had never left it. This subroutine, called an interrupt handler, is only executed when a certain event (interrupt) occurs. The event may be one of the timers "overflowing," receiving a character via the serial port, transmitting a character via the serialport, or one of two "external events." The 8051 may be configured so that when any of these events occur the main program is temporarily suspended and control passed to a special section of code which presumably would execute some function related to the event that occured. Once complete, control would be returned to the original program. The main program never even knows it was interrupted.The ability to interrupt normal program execution when certain events occur makes it much easier and much more efficient to handle certain conditions. If it were not for interrupts we would have to manually check in our main program whether the timers had overflown, whether we had received another character via the serial port, or if some external event had occured. Besides making the main program ugly and hard to read, such a situation would make our program inefficient since wed be burning precious "instruction cycles" checking for events that usually dont happen.For example, lets say we have a large 16k program executing many subroutines performing many tasks. Lets also suppose that we want our program to automatically toggle the P3.0 port every time timer 0 overflows. The code to do this isnt too difficult:JNB TF0,SKIP_TOGGLECPL P3.0CLR TF0SKIP_TOGGLE: ...Since the TF0 flag is set whenever timer 0 overflows, the above code will toggle P3.0 every time timer 0 overflows. This accomplishes what we want, but is inefficient. The JNB instruction consumes 2 instruction cycles to determine that the flag is not set and jump over the unnecessary code. In the event that timer 0 overflows, the CPL and CLR instruction require 2 instruction cycles to execute. To make the math easy, lets say the rest of the code in the program requires 98 instruction cycles. Thus, in total, our code consumes 100 instruction cycles (98 instruction cycles plus the 2 that are executed every iteration to determine whether or not timer 0 has overflowed). If were in 16-bit timer mode, timer 0 will overflow every 65,536 machine cycles. In that time we would have performed 655 JNB tests for a total of 1310 instruction cycles, plus another 2 instruction cycles to perform the code. So to achieve our goal weve spent 1312 instruction cycles. So 2.002% of our time is being spent just checking when to toggle P3.0. And our code is ugly because we have to make that check every iteration of our main program loop.Luckily, this isnt necessary. Interrupts let us forget about checking for the condition. The microcontroller itself will check for the condition automatically and when the condition is met will jump to a subroutine (called an interrupt handler), execute the code, then return. In this case, our subroutine would be nothing more than:CPL P3.0RETIFirst, youll notice the CLR TF0 command has disappeared. Thats because when the 8051 executes our "timer 0 interrupt routine," it automatically clears the TF0 flag. Youll also notice that instead of a normal RET instruction we have a RETI instruction. The RETI instruction does the same thing as a RET instruction, but tells the 8051 that an interrupt routine has finished. You must always end your interrupt handlers with RETI.Thus, every 65536 instruction cycles we execute the CPL instruction and the RETI instruction. Those two instructions together require 3 instruction cycles, and weve accomplished the same goal as the first example that required 1312 instruction cycles. As far as the toggling of P3.0 goes, our code is 437 times more efficient! Not to mention its much easier to read and understand because we dont have to remember to always check for the timer 0 flag in our main program. We just setup the interrupt and forget about it, secure in the knowledge that the 8051 will execute our code whenever its necessary.The same idea applies to receiving data via the serial port. One way to do it is to continuously check the status of the RI flag in an endless loop. Or we could check the RI flag as part of a larger program loop. However, in the latter case we run the risk of missing characters--what happens if a character is received right after we do the check, the rest of our program executes, and before we even check RI a second character has come in. We will lose the first character. With interrupts, the 8051 will put the main program "on hold" and call our special routine to handle the reception of a character. Thus, we neither have to put an ugly check in our main code nor will we lose characters.What Events Can Trigger Interrupts, and where do they go?We can configure the 8051 so that any of the following events will cause an interrupt:Timer 0 Overflow.Timer 1 Overflow.Reception/Transmission of Serial Character.External Event 0.External Event 1.In other words, we can configure the 8051 so that when Timer 0 Overflows or when a character is sent/received, the appropriate interrupt handler routines are called.Obviously we need to be able to distinguish between various interrupts and executing different code depending on what interrupt was triggered. This is accomplished by jumping to a fixed address when a given interrupt occurs.Interrupt Flag Interrupt Handler AddressExternal 0 IE0 0003hTimer 0 TF0 000BhExternal 1 IE1 0013hTimer 1 TF1 001BhSerial RI/TI 0023hBy consulting the above chart we see that whenever Timer 0 overflows (i.e., the TF0 bit is set), the main program will be temporarily suspended and control will jump to 000BH. It is assumed that we have code at address 000BH that handles the situation of Timer 0 overflowing.Setting Up InterruptsBy default at powerup, all interrupts are disabled. This means that even if, for example, the TF0 bit is set, the 8051 will not execute the interrupt. Your program must specifically tell the 8051 that it wishes to enable interrupts and specifically which interrupts it wishes to enable.Your program may enable and disable interrupts by modifying the IE SFR (A8h):Bit Name Bit Address Explanation of Function7 EA AFh Global Interrupt Enable/Disable6 - AEh Undefined5 - ADh Undefined4 ES ACh Enable Serial Interrupt3 ET1 ABh Enable Timer 1 Interrupt2 EX1 AAh Enable External 1 Interrupt1 ET0 A9h Enable Timer 0 Interrupt0 EX0 A8h Enable External 0 InterruptAs you can see, each of the 8051s interrupts has its own bit in the IE SFR. You enable a given interrupt by setting the corresponding bit. For example, if you wish to enable Timer 1 Interrupt, you would execute either:MOV IE,#08horSETB ET1Both of the above instructions set bit 3 of IE, thus enabling Timer 1 Interrupt. Once Timer 1 Interrupt is enabled, whenever the TF1 bit is set, the 8051 will automatically put "on hold" the main program and execute the Timer 1 Interrupt Handler at address 001Bh.However, before Timer 1 Interrupt (or any other interrupt) is truly enabled, you must also set bit 7 of IE. Bit 7, the Global Interupt Enable/Disable, enables or disables all interrupts simultaneously. That is to say, if bit 7 is cleared then no interrupts will occur, even if all the other bits of IE are set. Setting bit 7 will enable all the interrupts that have been selected by setting other bits in IE. This is useful in program execution if you have time-critical code that needs to execute. In this case, you may need the code to execute from start to finish without any interrupt getting in the way. To accomplish this you can simply clear bit 7 of IE (CLR EA) and then set it after your time-criticial code is done.So, to sum up what has been stated in this section, to enable the Timer 1 Interrupt the most common approach is to execute the following two instructions:SETB ET1SETB EAThereafter, the Timer 1 Interrupt Handler at 01Bh will automatically be called whenever the TF1 bit is set (upon Timer 1 overflow).Polling SequenceThe 8051 automatically evaluates whether an interrupt should occur after every instruction. When checking for interrupt conditions, it checks them in the following order:External 0 InterruptTimer 0 InterruptExternal 1 InterruptTimer 1 InterruptSerial InterruptThis means that if a Serial Interrupt occurs at the exact same instant that an External 0 Interrupt occurs, the External 0 Interrupt will be executed first and the Serial Interrupt will be executed once the External 0 Interrupt has completed.Interrupt PrioritiesThe 8051 offers two levels of interrupt priority: high and low. By using interrupt priorities you may assign higher priority to certain interrupt conditions.For example, you may have enabled Timer 1 Interrupt which is automatically called every time Timer 1 overflows. Additionally, you may have enabled the Serial Interrupt which is called every time a character is received via the serial port. However, you may consider that receiving a character is much more important than the timer interrupt. In this case, if Timer 1 Interrupt is already executing you may wish that the serial interrupt itself interrupts the Timer 1 Interrupt. When the serial interrupt is complete, control passes back to Timer 1 Interrupt and finally back to the main program. You may accomplish this by assigning a high priority to the Serial Interrupt and a low priority to the Timer 1 Interrupt.Interrupt priorities are controlled by the IP SFR (B8h). The IP SFR has the following format:Bit Name Bit Address Explanation of Function7 - - Undefined6 - - Undefined5 - - Undefined4 PS BCh Serial Interrupt Priority3 PT1 BBh Timer 1 Interrupt Priority2 PX1 BAh External 1 Interrupt Priority1 PT0 B9h Timer 0 Interrupt Priority0 PX0 B8h External 0 Interrupt PriorityWhen considering interrupt priorities, the following rules apply:Nothing can interrupt a high-priority interrupt--not even another high priority interrupt.A high-priority interrupt may interrupt a low-priority interrupt.A low-priority interrupt may only occur if no other interrupt is already executing.If two interrupts occur at the same time, the interrupt with higher priority will execute first. If both interrupts are of the same priority the interrupt which is serviced first by polling sequence will be executed first.What Happens When an Interrupt Occurs?When an interrupt is triggered, the following actions are taken automatically by the microcontroller:The current Program Counter is saved on the stack, low-byte first.Interrupts of the same and lower priority are blocked.In the case of Timer and External interrupts, the corresponding interrupt flag is cleared.Program execution transfers to the corresponding interrupt handler vector address.The Interrupt Handler Routine executes.Take special note of the third step: If the interrupt being handled is a Timer or External interrupt, the microcontroller automatically clears the interrupt flag before passing control to your interrupt handler routine. This means it is not necessary that you clear the bit in your code.What Happens When an Interrupt Ends?An interrupt ends when your program executes the RETI (Return from Interrupt) instruction. When the RETI instruction is executed the following actions are taken by the microcontroller:Two bytes are popped off the stack into the Program Counter to restore normal program execution.Interrupt status is restored to its pre-interrupt status.Serial InterruptsSerial Interrupts are slightly different than the rest of the interrupts. This is due to the fact that there are two interrupt flags: RI and TI. If either flag is set, a serial interrupt is triggered. As you will recall from the section on the serial port, the RI bit is set when a byte is received by the serial port and the TI bit is set when a byte has been sent.This means that when your serial interrupt is executed, it may have been triggered because the RI flag was set or because the TI flag was set--or because both flags were set. Thus, your routine must check the status of these flags to determine what action is appropriate. Also, since the 8051 does not automatically clear the RI and TI flags you must clear these bits in your interrupt handler.A brief code example is in order:INT_SERIAL: JNB RI,CHECK_TI ;If the RI flag is not set, we jump to check TIMOV A,SBUF ;If we got to this line, its because the RI bit *was* setCLR RI ;Clear the RI bit after weve processed itCHECK_TI: JNB TI,EXIT_INT ;If the TI flag is not set, we jump to the exit pointCLR TI ;Clear the TI bit before we send another characterMOV SBUF,#A ;Send another character to the serial portEXIT_INT: RETIAs you can see, our code checks the status of both interrupts flags. If both flags were set, both sections of code will be executed. Also note that each section of code clears its corresponding interrupt flag. If you forget to clear the interrupt bits, the serial interrupt will be executed over and over until you clear the bit. Thus it is very important that you always clear the interrupt flags in a serial interrupt.Important Interrupt Consideration: Register ProtectionOne very important rule applies to all interrupt handlers: Interrupts must leave the processor in the same state as it was in when the interrupt initiated.Remember, the idea behind interrupts is that the main program isnt aware that they are executing in the "background." However, consider the following code:CLR C ;Clear carryMOV A,#25h ;Load the accumulator with 25hADDC A,#10h ;Add 10h, with carryAfter the above three instructions are executed, the accumulator will contain a value of 35h.But what would happen if right after the MOV instruction an interrupt occured. During this interrupt, the carry bit was set and the value of the accumulator was changed to 40h. When the interrupt finished and control was passed back to the main program, the ADDC would add 10h to 40h, and additionally add an additional 1h because the carry bit is set. In this case, the accumulator will contain the value 51h at the end of execution.In this case, the main program has seemingly calculated the wrong answer. How can 25h + 10h yield 51h as a result? It doesnt make sense. A programmer that was unfamiliar with interrupts would be convinced that the microcontroller was damaged in some way, provoking problems with mathematical calculations.What has happened, in reality, is the interrupt did not protect the registers it used. Restated: An interrupt must leave the processor in the same state as it was in when the interrupt initiated.What does this mean? It means if your interrupt uses the accumulator, it must insure that the value of the accumulator is the same at the end of the interrupt as it was at the beginning. This is generally accomplished with a PUSH and POP sequence. For example:PUSH ACCPUSH PSWMOV A,#0FFhADD A,#02hPOP PSWPOP ACCThe guts of the interrupt is the MOV instruction and the ADD instruction. However, these two instructions modify the Accumulator (the MOV instruction) and also modify the value of the carry bit (the ADD instruction will cause the carry bit to be set). Since an interrupt routine must guarantee that the registers remain unchanged by the routine, the routine pushes the original values onto the stack using the PUSH instruction. It is then free to use the registers it protected to its hearts content. Once the interrupt has finished its task, it pops the original values back into the registers. When the interrupt exits, the main program will never know the difference because the registers are exactly the same as they were before the interrupt executed.In general, your interrupt routine must protect the following registers:PSWDPTR (DPH/DPL)PSWACCBRegisters R0-R7Remember that PSW consists of many individual bits that are set by various 8051 instructions. Unless you are absolutely sure of what you are doing and have a complete understanding of what instructions set what bits, it is generally a good idea to always protect PSW by pushing and popping it off the stack at the beginning and end of your interrupts.Note also that most assemblers (in fact, ALL assemblers that I know of) will not allow you to execute the instruction:PUSH R0This is due to the fact that depending on which register bank is selected, R0 may refer to either internal ram address 00h, 08h, 10h, or 18h. R0, in and of itself, is not a valid memory address that the PUSH and POP instructions can use.Thus, if you are using any "R" register in your interrupt routine, you will have to push that registers absolute address onto the stack instead of just saying PUSH R0. For example, instead of PUSH R0 you would execute:PUSH 00hOf course, this only works if youve selected the default register set. If you are using an alternate register set, you must PUSH the address which corresponds to the register you are using.Common Problems with InterruptsInterrupts are a very powerful tool available to the 8051 developer, but when used incorrectly they can be a source of a huge number of debugging hours. Errors in interrupt routines are often very difficult to diagnose and correct.If you are using interrupts and your program is crashing or does not seem to be performing as you would expect, always review the following interrupt-related issues:Register Protection: Make sure you are protecting all your registers, as explained above. If you forget to protect a register that your main program is using, very strange results may occur. In our example above we saw how failure to protect registers caused the main program to apparently calculate that 25h + 10h = 51h. If you witness problems with registers changing values unexpectedly or operations producing "incorrect" values, it is very likely that you've forgotten to protect registers. ALWAYS PROTECT YOUR REGISTERS.Forgetting to restore protected values: Another common error is to push registers onto the stack to protect them, and then forget to pop them off the stack before exiting the interrupt. For example, you may push ACC, B, and PSW onto the stack in order to protect them and subsequently pop only ACC and PSW off the stack before exiting. In this case, since you forgot to restore the value of "B", an extra value remains on the stack. When you execute the RETI instruction the 8051 will use that value as the return address instead of the correct value. In this case, your program will almost certainly crash. ALWAYS MAKE SURE YOU POP THE SAME NUMBER OF VALUES OFF THE STACK AS YOU PUSHED ONTO IT.Using RET instead of RETI: Remember that interrupts are always terminated with the RETI instruction. It is easy to inadvertantly use the RET instruction instead. However, the RETinstruction will not end your interrupt. Usually, using a RET instead of a RETI will cause the illusion of your main program running normally, but your interrupt will only be executed once. If it appears that your interrupt mysteriously stops executing, verify that you are exiting with RETI.11。
51单片机每个外部中断和定时器中断 应用模版
第一步,中断配置/************************************************************函数名:INT0_Config功能:配置单片机与中断相关的硬件,让单片机能够正常检测中断和执行中断代码。
输入参数:输出参数:************************************************************/void INT0_Config(void){IT0=1; //中断触发方式,IT0=0,低电平触发,INT0=1下降沿触发(下降沿就是由高电平向低电平的跳变);EX0=1; //外部中断0的中断开关,每个中断源都有自己的中断开关。
EA=1; //打开总中断,如果总中断不打开,就是其他中断开关被打开,单片机也不能执行中断。
}第二步,中断服务,也就是cpu被中断后所要做的事。
/************************************************************函数名:Isr_INT0功能:中断服务输入参数:输出参数:************************************************************/void Isr_INT0() interrupt 0 //interrupt表明该函数是中断函数,后面的标号表示是哪个中断源产生的中断。
{ //(INT0)为0, Timer0为1,INT1为2,Timer3,串口中断为4。
// Add your code here //自己想要中断后发生的程序}第三部主函数/************************************************************函数名:main功能:主函数输入参数:输出参数:************************************************************/void main(){INT0_Config();//调用这个函数来配置外部中断while(1){//Add your code here//CPU一直在这里循环的执行代码,一旦发生中断,就停下来去执行中断函数Isr_INT0() interrupt 0,//执行完成后,返回从断点处继续往下执行原来的代码。
中断及定时器实验报告
一、实验目的1. 理解中断和定时器的基本概念及工作原理。
2. 掌握51单片机中断系统和定时器的配置方法。
3. 学会使用中断和定时器实现特定功能,如延时、计数等。
4. 培养动手实践能力和问题解决能力。
二、实验原理中断是计算机系统中的一种机制,允许CPU在执行程序过程中,暂停当前程序,转去执行另一个具有更高优先级的程序。
51单片机具有5个中断源,包括两个外部中断(INT0、INT1)、两个定时器中断(定时器0、定时器1)和一个串行口中断。
定时器是51单片机内部的一种计数器,可以用于产生定时中断或实现定时功能。
51单片机有两个定时器,即定时器0和定时器1。
定时器可以工作在模式0、模式1、模式2和模式3。
三、实验内容及步骤1. 实验内容一:外部中断实验(1)实验目的:掌握外部中断的使用方法,实现按键控制LED灯的亮灭。
(2)实验步骤:- 使用Keil for 8051编译器创建项目。
- 根据电路原理图连接电路。
- 编写程序,配置外部中断,实现按键控制LED灯的亮灭。
2. 实验内容二:定时器中断实验(1)实验目的:掌握定时器中断的使用方法,实现LED灯闪烁。
(2)实验步骤:- 使用Keil for 8051编译器创建项目。
- 根据电路原理图连接电路。
- 编写程序,配置定时器中断,实现LED灯闪烁。
3. 实验内容三:定时器与外部中断结合实验(1)实验目的:掌握定时器与外部中断结合使用的方法,实现按键控制LED灯闪烁频率。
(2)实验步骤:- 使用Keil for 8051编译器创建项目。
- 根据电路原理图连接电路。
- 编写程序,配置定时器中断和外部中断,实现按键控制LED灯闪烁频率。
四、实验结果与分析1. 外部中断实验:成功实现了按键控制LED灯的亮灭。
当按下按键时,LED灯亮;松开按键时,LED灯灭。
2. 定时器中断实验:成功实现了LED灯闪烁。
LED灯每隔一定时间闪烁一次,闪烁频率可调。
3. 定时器与外部中断结合实验:成功实现了按键控制LED灯闪烁频率。
51单片机外部中断详解-(最新版)
一.外部中断相关寄存器1.定时器/计数器控制寄存器控制寄存器(TCON)IT0:外部中断0触发方式控制位当IT0=0时,为电平触发方式(低电平有效)当IT0=1时,为边沿触发方式(下降沿有效)IT1:外部中断1触发方式控制位当IT1=0时,为电平触发方式(低电平有效)当IT1=1时,为边沿触发方式(下降沿有效)2.中断允许控制寄存器(IE)EX0:外部中断0允许位;EX1:外部中断1允许位;EA :CPU中断允许(总允许)位。
二.外部中断的处理过程1、设置中断触发方式,即IT0=1或0,IT1=1或02、开对应的外部中断,即EX0=1或EX1=1;3、开总中断,即EA=1;4、等待外部设备产生中断请求,即通过,口连接外部设备产生中断5、中断响应,执行中断服务函数三.程序编写要求:通过两位按键连接外部中断0和1,设定外部中断0为下降沿触发方式,外部中断1为低电平触发方式,按键产生中断使数字加减,用一位共阳极数码管来显示数值。
目的:感受外部中断对程序的影响,体会低电平触发和下降沿触发的区别。
#include<>#define uint unsigned int #define uchar unsigned char uchar code dat[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};uint num;void main(){EA=1; //开总中断IT0=1; //下降沿触发IT1=0; //低电平触发EX0=1; //外部中断0允许EX1=1; //外部中断1允许while(1){P0=dat[num%10];}}void plus() interrupt 0//外部中断0 {EX0=0;num++;EX0=1;}void minus() interrupt 2//外部中断1{EX1=0;num--;EX1=1;}。
51单片机的定时器中断
51单⽚机的定时器中断⼀、中断的概念CPU在处理某⼀事件A时,发⽣了另⼀事件B请求CPU迅速去处理(中断产⽣);CPU暂时中断当前的⼯作,转去处理事件B(中断响应和中断服务);待CPU将事件B处理完毕后,再回到原来事件A中断的地⽅继续处理事件A(中断返回),这⼀过程称为中断。
⼆、中断的优先级51单⽚机⾥⼀共有5个中断源,分别是外部中断0,定时器0,外部中断1,定时器1,串⼝中断,中断优先级从⼤到⼩分别是0,1,2,3,4。
三、中断的优点1.分时操作。
CPU可以分时为多个I/O设备服务,提⾼了计算机的利⽤率;2.实时响应。
CPU能够及时处理应⽤系统的随机事件,系统的实时性⼤⼤增强;3.可靠性⾼。
CPU具有处理设备故障及掉电等突发性事件能⼒,从⽽使系统可靠性⾼。
四、定时器中断⼯作⽅式寄存器TMOD:GATE:门控位。
GATE=0时,只要⽤软件使TCON中的TR0或TR1为1,就可以启动定时/计数器⼯作;GATA=1时,要⽤软件使TR0或TR1为1,同时外部中断引脚或也为⾼电平时,才能启动定时/计数器⼯作。
即此时定时器的启动多了⼀个条件。
(默认情况下等于0不要设置)。
C/T:定时/计数模式选择位。
=0为定时模式;=1为计数模式。
M1M0:⼯作⽅式设置位。
定时/计数器有四种⼯作⽅式,由M1M0进⾏设置。
(正常情况旋⽅式1,即M1M0=01)。
中断寄存器:EA是总中断,ET0是定时器0中断,EX0是外部中断0,ET1是定时器1中断,EX1是外部中断1。
【参考资料】51单⽚机第⼆讲(定时器中断)。
单片机中的中断与定时器的应用
单片机中的中断与定时器的应用在单片机的应用中,中断和定时器是非常重要的功能模块。
它们可以帮助我们实现各种需要时间控制或者事件触发的任务。
本文将详细介绍单片机中中断和定时器的应用,并讨论它们在实际项目中的一些常见用法。
首先,让我们来了解一下中断的概念。
中断是指在程序执行过程中,突然发生的某个事件打断了正常的执行流程。
这种事件可能是外部输入、定时器超时或者其他外部设备的状态改变。
中断可以帮助我们快速地响应这些事件,并执行相应的处理程序。
在单片机中,中断通常由硬件触发,并通过中断向量来识别具体的中断源。
每个中断源都有一个中断向量地址,当中断发生时,CPU会将当前执行的指令地址保存下来,并跳转到相应的中断向量地址执行中断服务程序。
中断服务程序是用户预先定义的程序片段,用于处理中断事件。
单片机中的定时器是一种特殊的计时模块。
它可以帮助我们精确测量时间间隔,并执行相应的操作。
定时器通常有一个或多个计数器组成,每个计数器都有一个时钟源,并且可以设置计数器的起始值和计数模式。
当计数器达到指定的值时,会产生一个中断或者触发外部事件。
中断和定时器常常结合使用,以实现一些需要定时操作或者及时响应的功能。
例如,我们可以使用定时器来定时发送脉冲信号,然后通过中断来接收这些信号并进行相应的处理。
这在一些实时控制系统中非常常见。
另一个常见的用法是使用定时器来检测某个事件是否发生,并在事件发生时触发中断。
例如,我们可以使用定时器来定时检测按键是否被按下,当按键被按下时,定时器会触发中断,并执行相应的按键处理程序。
这种方法可以避免频繁地轮询按键状态,从而节省了系统资源。
在实际项目中,中断和定时器还可以用于实现一些周期性的任务。
例如,我们可以使用定时器来触发一个周期性中断,然后在中断服务程序中执行周期性任务。
这种方法可以帮助我们实现周期性的数据采集、通信协议等功能。
此外,中断和定时器还可以用于实现多任务系统。
通过使用定时器和中断,我们可以周期性地切换任务,并在每个任务中执行相应的操作。
第一篇:51单片机的中断和定时
第一篇:51单片机的中断和定时自学51单片机也有两个星期了,今天第一次写关于51的博客,也是因为感觉定时和中断挺重要的,要记录一下了。
定时器/计数器51的定时器/计数器有2个分别是T1和T0,52系列的单片机有3个定时器/计数器,T0和T1是通用定时器/计数器,定时器/计数器2(简称T2)是集定时、计数和捕获三种功能于一体,功能更强。
首先看一下这个简单点的功能,我在实验中用到的定时器的作用是高精度延时的作用,之前使用的通过while和for循环的延时方法都只是大概的时间,而定时器则可以精确设定时间在1微秒(10^-6)左右(以晶振频率为11.0592MHZ来说),其最大的时间取值为0.071,可见已经可以达到钟表的误差水准了。
定时器/计数器0和1的方式控制寄存器TMOD:T1 T0T1和T0分别代表单片机两个计数器GATE:门控制位。
当门控制位GATE=1时,定时器/计数器的运行受外部引脚输入电平的控制。
其中INT0引脚控制T0,INT1引脚控制T1.当控制引脚为高电平且TR0或TR1置1时,相应的定时器/计数器才被选通。
当门控制位GATE=0时,只要TR0或TR1置1,相应的定时器/计数器就被选通,此时不受外部引脚的控制。
C/T:该位为0的时候,用作定时器,该位为1的时候,用做计数器。
TH1)和一个具有32为分频的低8位计数器中的(TL0或TL1)的低5位(0~4)组合成。
模式1:16位的计数器。
(TH1,TL1)模式2:自动装载8位计数器。
主要应用在串口波特率发生器。
模式3:将16位计数器分成两个独立的8位计数器TL0和TH0.定时器/计数器的工作模式3只适用于 T0.模式0&模式3:几乎不用。
特殊功能寄存器TCONT1 T0 定时中断溢出标志位TF1/TF0:当定时器T1/T0溢出时,硬件自动将TF0/TF1置1,并申请中断。
当进入中断服务程序时,硬件又将自动清零TF1/TF0.启/停控制位TR1/TR0:该位由软件置位和复位。
51单片机中断与定时器
也就是由单片机的晶体震荡器经过12分频后获得的一个脉 冲源(机器周期)。晶振的频率是很准确的,所以这个计 数脉冲的时间间隔也很准。一个12M的晶振,它供给给计 数器的脉冲时间间隔是1微秒。计数脉冲的间隔与晶振有 关,12M的晶振,计数脉冲的间隔是1微秒。
这是逻辑图,可以看到T1是一个单刀双掷开关,说明定一个定时/计数器 同一时刻要么作定时用,要么作计数用,不能同时用; 接通T1引脚时作为外部计数用。(T0的引脚是P3.4,T1的引脚是P3.5)。
手机
一开始你正在看我的视频教程
手机铃声响了 提醒你去接 你准备去接电话 在电脑上暂停我的这个视频教程 你开始接电话 挂断电话 回来 继续看我的视频教程
③开放中断
④保护现场
⑤中断服务
⑥恢复现场
⑦中断返回
AT89S52单片机的中断源及TCON S52系列有6个中断源(比S51多一个T2) 2个外部中断请求:INT0,INT1 3个片内定时器/计数器T0和T1中断请求: TF0,TF1,(TF2) 1个串行口中断请求:TI/RI
中断允许寄存器IE (0A8H)
IE
EA — ET2 ES ET1 EX1 ET0 EX0
EX0/EX1/ET1/ET0/ES 位: 分别是INT0/1,Timer0/1,串行口的中断允 许控制位: =0 时禁止中断; =1 时允许中断。 ET2:T2中断允许控制位(仅52系列有) =0 时禁止中断; =1 时允许中断。 EA:总的中断允许控制位(总开关): =0 时禁止全部中断;=1 时允许中断。
EA位
IP寄存器
中断源 标志位
中断入口
注:各中断允许控制位=0,开关断开; =1,开关接通
中断优先级控制寄存器IP
51单片机中断程序例子
51单片机中断程序例子1. 外部中断程序:外部中断是指由外部设备或外部信号触发的中断。
在51单片机中,通过设置中断允许位和中断优先级来实现对外部中断的响应。
例如,当外部设备发出一个信号时,单片机可以立即停止当前任务,转而执行外部中断程序。
外部中断程序的编写需要根据具体的外部设备和信号进行相应的处理,如读取设备状态、处理数据等。
通过外部中断程序,可以实现单片机与外部设备的互动和数据交换。
2. 定时器中断程序:定时器中断是指通过设置定时器的计数值和中断允许位,使得在指定的时间间隔内触发中断。
在51单片机中,可以通过定时器中断来实现定时任务的执行。
例如,可以设置一个定时器,在每隔一定的时间就触发中断,然后在中断程序中执行相应的任务,如数据采集、数据处理等。
通过定时器中断程序,可以实现定时任务的自动执行,提高系统的实时性和可靠性。
3.串口中断程序:串口中断是指通过串口通信接口接收或发送数据时触发的中断。
在51单片机中,可以通过设置串口中断允许位和中断优先级来实现对串口数据的中断处理。
例如,当接收到一个完整的数据包时,单片机可以立即停止当前任务,转而执行串口中断程序,对接收到的数据进行处理。
通过串口中断程序,可以实现单片机与外部设备的数据交换和通信。
4. ADC中断程序:ADC(模数转换器)中断是指在进行模数转换时触发的中断。
在51单片机中,可以通过设置ADC中断允许位和中断优先级来实现对模数转换结果的中断处理。
例如,当模数转换完成后,单片机可以立即停止当前任务,转而执行ADC中断程序,对转换结果进行处理和分析。
通过ADC中断程序,可以实现对模拟信号的采集和处理,用于实时监测和控制。
5. 外部中断优先级设置:在51单片机中,可以通过设置外部中断的中断优先级来确定中断的响应顺序。
中断优先级越高,优先级越高的中断会先被响应。
通过合理设置中断优先级,可以确保关键任务的及时响应和执行。
例如,当多个外部设备同时发出中断信号时,可以通过设置优先级,确保先响应优先级高的设备,保证系统的正常运行。
51单片机定时器计数器、外部、串行中断服务控制字(详版)
51单片机定时器0中断服务51单片机定时器0工作在模式0,每中断10次,使P2.0引脚连接的LED灯闪烁。
#include "reg_c51.h"int nn; //中断次数变量中断服务程序中计数count++时,count应在void main()外定义为全局变量!!!void main(void){//TMOD=0x0F;TMOD &= 0xF0; //定时器0运行在模式0 ,13位计数器// GATE0=0; C/T0#=0; M1=0; M0=0;TH0 = 0x00; //设置初值0x00,所以计数值为8192(213),若是时钟频率为12MHzTL0 = 0x00; //则8192μs中断一次(定时器每计数一次1μs,8192次即8192μs)ET0=1; //允许定时器0中断EA=1; //允许总中断TR0=1; //启动定时器0while(1); //无限循环,没有循环体}void it_timer0(void) interrupt 1 定时器0中断服务程序{nn=nn++; //每次中断nn加1if(nn==10) //当中断10次后,使LED灯闪烁{ nn=0;P2_0 = ~P2_0; //引脚P2.0取反}}①IT0(IT1):外部中断0(或1)置0:电平触发置1:边沿触发②IE0(IE1):外部中断标志硬件置位③TF0(TF1):定时器0(或1)溢出中断标志(通常用于查询方式)当T0(T1)被允许计数后,T1(T0)从初始值开始加1计数,最高位产生溢出时,该位由内部硬件置位,并向CPU请求申请中断。
当CPU响应时,由硬件清零。
硬件置位硬件清零④TR0(TR1):定时器/计数器T1(T0)的运行控制位置0:关闭定时器/计数器置1:启动定时器/计数器TMOD高4位:定时器1(1)M1M0:工作方式0 0 方式0:13位定时器/计数器0 1 方式1:16位定时器/计数器1 0 方式2:自动重装8位定时器/计数器1 1 方式3:仅适用于T0,分为两个8位定时器/计数器方式0:M=213=8192方式1:M=216=65536方式2:M=28=256方式3:定时器0分成两个8位计数器,所以两个定时器的M值均为256(2)C/T:计数器/定时器0:定时器1:计数器(3)GA TE:门控位GA TE=0时,只要TRi=1,定时器/计数器就开始工作,称为软启动。
51单片机串口中断的两种写法
单片机串口通信在嵌入式系统中具有非常重要的作用,而其中串口中断的编写方式更是至关重要。
今天我们来讨论一下51单片机串口中断的两种写法。
1. 外部中断写法在51单片机中,串口通信一般使用串口中断来实现。
外部中断写法是一种常见的串口中断编写方式。
其具体步骤如下:1)需要设置串口工作参数,包括波特率、数据位、停止位和校验位等。
2)在主程序中使能串口中断,并设置中断优先级。
3)在中断服务函数中进行接收数据的处理,可以通过接收缓冲区、中断标志位等来判断接收数据的情况,并进行相应的处理。
2. 定时器中断写法除了外部中断写法,定时器中断也是一种常见的串口中断编写方式。
其具体步骤如下:1)同样需要设置串口工作参数,包括波特率、数据位、停止位和校验位等。
2)在主程序中初始化定时器,并使能定时器中断。
3)在定时器中断服务函数中进行接收数据的处理,同样可以通过接收缓冲区、中断标志位等来判断接收数据的情况,并进行相应的处理。
总结无论是外部中断写法还是定时器中断写法,都是实现51单片机串口通信的常见方式。
在选择具体的编写方式时,需要根据具体的应用场景和需求来进行选择。
在实际应用中,可以根据具体情况来灵活选择合适的串口中断编写方式,以便更好地满足系统的需求。
在实际编写中断服务函数时,需要注意以下几点:1)处理数据时需要考虑数据的完整性和准确性,可以通过校验位等手段来验证数据的正确性。
2)在中断服务函数中应尽量减少对全局变量的访问,以避免出现数据冲突和竞争的情况。
3)合理设置中断优先级,避免产生中断嵌套和冲突。
通过合理的中断编写方式和注意事项,可以更好地实现串口通信功能,提高系统的稳定性和可靠性,为嵌入式系统的应用提供良好的技术支持。
对于外部中断写法和定时器中断写法,两者各有优缺点。
外部中断写法在串口数据到达时能够即刻响应中断、处理数据。
但是,如果数据传输速率较快或需要高精度的数据处理,外部中断写法可能无法满足要求。
在这种情况下,定时器中断写法显得更加合适。
51单片机(STC89C52)的中断和定时器
51单⽚机(STC89C52)的中断和定时器STC89C51/STC89C52 Timer内部不带振荡源, 必须外接晶振采⽤11.0592MHz,或22.1184MHz,可⽅便得到串⼝通讯的标准时钟.STC89和STC90系列为12T, STC11/STC12系列为1T, 也就是⼀个指令⼀个机器周期, 这些都需要外置晶振; STC15系列有内置晶振.中断中断允许控制寄存器 IE字节地址A8H, CPU对中断系统所有中断以及某个中断源的开放和屏蔽是由中断允许寄存器IE控制的D7D6D5D4D3D2D1D0EA—ET2ES ET1EX1ET0EX0EA (IE.7): 整体中断允许位, 1:允许ET2(IE.5): T2中断允许位, 1:允许(for C52)ES (IE.4): 串⼝中断允许位, 1:允许ET1(IE.3): T1中断允许位, 1:允许EX1(IE.2): 外部中断INT1允许位, 1:允许ET0(IE.1): T0中断允许位, 1:允许EX0(IE.0): 外部中断INT0允许位, 1:允许52单⽚机⼀共有6个中断源, 它们的符号, 名称以及各产⽣的条件分别如下1. INT0 - 外部中断0, 由P3.2端⼝线引⼊, 低电平或下降沿引起2. INT1 - 外部中断1, 由P3.3端⼝线引⼊, 低电平或下降沿引起3. T0 - 定时器/计数器0中断, 由T0计数器计满回零引起4. T1 - 定时器/计数器1中断, 由T1计数器计满回零引起5. T2 - 定时器/计数器2中断, 由T2计数器计满回零引起 <--这个是52特有的6. TI/RI - 串⾏⼝中断, 串⾏端⼝完成⼀帧字符发送/接收后引起定时器中断51单⽚机内部共有两个16位可编程的定时器,即定时器T0和定时器T1, 52单⽚机内部多⼀个T2定时器. 它们既有定时功能,也有计数功能。
可通过设置与它们相关的特殊功能寄存器选择启⽤定时功能还是计数功能. 这个定时器系统是单⽚机内部⼀个独⽴的硬件部分,它与CPU和晶振通过内部某些控制线连接并相互作⽤,CPU⼀旦设置开启定时功能后,定时器便在晶振的作⽤下⾃动开始计时,但定时器的计数器计满后,会产⽣中断。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
中断使能寄存器
通过设置中断使能寄存器 IE 的 EA 位 使能所有中断 每个中断源都有单独的使能位 可通过软件设置 IE 中相应的使能位在任何时候使能或禁能中断 中断使能寄存器 IE 的各 位如下所示
中断使能寄存器IE
位地址 0AFH 0AEH 0ADH 0ACH 0ABH 0AAH 0A9H 0A8H 位符号 EA
/ ET2 ES
ET1 EX1 ET0 EX0
EA 使能标志位 置位则所有中断使能 复位则禁止所有中断保留 ET2 定时器2 中断使能 ES 串行通信中断使能 ET1 定时器 1 中断使能 EX1 外部中断 1 使能 ET0 定时器0 中断使能 EX0 外部中断 0使能
8051 支持两个中断优先级 有标准的中断机制, 低优先级的中断只能被高优先级的中断所中断 ,而高优先级的中断不能被中断。
中断优先级寄存器
每个中断源都可通过设置中断优先级寄存器IP 来单独设置中断优先级 如果每个中断源的相应位被置位 则该中断源的优先级为高,如果相应的位被复位, 则该中断源的优先级为低, 如果你觉得两个中断源不够用 ,别急以后我会教你如何增加中断优先级 表 A-5 示出了 IP 寄存器的各位 此寄存器可位寻址 IP 寄存器
位地址 0BFH 0BEH 0BDH 0BCH 0BBH 0BAH 0B9H 0B8H 位符号 /
/
/ PS PT1 PX1 PT0 PX0
编号 中断源
中断向量
上电复位 0000H 0 外部中断0 0003H 1 定时器0溢出 000BH 2 外部中断1 0013H 3 定时器1溢出 001BH 4 串行口中断 0023H 5
定时器2溢出 002BH
PT2 定时器 2中断优先级 PS 串行通信中断优先级 PT1 定时器 1中断优先级 PX1 外部中断1 优先级 PT0 定时器0中断优先级 PX0 外部中断0 优先级
定时器控制寄存器 TCON
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 TF1 定时器1溢出中断标志响应中断后由处理器清零
TR1 定时器1控制位置位时定时器 1 工作复位时定时器 1 停止工作
TF0 定时器0溢出标志位定时器 0 溢出时置位处理器响应中断后清除该位TR0 定时器0控制位置位时定时器 0 工作复位时定时器 0 停止工作
IE1 外部中断1 触发标志位当检测到 P3.3 有从高到低的跳变电平时置位处理器响应中断后由硬件清除该位
IT1 中断1 触发方式控制位置位时为跳变触发复位时为低电平触发
IE0 外部中断1 触发标志位当检测到 P3.3 有从高到低的跳变电平时置位处理器响应中断后由硬件清除该位
IT0 中断1 触发方式控制位置位时为跳变触发复位时为低电平触发
定时器控制寄存器 TMOD
GATE C/T M1 M0 GATE C/T M1 M0 定时器1 定时器0
GATE 当 GATE置位时定时器仅当 TR=1并且 INT=1 时才工作如果 GATE=0 置位TR 定时器就开始工作
C/T 定时器方式选择如果 C/T=1 定时器以计数方式工作 C/T=0 时以
定时方式工作
M1 模式选择位高位
M0 模式选择位低位
定时器:
1、设置TMOD工作方式
2、允许定时器中断设置IE(ET0/ET1)
3、启动定时器设置TCON TR0/TR1
4、设置定时器初值 TH0、TL0
EA=1;
TR0=1;
ET0=1;
中断:
1、设置中断使能寄存器 IE的EX0
2、设置TCON 中断方式上升沿是下降沿(IT0/IT1)
EA=1;
EX0=1;
IT0=1;。