51单片机 各中断模版
- 格式:doc
- 大小:44.00 KB
- 文档页数:6
MCS-51单⽚机的中断系统单⽚机中断技术概述在任何⼀款事件驱动型的CPU⾥⾯都应该会有中断系统,因为中断就是为响应某种事件⽽存在的。
中断的灵活应⽤不仅能够实现想要的功能,⽽且合理的中断安排可以提⾼事件执⾏的效率,因此中断在单⽚机应⽤中的地位是⾮常重要的。
单⽚机中断(Interrupt)是硬件驱动事件,它使得CPU暂停当前的主程序,转⽽去执⾏⼀个中断服务⼦程序。
为了更形象地理解中断,下⾯以学⽣上⾃习时接电话为例阐述⼀下中断的概念。
单⽚机的中断系统有5个中断源、2个中断优先级,可实现两级中断服务程序嵌套。
如果单⽚机没有中断系统,单⽚机的⼤量时间可能会浪费在查询是否有服务请求发⽣的定时査询操作上。
采⽤中断技术完全消除了单⽚机在査询⽅式中的等待现象,⼤⼤地提⾼了单⽚机的⼯作效率和实时性。
单⽚机中断系统结构及中断控制中断系统结构图如图5-2所⽰。
由图5-2可见,MCS-51中断系统共有5个中断请求源:INT0——外部中断请求0,中断请求信号由INT0引脚输⼊。
定时/计数器T0计数溢出发出的中断请求。
INT1——外部中断请求1,中断请求信号由INT1引脚输⼊。
定时/计数器T1计数溢出发出的中断请求。
串⾏⼝中断请求。
中断优先级从⾼到底排列。
单⽚机如何知道有中断请求信号?是否能够响应该中断?若5个中断源请求信号同时到来,单⽚机如何响应?这些问题都可以由中断寄存器来解决。
单⽚机中断寄存器有中断标志寄存器TCON和SCON、中断使能寄存器IE和中断优先级寄存器IP,这些寄存器均为8位。
中断标志寄存器5个中断请求源的中断请求标志分别由TCON和SCON的相应位锁存,单⽚机通过这些中断标志位的状态便能知道具体是哪个中断源正在申请中断。
TCON寄存器TCON寄存器为定时/计数器的控制寄存器,字节地址为88H,可位寻址。
特殊功能寄存器TCON的格式如图5-3所⽰。
TCON各标志位功能如下。
TF1——定时/计数器T1的溢出中断请求标志位。
//实例 42 :用定时器 T0 查询方式 P2 口 8 位控制 LED 闪烁#include<reg51.h>//包含51单片机寄存器定义的头文件/**************************************************************函数功能:主函数**************************************************************/void main(void){// EA=1;// 开总中断// ET0=1;// 定时器 T0 中断允许TMOD=0x01;// 使用定时器 T0 的模式 1TH0=(65536-46083)/256; // 定时器 T0 的高 8 位赋初值TL0=(65536-46083)%256; // 定时器 T0 的高 8 位赋初值TR0=1;// 启动定时器 T0TF0=0;P2=0xff;while(1)// 无限循环等待查询{while(TF0==0);TF0=0;P2=~P2;TH0=(65536-46083)/256; // 定时器 T0 的高 8 位赋初值TL0=(65536-46083)%256; // 定时器 T0 的高 8 位赋初值}}// 实例43 :用定时器T1查询方式控制单片机发出1KHz音频#include<reg51.h>sbit sound=P3^7;// 将// 包含 51 单片机寄存器定义的头文件sound 位定义为 P3.7 引脚/**************************************************************函数功能:主函数**************************************************************/ void main(void){// EA=1;// 开总中断// ET0=1;// 定时器 T0 中断允许TMOD=0x10;// 使用定时器 T1 的模式 1 TH1=(65536-921)/256; // 定时器 T1 的高 8 位赋初值TL1=(65536-921)%256; // 定时器 T1 的高 8 位赋初值TR1=1;// 启动定时器 T1TF1=0;while(1)// 无限循环等待查询{while(TF1==0);TF1=0;sound=~sound; // 将 P3.7 引脚输出电平取反TH1=(65536-921)/256; // 定时器 T0 的高 8 位赋初值TL1=(65536-921)%256; // 定时器 T0 的高 8 位赋初值}}//实例 44 :将计数器 T0 计数的结果送 P1 口 8 位 LED 显示#include<reg51.h> // 包含 51 单片机寄存器定义的头文件 sbitS=P3^4; // 将 S位定义为 P3.4 引脚/**************************************************************函数功能:主函数**************************************************************/void main(void){// EA=1;// 开总中断// ET0=1;// 定时器 T0 中断允许2TMOD=0x02;// 使用定时器 T0 的模式TH0=256-156; // 定时器 T0 的高 8 位赋初值TL0=256-156; // 定时器 T0 的高 8 位赋初值TR0=1;// 启动定时器 T0while(1)// 无限循环等待查询{while(TF0==0)// 如果未计满就等待{if(S==0)// 按键S 按下接地,电平为0P1=TL0; //计数器 TL0 加 1 后送 P1 口显示}TF0=0; // 计数器溢出后,将TF0清 0}}//实例 45 :用定时器 T0 的中断控制 1 位 LED 闪烁#include<reg51.h> // 包含 51 单片机寄存器定义的头文件sbit D1=P2^0; // 将 D1 位定义为 P2.0 引脚/**************************************************************函数功能:主函数**************************************************************/void main(void){EA=1;// 开总中断ET0=1;// 定时器 T0 中断允许TMOD=0x01;// 使用定时器 T0 的模式 2TH0=(65536-46083)/256; //定时器 T0 的高 8 位赋初值TL0=(65536-46083)%256; //定时器 T0 的高 8 位赋初值TR0=1;// 启动定时器 T0while(1)// 无限循环等待中断;}/**************************************************************函数功能:定时器T0 的中断服务程序**************************************************************/void Time0(void) interrupt 1 using 0 // “interrupt ”声明函数为中断服务函数// 其后的 1 为定时器 T0 的中断编号; 0 表示使用第 0 组工作寄存器{D1=~D1; // 按位取反操作,将P2.0 引脚输出电平取反TH0=(65536-46083)/256; //定时器 T0 的高 8 位重新赋初值TL0=(65536-46083)%256; //定时器 T0 的高 8 位重新赋初值}//实例 46 :用定时器 T0 的中断实现长时间定时#include<reg51.h> //包含51单片机寄存器定义的头文件sbit D1=P2^0; // 将 D1 位定义为 P2.0 引脚unsigned char Countor; //设置全局变量,储存定时器T0 中断次数/**************************************************************函数功能:主函数**************************************************************/void main(void){EA=1;// 开总中断ET0=1;// 定时器 T0 中断允许TMOD=0x01;// 使用定时器 T0 的模式 2 TH0=(65536-46083)/256; //定时器 T0 的高 8 位赋初值TL0=(65536-46083)%256; //定时器 T0 的高 8 位赋初值TR0=1; Countor=0;// 启动定时器 T0// 从 0 开始累计中断次数while(1)// 无限循环等待中断;}/**************************************************************函数功能:定时器T0 的中断服务程序**************************************************************/void Time0(void) interrupt 1 using 0 // “interrupt ”声明函数为中断服务函数// 其后的 1 为定时器 T0 的中断编号; 0 表示使用第 0 组工作寄存器{Countor++; // 中断次数自加 1if(Countor==20)// 若累计满20 次,即计时满1s{D1=~D1; Countor=0;// 按位取反操作,将P2.0 引脚输出电平取反// 将 Countor 清 0,重新从 0 开始计数}TH0=(65536-46083)/256; //定时器 T0 的高 8 位重新赋初值TL0=(65536-46083)%256; //定时器 T0 的高 8 位重新赋初值}//实例 47 :用定时器 T1 中断控制两个 LED 以不同周期闪烁#include<reg51.h> //包含51单片机寄存器定义的头文件sbit D1=P2^0; // 将 D1 位定义为 P2.0 引脚sbit D2=P2^1; // 将 D2 位定义为 P2.1 引脚unsigned char Countor1; //设置全局变量,储存定时器unsigned char Countor2; //设置全局变量,储存定时器T1 中断次数T1 中断次数/**************************************************************函数功能:主函数**************************************************************/ void main(void){EA=1;// 开总中断ET1=1;// 定时器 T1 中断允许TMOD=0x10;// 使用定时器 T1 的模式 1TH1=(65536-46083)/256; //定时器 T1 的高 8 位赋初值TL1=(65536-46083)%256; //定时器 T1 的高 8 位赋初值TR1=1;// 启动定时器 T1Countor1=0;// 从 0 开始累计中断次数Countor2=0;// 从 0 开始累计中断次数while(1)// 无限循环等待中断;}/**************************************************************函数功能:定时器T1 的中断服务程序**************************************************************/void Time1(void) interrupt 3 using 0 // “interrupt ”声明函数为中断服务函数// 其后的 3 为定时器 T1 的中断编号; 0 表示使用第 0 组工作寄存器{Countor1++; //Countor1 自加 1Countor2++; //Countor2 自加 1if(Countor1==2) // 若累计满 2 次,即计时满{100msD1=~D1; Countor1=0;// 按位取反操作,将P2.0引脚输出电平取反// 将 Countor1 清 0,重新从 0 开始计数}if(Countor2==8) // 若累计满 8 次,即计时满 400ms {D2=~D2; Countor2=0;// 按位取反操作,将P2.1引脚输出电平取反// 将 Countor1 清 0,重新从 0 开始计数}TH1=(65536-46083)/256; //定时器 T1 的高 8 位重新赋初值TL1=(65536-46083)%256; //定时器 T1 的高 8 位重新赋初值}//实例 50-1 :输出 50 个矩形脉冲#include<reg51.h> // 包含 51 单片机寄存器定义的头文件sbit u=P1^4;// 将 u 位定义为 P1.4/*************************************************函数功能:延时约30ms (3*100*100=30 000μs =30m*************************************************/void delay30ms(void){unsigned char m,n;for(m=0;m<100;m++)for(n=0;n<100;n++);}/*******************************************函数功能:主函数******************************************/void main(void){unsigned char i;u=1;// 初始化输出高电平for(i=0;i<50;i++) // 输出 50 个矩形脉冲{u=1;delay30ms();u=0;delay30ms();}while(1);// 无限循环,防止程序“跑飞”}//实例 50-2 :计数器 T0 统计外部脉冲数#include<reg51.h> // 包含 51 单片机寄存器定义的头文件/*******************************************函数功能:主函数******************************************/void main(void){TMOD=0x06;// TMOD=0000 0110B,使用计数器 T0 的模式 2EA=1; ET0=0; TR0=1;// 开总中断// 不使用定时器// 启动 T0T0 的中断TH0=0; TL0=0; while(1)// 计数器 T0 高 8 位赋初值// 计数器 T0 低 8 位赋初值// 无限循环,不停地将TL0 计数结果送P1 口P1=TL0; }//实例 51-2 :定时器 T0 的模式 2 测量正脉冲宽度#include<reg51.h> // 包含 51 单片机寄存器定义的头文件sbit ui=P3^2;// 将 ui 位定义为 P3.0( INT0)引脚,表示输入电压/*******************************************函数功能:主函数******************************************/void main(void){TMOD=0x0a;// TMOD=0000 1010B,使用定时器T0 的模式2, GATE置 1EA=1; ET0=0; TR0=1; TH0=0; TL0=0; while(1)// 开总中断// 不使用定时器 T0 的中断// 启动 T0// 计数器 T0 高 8 位赋初值// 计数器 T0 低 8 位赋初值// 无限循环,不停地将TL0 计数结果送P1 口{while(ui==0)//INT0为低电平,T0 不能启动;TL0=0;//INT0 为高电平,启动T0 计时,所以将while(ui==1) // 在 INT0 高电平期间,等待,计时TL0清;P1=TL0;// 将计时结果送P1 口显示}}//实例 53 :用外中断 0 的中断方式进行数据采集#include<reg51.h> sbit S=P3^2;// 包含 51 单片机寄存器定义的头文件// 将 S位定义为 P3.2,/*******************************************函数功能:主函数******************************************/ void main(void){EA=1; // 开放总中断EX0=1; // 允许使用外中断IT0=1;// 选择负跳变来触发外中断P1=0xff;while(1);// 无限循环,防止程序跑飞}/**************************************************************函数功能:外中断T0 的中断服务程序**************************************************************/void int0(void) interrupt 0 using 0 // 外中断 0 的中断编号为 0{P1=~P1; // 每产生一次中断请求,P1 取反一次。
51单片机-中断函数基础
单片机中断按照中断源类型的不同主要分为:外部中断、定时器中断、串口中断
而因为电路板上可能存在多个定时器或多个引起外部中
断的位置,所以产生多个中断源,也因此单片机有多个
中断函数
以51单片机为例:
====================================
中断编号
中断源
外部中断0
1
T0定时器溢出中断
2
外部中断1
3
T1定时器溢出中断
4
串口中断
====================================
C程序中使用中断的方法
EA=1;
//打开中断总开关
ET0=1;
//打开T0定时器中断
while(1)
{
//your code
}
//定义中断处理函数(程序会自动调用)
void InterruptTimer0() interrupt 1
{
//关键词interrupt后面的1表示中断函数编号 //your code
//当T0定时器溢出(即截获中断)时,执行InterruptTimer0中断处理函数,执行完毕后程序将从
while中发生中断的位置继续往下执行}。
//实例42 :用定时器TO查询方式P2 口8位控制LED闪烁#include<reg51.h> // 包含 51 单片机寄存器定义的头文件/************************************************************** 函数功能:主函数void main(void){// EA=1; // 开总中断// ETO=1; // 定时器 TO 中断允许TMOD=OxO1; // 使用定时器 TO 的模式 1THO=(65536-46O83)/256; // 定时器 TO 的高 8 位赋初值TLO=(65536-46O83)%256; // 定时器 TO 的高 8 位赋初值TRO=1; // 启动定时器 TOTFO=O;P2=Oxff;while(1)// 无限循环等待查询{while(TFO==O)TFO=O;P2=~P2;THO=(65536-46O83)/256; // 定时器 TO 的高 8 位赋初值TL0=(65536-46083)%256; // 定时器 T0 的高 8 位赋初值}// 实例43 :用定时器T1 查询方式控制单片机发出1KHz 音频#include<reg51.h> // 包含 51 单片机寄存器定义的头文件sbit sou nd=P3^7; // 将 sound 位定义为 P3.7 引脚/**************************************************************函数功能:主函数**************************************************************/void main(void){// EA=1; // 开总中断// ET0=1; // 定时器 T0 中断允许TMOD=0x10; // 使用定时器 T1 的模式 1TH1=(65536-921)/256; // 定时器 T1 的高 8 位赋初值TL1=(65536-921)%256; // 定时器 T1 的高 8 位赋初值TR1=1; // 启动定时器 T1TF1=0;while(1)// 无限循环等待查询{while(TF1==0)TF1=0;sound=~sound; // 将 P3.7 引脚输出电平取反TH1=(65536-921)/256; // 定时器 T0 的高 8 位赋初值TL1=(65536-921)%256; // 定时器 T0 的高 8 位赋初值}}// 实例44 :将计数器T0 计数的结果送P1 口8 位LED 显示#include<reg51.h> // 包含 51 单片机寄存器定义的头文件sbit S=P3A4; //将S位定义为P3.4引脚/************************************************************** 函数功能:主函数**************************************************************/void main(void){// EA=1; // 开总中断// ET0=1; // 定时器 T0 中断允许TMOD=0x02; // 使用定时器 T0 的模式 2TH0=256-156; // 定时器 T0 的高 8 位赋初值TL0=256-156; // 定时器 T0 的高 8 位赋初值TR0=1; // 启动定时器 T0while(1)// 无限循环等待查询{while(TF0==0) // 如果未计满就等待{if(S==0) // 按键 S 按下接地,电平为 0P1=TL0; // 计数器 TL0 加 1 后送 P1 口显示}TFO=O; //计数器溢出后,将TFO清0}}// 实例45 :用定时器TO 的中断控制1 位LED 闪烁#include<reg51.h> // 包含 51 单片机寄存器定义的头文件sbit D仁P2A0; //将D1位定义为P2.0引脚/************************************************************** 函数功能:主函数**************************************************************/void main(void)ET0=1; // 定时器 T0 中断允许TMOD=0x01; // 使用定时器 T0 的模式 2TH0=(65536-46083)/256; // 定时器 T0 的高 8 位赋初值TL0=(65536-46083)%256; // 定时器 T0 的高 8 位赋初值TR0=1; // 启动定时器 T0while(1)// 无限循环等待中断J}/**************************************************************函数功能:定时器 T0 的中断服务程序**************************************************************/ void Time0(void) interrupt 1 using 0 // “ interrupt ”声明函数为中断服务函数// 其后的 1 为定时器 T0 的中断编号;0 表示使用第 0 组工作寄存器{D1=~D1; // 按位取反操作,将 P2.0 引脚输出电平取反TH0=(65536-46083)/256; // 定时器 T0 的高 8 位重新赋初值TL0=(65536-46083)%256; // 定时器 T0 的高 8 位重新赋初值}// 实例46 :用定时器T0 的中断实现长时间定时#include<reg51.h> // 包含 51 单片机寄存器定义的头文件sbit D仁P2P; //将D1位定义为P2.0引脚unsigned char Countor; 设置全局变量,储存定时器 T0 中断次数/**************************************************************函数功能:主函数**************************************************************/void main(void){EA=1; // 开总中断ET0=1; // 定时器 T0 中断允许TMOD=0x01; // 使用定时器 T0 的模式 2TH0=(65536-46083)/256; // 定时器 T0 的高 8 位赋初值TL0=(65536-46083)%256; // 定时器 T0 的高 8 位赋初值TR0=1; // 启动定时器 T0Countor=0; //从0开始累计中断次数while(1)// 无限循环等待中断J}函数功能:定时器 T0 的中断服务程序void Time0(void) interrupt 1 using 0 // “ interrupt ”声明函数为中断服务函数// 其后的 1 为定时器 T0 的中断编号;0 表示使用第 0 组工作寄存器{Countor++; // 中断次数自加 1if(Countor==20) // 若累计满 20 次,即计时满 1s{D1=~D1; // 按位取反操作,将 P2.0 引脚输出电平取反Countor=0; // 将 Countor 清 0 ,重新从 0 开始计数}TH0=(65536-46083)/256; // 定时器 T0 的高 8 位重新赋初值TL0=(65536-46083)%256; // 定时器 T0 的高 8 位重新赋初值}// 实例47 :用定时器T1 中断控制两个LED 以不同周期闪烁#include<reg51.h> // 包含 51 单片机寄存器定义的头文件sbit D仁P2P; //将D1位定义为P2.0引脚sbit D2=P2A1; //将D2位定义为P2.1引脚unsigned char Countor1; // 设置全局变量,储存定时器 T1 中断次数unsigned char Countor2; // 设置全局变量,储存定时器 T1 中断次数函数功能:主函数void main(void){EA=1; // 开总中断ET1=1; // 定时器 T1 中断允许TMOD=0x10; // 使用定时器 T1 的模式 1TH1=(65536-46083)/256; // 定时器 T1 的高 8 位赋初值TL1=(65536-46083)%256; // 定时器 T1 的高 8 位赋初值TR1=1; // 启动定时器 T1Countor1=0; // 从0 开始累计中断次数Countor2=0; // 从0 开始累计中断次数while(1)// 无限循环等待中断}函数功能:定时器 T1 的中断服务程序**************************************************************/void Time1(void) interrupt 3 using 0 // “ interrupt ”声明函数为中断服务函// 其后的 3 为定时器 T1 的中断编号;0 表示使用第 0 组工作寄存器g =30m {Countor1++;//Countor1 自加 1 Countor2++; //Countor2 自加 1if(Countor1==2) // 若累计满 2 次,即计时满 100ms{D1=~D1; // 按位取反操作,将 P2.0 引脚输出电平取反Countor1=0; // 将 Countor1 清 0 ,重新从 0 开始计数 }if(Countor2==8) // 若累计满 8 次,即计时满 400ms{D2=~D2; // 按位取反操作,将 P2.1 引脚输出电平取反Countor2=0; // 将 Countor1 清 0 ,重新从 0 开始计数 }TH1=(65536-46083)/256; // 定时器 T1 的高 8 位重新赋初值 TL1=(65536-46083)%256; // 定时器 T1 的高 8 位重新赋初值 }// 实例 50-1 :输出 50 个矩形脉冲#include<reg51.h> // 包含 51 单片机寄存器定义的头文件 sbit u=P1A 4; // 将 u 位定义为 P1.4***********************************************函数功能:延时约 30ms (3*100*100=30 000*************************************************/ void delay30ms(void) {unsigned char m,n;for(m=0;m<100;m++)for(n=0;n<100;n++)J}/*******************************************函数功能:主函数******************************************/void main(void){unsigned char i;u=1; // 初始化输出高电平for(i=0;i<50;i++) // 输出 50 个矩形脉冲{u=1;delay30ms();u=0;delay30ms();while(1); // 无限循环,防止程序“跑飞”}// 实例50-2 :计数器T0 统计外部脉冲数#include<reg51.h> // 包含 51 单片机寄存器定义的头文件/*******************************************函数功能:主函数******************************************/ void main(void) {TMOD=0x06; // TMOD=0000 0110B, 使用计数器 T0 的模式 2 EA=1; // 开总中断ET0=0; // 不使用定时器 T0 的中断TR0=1; // 启动 T0TH0=0; // 计数器 T0 高 8 位赋初值TL0=0; // 计数器 T0 低 8 位赋初值while(1) // 无限循环,不停地将 TL0 计数结果送 P1 口P1=TL0;// 实例51-2 :定时器T0 的模式2 测量正脉冲宽度#include<reg51.h> // 包含 51 单片机寄存器定义的头文件sbit ui=P3A2; //将ui位定义为P3.0 (INTO )引脚,表示输入电压/*******************************************函数功能:主函数******************************************/ void main(void) {TMOD=0x0a; // TMOD=0000 1010B, 使用定时器 TO 的模式 2 , GATE 置1EA=1; //开总中断ET0=0; // 不使用定时器 T0 的中断TR0=1; // 启动 T0TH0=0; // 计数器 T0 高8 位赋初值TL0=0; // 计数器 T0 低8 位赋初值while(1) //无限循环,不停地将TL0计数结果送P1 口{while(ui==0) //INT0为低电平,T0不能启动TL0=0; //INT0 为高电平,启动 T0 计时,所以将 TL0 清 0 while(ui==1)// 在 INT0 高电平期间,等待,计时JP1=TL0; // 将计时结果送 P1 口显示}}// 实例53 :用外中断0 的中断方式进行数据采集#include<reg51.h> // 包含 51 单片机寄存器定义的头文件sbit S=P3A2; // 将 S 位定义为 P3.2 ,/*******************************************函数功能:主函数******************************************/void main(void){EA=1; // 开放总中断EX0=1;// 允许使用外中断IT0=1; // 选择负跳变来触发外中断P1=0xff;while(1); // 无限循环,防止程序跑飞函数功能:外中断 T0 的中断服务程序**************************************************************/ void int0(void) interrupt 0 using 0 // 外中断 0 的中断编号为 0 {P1=~P1; // 每产生一次中断请求, P1 取反一次。
中断一、中断允许寄存器 IEEA-----全局中断允许位EA=0打开全局中断控制。
EA=1关闭全部中断。
ET2----定时器/计数器2中断允许位 ET2=1打开T2中断。
ET2=0关闭T2中断。
ES----串口中断允许位。
ES=1打开串口中断。
ES=0关闭串口中断。
EX1----外部中断1中断允许位; EX1=1打开外部中断1中断。
EX1=0关闭外部中断1中断。
ET0----定时期计数器0中断允许位 ET0=1,打开T0中断。
ET0=0,关闭T 中断。
EX0----外部中断0中断允许位。
位序号 D7 D6 D5 D4 D3 D2 D1 D0 位符号 EA -- ET2 ES ET1 EX1 ET0 EX0 位地址 AFH -- ADH ACH ABH AAH A9H A8HEX0EA PX001ET0PT001EX1PX101ET1PT101ES PS 01≥1RI TISCONTCONIE0TF0IE1TF11101IT0IT1INT0INT1T0T1RX TXIEIP11111111硬件查询自然优先级自然优先级中断入口中断入口高级低级中断源中断源EX0=1打开外部中断0中断。
EX0=0关闭外部中断0中断。
二、中断优先级级寄存器IP位序号D7 D6 D5 D4 D3 D2 D1 D0 位符号-- -- -- PS PT1 PX1 PT0 PX0 位地址-- -- -- BCH BBH BAH B9H B8H 单片机的定时器中断一、定时器/计数器工作方式寄存器TMOD位序号D7 D6 D5 D4 D3 D2 D1 D0 位符号GATE C/T M1 M0 GATE C/T M1 M0 二、定时器/计数器控制寄存器TCON位序号D7 D6 D5 D4 D3 D2 D1 D0位符号TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 位地址8FH 8EH 8DH 8CH 8BH 8AH 89H 88H。
有关51单片机中断的形式和C语言编程格式[精选5篇]第一篇:有关51单片机中断的形式和C语言编程格式有关51单片机中断的形式和C语言编程格式void INT0()interrupt 0 using 1 {.........} interrupt 0 指明是外部中断0; interrupt 1 指明是定时器中断0; interrupt 2 指明是外部中断1; interrupt 3 指明是定时器中断1; interrupt 4 指明是串行口中断;using 0 是第0组寄存器; using 1 是第1组寄存器; using 2 是第2组寄存器; using 3 是第3组寄存器;例如:/*-----------------外部中断程序-----------------*/ void ISR_Key(void)interrupt 0 using 1 { P1=~P1;//s3按下触发一次,P1取反一次 }/*-----------------串口中断程序-----------------*/ void UART_SER(void)interrupt 4 //串行中断服务程序 {unsigned char Temp;//定义临时变量if(RI)//判断是接收中断产生{RI=0;//标志位清零Temp=SBUF;//读入缓冲区的值P1=Temp;//把值输出到P1口,用于观察SBUF=Temp;//把接收到的值再发回电脑端}if(TI)//如果是发送标志位,清零TI=0;}第二篇:--单片机C语言编程实训实习报告实习地点:201机房实习时间:2014.12.1——2014.12.6 实习项目:单片机C语言编程实训指导老师:骆乐姓名:班级:电信3121一、实习内容 1.计算字符的ASCII码编写一个程序,在终端输入一个字符,输出它的ASCII码。
解题思路:通常我们输出一个字符一般用printf(“%c”,c);的形式,因为输出格式规定的是“%c”,因此表示以字符的形式输出,所以我们看到的是相对应的ASCII码的字符形式。
51单片机中断函数在51单片机中,中断是一种强大的功能,它可以在一些特定的时间或事件发生时打断正在执行的程序,并执行一个特定的函数,然后再回到原来的程序继续执行。
中断函数是在中断事件发生时自动执行的一段程序代码,可以用来处理中断事件。
中断函数的定义格式如下:```cvoid interrupt_function_name( interrupt interrupt_number//中断处理代码```其中,`interrupt_function_name`是中断函数的名字,`interrupt_number`是中断号。
当中断事件发生时,单片机自动调用该中断函数执行中断处理代码。
在51单片机中,有两种中断类型:硬件中断和软件中断。
一、硬件中断:硬件中断是由硬件引脚的输入触发的中断,常见的硬件中断包括外部中断、定时器中断和串口中断。
1.外部中断:外部中断是通过控制P3口上的引脚来实现的,有两个外部中断引脚INT0和INT1、当引脚上的电平发生变化时,会触发外部中断。
外部中断的中断号分别为0和1、具体的外部中断函数定义如下:```cvoid external_interrupt_0( interrupt 0//外部中断0处理代码void external_interrupt_1( interrupt 1//外部中断1处理代码```2.定时器中断:定时器中断是通过定时器产生的中断。
51单片机内部有两个定时器,分别为定时器0和定时器1、定时器中断的中断号分别为1和3、具体的定时器中断函数定义如下:```c//定时器0中断处理代码//定时器1中断处理代码```3.串口中断:串口中断是通过UART模块产生的中断,当接收到数据或发送数据完成时,会触发串口中断。
串口中断的中断号为4、具体的串口中断函数定义如下:```cvoid uart_interrupt( interrupt 4//串口中断处理代码```二、软件中断:软件中断是通过程序来触发的中断,通过软件中断可以在程序执行过程中主动调用中断函数。
单片机串口通信在嵌入式系统中具有非常重要的作用,而其中串口中断的编写方式更是至关重要。
今天我们来讨论一下51单片机串口中断的两种写法。
1. 外部中断写法在51单片机中,串口通信一般使用串口中断来实现。
外部中断写法是一种常见的串口中断编写方式。
其具体步骤如下:1)需要设置串口工作参数,包括波特率、数据位、停止位和校验位等。
2)在主程序中使能串口中断,并设置中断优先级。
3)在中断服务函数中进行接收数据的处理,可以通过接收缓冲区、中断标志位等来判断接收数据的情况,并进行相应的处理。
2. 定时器中断写法除了外部中断写法,定时器中断也是一种常见的串口中断编写方式。
其具体步骤如下:1)同样需要设置串口工作参数,包括波特率、数据位、停止位和校验位等。
2)在主程序中初始化定时器,并使能定时器中断。
3)在定时器中断服务函数中进行接收数据的处理,同样可以通过接收缓冲区、中断标志位等来判断接收数据的情况,并进行相应的处理。
总结无论是外部中断写法还是定时器中断写法,都是实现51单片机串口通信的常见方式。
在选择具体的编写方式时,需要根据具体的应用场景和需求来进行选择。
在实际应用中,可以根据具体情况来灵活选择合适的串口中断编写方式,以便更好地满足系统的需求。
在实际编写中断服务函数时,需要注意以下几点:1)处理数据时需要考虑数据的完整性和准确性,可以通过校验位等手段来验证数据的正确性。
2)在中断服务函数中应尽量减少对全局变量的访问,以避免出现数据冲突和竞争的情况。
3)合理设置中断优先级,避免产生中断嵌套和冲突。
通过合理的中断编写方式和注意事项,可以更好地实现串口通信功能,提高系统的稳定性和可靠性,为嵌入式系统的应用提供良好的技术支持。
对于外部中断写法和定时器中断写法,两者各有优缺点。
外部中断写法在串口数据到达时能够即刻响应中断、处理数据。
但是,如果数据传输速率较快或需要高精度的数据处理,外部中断写法可能无法满足要求。
在这种情况下,定时器中断写法显得更加合适。
51单片机中断总结-马强51单片机中断总结-马强Yybmec51单片机中断系统5个中断源:2个外部中断请求INT0和INT1、2个片内定时器/计数器T0和T1的溢出中断请求串行口中断请求TI 或RI(合为一个中断源)51单片机中断级别中断源INIT0---外部中断0T0---定时器/计数器0中断INIT1---外部中断1T1----定时器/计数器1中断TI/RI---串行口中断T2---定时器/计数器2中断默认中断级别最高第2第3第4第5最低序号(C语言用)012345中断允许寄存器IE位序号符号位DB7EADB6-------DB5ET2DB4ESDB3ET1DB2EX1DB1ET0DB0EX0EA---全局中允许位。
EA=1,打开全局中断控制,在此条件下,由各个中断控制位确定相应中断的打开或关闭。
EA=0,关闭全部中断。
-------,无效位。
ET2---定时器/计数器2中断允许位。
ET2=1,打开T2中断。
ET2=0,关闭T2中断。
ES---串行口中断允许位。
ES=1,打开串行口中断。
ES=0,关闭串行口中断。
ET1---定时器/计数器1中断允许位。
ET1=1,打开T1中断。
ET1=0,关闭T1中断。
EX1---外部中断1中断允许位。
EX1=1,打开外部中断1中断。
EX1=0,关闭外部中断1中断。
ET0---定时器/计数器0中断允许位。
ET0=1,打开T0中断。
ET0=0,关闭T0中断。
EX0---外部中断0中断允许位。
EX0=1,打开外部中断0中断。
EX0=0,关闭外部中断0中断。
中断优先级寄存器IP位序号DB7DB6DB5DB41DB3DB2DB1DBYybmec位地址---------PSPT1PX1PT0PX0-------,无效位。
PS---串行口中断优先级控制位。
PS=1,串行口中断定义为高优先级中断。
PS=0,串行口中断定义为低优先级中断。
PT1---定时器/计数器1中断优先级控制位。
51单片机一般有两个外部中断输入端,并允许外部中断源以低电平或负边沿两种触发方式输入中断请求信号。
本例就是利用一只按钮,在按下时产生的负边沿触发外部中断。
1 硬件设计将一只按钮接在外部中断输入0(12脚),八支发光二极管分别接在P0.0~P0.7,其电路如下图所示。
⒉软件设计通过按下按钮SW触发外部中断,从而改变发光二极管D1~D8的亮、灭,当第一次按下按钮时,只有D1发光二极管亮;第二次按下按钮时,只有D2发光二极管亮;第三次按下按钮时,只有D3发光二极管亮;……第八次按下按钮时,只有D8发光二极管亮;第九次按下按钮时,D1~D8发光二极管全亮;第十次按下按钮时,D1~D8发光二极管全都不亮;第十一次按下按钮时,只有D1发光二极管亮;按钮SW触发外部中断,从而控制D1~D8亮灭的详细C51程序如下。
/***************外部中断****************/#include <reg51.h>unsigned char count=0; //外部中断计数unsigned char F0=0;main(){F0=0;IE=0X81;//打开外部中断0和总中断使能或者(EX0=1;EA=1)IT0=1; //标志位清零,开中断 ,边沿激活(或者TCON|=0X01)while(1){while(F0==0);switch(count%10){case(0): P0=0XFF;break;case(1): P0=0XFE;break;case(2): P0=0XFD;break;case(3): P0=0XFB;break;case(4): P0=0XF7;break;case(5): P0=0XEF;break;case(6): P0=0XDF;break;case(7): P0=0XBF;break;case(8): P0=0X7F;break; case(9): P0=0X00;break; }F0=0;}}void int_int0() interrupt 0 //外部中断{count++;F0=1;}。
80C51单片机中断系统结构图’中断的类型和应用(个人理解):1、外部中断(INT0、INT1):直接可以由单片机外围设备的变化导致外部中断接口(P3^2、P3^3)电平变化(低电平和下降沿)触发,可由外部控制。
2、定时器中断(T0、T1、T2):直接由软件设置的定时的内部中断,按照指定的时间计满数触发。
3、串口中断(TI、RI):应用在串口通信,把数据发送标志位TI和接收位RI置0。
一、外部中断1、外部中断(INT0、INT1)的初始化设置的步骤:**************************************(1)首先设置这些外部中断优先级PX0=1/0;PX1=1/0(1为高级,0为低级);【默认为0】(2)其次要开总中断EA=1;【默认为0】(3)设置外部中断触发方式:IT0 = 1(下降沿触发)/0(低电平触发)、IT1=1(下降沿触发)/0(低电平触发);【默认为0】(4)再开启外部中断使能:EX0=1(外部中断0)或EX1=1(外部中断1)【默认为0】(5)中断请求标志(不需人为设定,机器自动设置):EI0=1/0;(外部中断0中断请求标志)EI1=1/0;(外部中断1请求标志)【1表示处于中断请求状态,0表示无该中断请求,在电平触发方式时,在相应的中断端口检测到低电平时置1】(6)只要对应中断的接口(INT0或INT1)接受到有效电平(至少持续两个机器周期的低电平(电平触发方式)或下降沿(下降沿触发方式))它就启动。
2、外部中断涉及的寄存器(1)IP(中断优先级寄存器)(2)IE(中断允许寄存器)(3)TCON(中断控制和标志寄存器)3、外部中断的应用#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbitdula=P2^6;sbitwela=P2^7;sbit d1=P1^0;ucharnum;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void delay(uint z);void main(){EA=1;//开总中断EX0=1;//开外部中断0//IT0=1;TCON=0x01;wela=1;//11101010P0=0xea;wela=0;while(1){for(num=0;num<16;num++){d1=1;dula=1;P0=table[num];dula=0;delay(1000);}}}void delay(uint z){uintx,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void exter0() interrupt 0{d1=0;}4、外部中断的电平触发和下降沿触发的区别:选择电平触发时,单片机在每个机器周期检查中断源口线,检测到低电平,即置位中断请求标志,向CPU请求中断。
51单片机各中断初始化及子程序模板/************************************************************ *51单片机各中断初始化及子程序模板,几乎包括了传统51单片机的全部中断*1、外部中断0*2、定时器中断0*3、外部中断1*4、定时器中断1*5、串行中断*6、定时器中断2---本中断在52时才有*以上所有中断已经在Keil软件环境上经过测试,工作正常*在使用定时中断的时候需要根据实际需要重设定时器的初值和工作方式*在串行通讯中,使用11.0592M晶振,通讯波特率为9600bps*为了保证文件的单一和方便保存,本项目只用了一个文件,没有进行模块化处理,在实际应用中不建议这样做*本程序在UE11.00b下编辑,在KeilV3.23(C8.01)下编译调试*本程序仅供初学者参考使用,细节问题未涉及,在实际项目中请谨慎使用*Author:大灵通*昌宁科技,欢迎您提出宝贵意见!*2006-12-7 15:05,OK!*************************************************************/#include<reg52.h>//如果是使用51单片机,则应该是reg51.h,//且不能使用定时器2#include<intrins.h>//以下两个包含文件在本代码中实际不需要,#include<absacc.h>//但经常用到,所以列出#define uchar unsigned char#define uint unsigned int#define TimeDelay 2//程序所用变量声明bit Time0Int;bit Int0Flag,Int1Flag;uchar Time0Count,Time1Count,Time2Count;uchar ReceiveData;//程序所用函数声明void McuInitial(void);void InitialTime0(void);void InitialTime1(void);void InitialTime2(void);void IntialSerialComm(void);void SerialSend(uchar SendData);void delay(uint n);/************************************************************ *Function: 主函数*parameter:*Return:*Modify:*************************************************************/ void main(void){uchar i;McuInitial();delay(TimeDelay);while(1){if(Int0Flag==1)//各中断的具体处理{Int0Flag = 0;}if(Int1Flag==1){Int1Flag = 0;}if(Time0Count==5){Time0Count = 0;}if(Time1Count==5){Time1Count = 0;}if(Time2Count==5){Time2Count = 0;}SerialSend(i);i++;if(i>=0xff)i=0;}}/*************************************************************Function: 单片机初始化处理*parameter:*Return:*Modify:*************************************************************/ void McuInitial(void){//外部中断0初始化IT0 = 1;EX0 = 1;//外部中断1初始化IT1 = 1;EX1 = 1;InitialTime0();//定时器0初始化// InitialTime1();//定时器1初始化InitialTime2();//定时器2初始化IntialSerialComm();//串行中断初始化,占用定时器1,//如果用串行中断,定时器1不能用于定时EA = 1;//打开中断}/************************************************************ *Function: 定时器1初始化*parameter:*Return:*Modify:*************************************************************/ void InitialTime0 (void){TMOD |= 0x01;//16位定时器TH0 = 0x06;//8msTL0 = 0xed;ET0 = 1;//使能中断TR0 = 1;//打开定时器}/************************************************************ *Function: 定时器1初始化*parameter:*Return:*Modify:*************************************************************/void InitialTime1 (void){TMOD |= 0x10;//16位定时器TH1 = 0x06;//8msTL1 = 0xed;ET1 = 1;//使能中断TR1 = 1;//打开定时器}/************************************************************ *Function: 定时器2初始化,本中断仅在52时才有*parameter:*Return:*Modify:*************************************************************/ void InitialTime2 (void){T2CON=0x04;RCAP2H=0x04;RCAP2L=0x00;ET2 = 1;}/************************************************************ *Function: 串行中断初始化*parameter:*Return:*Modify:*************************************************************/ void IntialSerialComm(void){TMOD |= 0x20;SCON=0xf0;TH1=0xfd;//fdTL1=0xfd;//fdTR1=1;ES=1;}/************************************************************ *Function: 外部中断0中断服务子程序*parameter:*Return:*Modify:*************************************************************/ void Interrupt0 (void) interrupt 0Int0Flag = 1;}/************************************************************ *Function: 外部中断1中断服务子程序*parameter:*Return:*Modify:*************************************************************/ void Interrupt1 (void) interrupt 2{Int1Flag = 1;}/************************************************************ *Function: 定时器0中断服务子程序*parameter:*Return:*Modify:*************************************************************/ void InterruptTime0(void) interrupt 1{TH0 = 0x06;//8msTL0 = 0xed;Time0Count++;}/************************************************************ *Function: 定时器1中断服务子程序*parameter:*Return:*Modify:*************************************************************/ void InterruptTime1(void) interrupt 3{TH1 = 0x06;//8msTL1 = 0xed;Time1Count++;}/************************************************************ *Function: 定时器2中断服务子程序*parameter:*Return:*Modify:*************************************************************/ void InterruptTime2(void) interrupt 5TF2=0;Time2Count++;}/************************************************************ *Function: 串行接收中断服务子程序*parameter:*Return:*Modify:*************************************************************/ void InterruptSerialComm(void) interrupt 4{if(RI){RI = 0;ReceiveData = SBUF;}}/************************************************************ *Function: 串行发送程序*parameter:*Return:*Modify:*************************************************************/ void SerialSend(uchar SendData){SBUF = SendData;while(TI==0);TI = 0;}/************************************************************ *Function: 延时*parameter:*Return:*Modify:*************************************************************/ void delay(uint n){while(n!=0){n--;}。
第一步,中断配置/************************************************************函数名: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,//执行完成后,返回从断点处继续往下执行原来的代码。
51系列单片机各中断初始化及子程序模板/*************************************************************51单片机各中断初始化及子程序模板,几乎包括了传统51单片机的全部中断*1、外部中断0*2、定时器中断0*3、外部中断1*4、定时器中断1*5、串行中断*6、定时器中断2---本中断在52时才有*以上所有中断已经在Keil软件环境上经过测试,工作正常*在使用定时中断的时候需要根据实际需要重设定时器的初值和工作方式*在串行通讯中,使用11.0592M晶振,通讯波特率为9600bps*为了保证文件的单一和方便保存,本项目只用了一个文件,没有进行模块化处理,在实际应用中不建议这样做*本程序在UE11.00b下编辑,在KeilV3.23(C8.01)下编译调试*本程序仅供初学者参考使用,细节问题未涉及,在实际项目中请谨慎使用*Author:大灵通*昌宁科技,欢迎您提出宝贵意见!*2006-12-7 15:05,OK!*************************************************************/#include<reg52.h>//如果是使用51单片机,则应该是reg51.h,//且不能使用定时器2#include<intrins.h>//以下两个包含文件在本代码中实际不需要,#include<absacc.h>//但经常用到,所以列出#define uchar unsigned char#define uint unsigned int#define TimeDelay 2//程序所用变量声明bit Time0Int;bit Int0Flag,Int1Flag;uchar Time0Count,Time1Count,Time2Count;uchar ReceiveData;//程序所用函数声明void McuInitial(void);void InitialTime0(void);void InitialTime1(void);void InitialTime2(void);void IntialSerialComm(void);void SerialSend(uchar SendData);void delay(uint n);/*************************************************************Function: 主函数*parameter:*Return:*Modify:*************************************************************/ void main(void){uchar i;McuInitial();delay(TimeDelay);while(1){if(Int0Flag==1)//各中断的具体处理{Int0Flag = 0;}if(Int1Flag==1){Int1Flag = 0;}if(Time0Count==5){Time0Count = 0;}if(Time1Count==5){Time1Count = 0;}if(Time2Count==5){Time2Count = 0;}SerialSend(i);i++;if(i>=0xff)i=0;}}/************************************************************ *Function: 单片机初始化处理*parameter:*Return:*Modify:*************************************************************/ void McuInitial(void){//外部中断0初始化IT0=0; //低电平触发IT0=1; //下降沿触发EX0=1;//外部中断1初始化IT1 = 1;EX1 = 1;InitialTime0();//定时器0初始化// InitialTime1();//定时器1初始化InitialTime2();//定时器2初始化IntialSerialComm();//串行中断初始化,占用定时器1,//如果用串行中断,定时器1不能用于定时EA = 1;//打开中断}/************************************************************ *Function: 定时器1初始化*parameter:*Return:*Modify:*************************************************************/ void InitialTime0 (void){TMOD |= 0x01;//16位定时器TH0 = 0x06;//8msTL0 = 0xed;ET0 = 1;//使能中断TR0 = 1;//打开定时器}/************************************************************ *Function: 定时器1初始化*parameter:*Return:*Modify:*************************************************************/ void InitialTime1 (void){TMOD |= 0x10;//16位定时器TH1 = 0x06;//8msTL1 = 0xed;ET1 = 1;//使能中断TR1 = 1;//打开定时器}/************************************************************ *Function: 定时器2初始化,本中断仅在52时才有*parameter:*Return:*Modify:*************************************************************/ void InitialTime2 (void){T2CON=0x04;RCAP2H=0x04;RCAP2L=0x00;ET2 = 1;}/************************************************************ *Function: 串行中断初始化*parameter:*Return:*Modify:*************************************************************/ void IntialSerialComm(void){TMOD |= 0x20;SCON=0xf0;TH1=0xfd;//fdTL1=0xfd;//fdTR1=1;ES=1;}/************************************************************ *Function: 外部中断0中断服务子程序*parameter:*Return:*Modify:*************************************************************/ void Interrupt0 (void) interrupt 0{Int0Flag = 1;}/************************************************************ *Function: 外部中断1中断服务子程序*parameter:*Modify:*************************************************************/ void Interrupt1 (void) interrupt 2{Int1Flag = 1;}/************************************************************ *Function: 定时器0中断服务子程序*parameter:*Return:*Modify:*************************************************************/ void InterruptTime0(void) interrupt 1{TH0 = 0x06;//8msTL0 = 0xed;Time0Count++;}/************************************************************ *Function: 定时器1中断服务子程序*parameter:*Return:*Modify:*************************************************************/ void InterruptTime1(void) interrupt 3{TH1 = 0x06;//8msTL1 = 0xed;Time1Count++;}/************************************************************ *Function: 定时器2中断服务子程序*parameter:*Return:*Modify:*************************************************************/ void InterruptTime2(void) interrupt 5{TF2=0;Time2Count++;}/************************************************************ *Function: 串行接收中断服务子程序*Return:*Modify:*************************************************************/ void InterruptSerialComm(void) interrupt 4{if(RI){RI = 0;ReceiveData = SBUF;}}/************************************************************ *Function: 串行发送程序*parameter:*Return:*Modify:*************************************************************/ void SerialSend(uchar SendData){SBUF = SendData;while(TI==0);TI = 0;}/************************************************************ *Function: 延时*parameter:*Return:*Modify:*************************************************************/ void delay(uint n){while(n!=0){n--;}。