一。51单片机的中断
在51单片机中,中断是指当发生某些特定事件时,会打断当前程序的执行,转而执行预先定义好的中断服务程序。这样可以实现及时响应外部事件或处理紧急任务的功能。中断可以分为外部中断和定时器中断两种类型。
外部中断是由外部信号触发的中断,比如按键触发的中断。定时器中断是由定时器产生的中断,用于定时执行某些操作。
通过使用中断,可以提高系统的响应速度和效率,使单片机能够同时处理多个任务,提高系统的可靠性。
2.单一中断
在51单片机中,单一中断通常指只有一个中断源,即只有一个中断服务程序。当这个中断源触发时,会打断当前程序的执行,转而执行该中断服务程序。这种情况下,单片机只需要管理一个中断服务程序,可以简化系统设计和编程。
单一中断通常用于处理特定的事件或任务,比如处理外部按键的中断、处理定时器的中断等。通过单一中断,可以实现对特定事件的及时响应和处理,提高系统的可靠性和实时性。
代码如下
#include <reg51.h>
#define uchar unsigned char
void Delay(unsigned int i)
{
unsigned int j;
for(;i > 0;i--)
for(j=0;j<444;j++)//晶振为12MHz,j和i越大延时越久
{;} //空操作,用来达到延时效果
}
void main( )
{
EA=1; //总中断允许
EX0=1; //允许外部中断0中断
IT0=1; //选择外部中断0为跳沿触发方式
while(1) //循环
{ P1=0;} // P1口的8只LED全亮
}
void int0( ) interrupt 0 using 0 //外中断0的中断函数
{
uchar m;
EX0=0; //禁止外部中断0中断
for(m=0;m<5;m++)//交替闪烁5次
{
P1=0x0f; //低4位LED灭,高4位LED亮
Delay(500); //延时
P1=0xf0; //高4位LED灭,低4位LED亮
Delay(500); //延时
}
EX0=1; //中断返回前,打开外部中断0中断
}
Proteus仿真:
在51单片机普中开发板
三.51单片机双中断
51单片机双中断指的是在51单片机中同时存在两个中断源,即可以同时处理两个不同的中断事件。这样可以在同一时间处理两个不同优先级的中断请求,提高系统的响应能力和灵活性。
代码如下
#include <reg51.h>
#define uchar unsigned char
void Delay(unsigned int i)
{
uchar j;
for(;i>0;i--)
for(j=0;j<125;j++)
{;}
}
void main( )
{
uchar display[9]={0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf, 0x7f};
unsigned int a;
for(;;)
{
EA=1;
EX0=1;
EX1=1;
IT0=1;
IT1=1;
IP=0;
for(a=0;a<9;a++)
{
Delay(500);
P1=display[a];
}
}
void int0_isr(void) interrupt 0 using 1//中断0的中断函数
{
uchar n;
for(n=0;n<10;n++)
{
P1=0x0f;
Delay(500);
P1=0xf0;
Delay(500);
}
}
void int1_isr (void) interrupt 2 using 2//中断1的中断函数
{
uchar m;
for(m=0;m<10;m++)
{
P1=0xff;
Delay(500);
P1=0;
Delay(500);
}
}
Proteus仿真:
在51单片机普中开发板
中断嵌套
题目:设计一中断嵌套程序:要求K1和K2都未按下时,P1口8只LED呈流水灯显示,当按一下K1时,产生一个低优先级外中断0请求(跳沿触发),进入外中断0中断服务程序,上下4只LED交替闪烁。此时按一下K2时,产生一个高优先级的外中断1请求(跳沿触发),进入外中断1中断服务程序,使8只LED全部闪烁。当显示5次后,再从外中断1返回继续执行外中断0中断服务程序,即P1口控制8只LED,上、下4只LED交替闪烁。设置外中断0为低优先级,外中断1为高优先级
#include <reg51.h>
sbit K1 = P3^2; // K1按键引脚
sbit K2 = P3^3; // K2按键引脚
sbit LED = P1^0; // LED引脚
bit flag = 0; // 中断嵌套标志
bit flag1 = 0; // 外中断1计数标志
int count = 0; // 外中断1计数器
void ExternalInterrupt0() interrupt 0 {
if (!K1) {
flag = 1; // 设置中断嵌套标志
IE0 = 0; // 禁止外部中断0
}
}
void ExternalInterrupt1() interrupt 2 {
if (!K2) {
flag1 = 1; // 设置外中断1计数标志
IE1 = 0; // 禁止外部中断1
}
}
void delay() {
int i, j;
for (i = 0; i < 500; i++)
for (j = 0; j < 500; j++);
}
void main() {
EA = 1; // 允许中断
EX0 = 1; // 允许外部中断0
EX1 = 1; // 允许外部中断1
while(1) {
if (!K1 && !K2) {
// 流水灯显示
int i;
for (i = 0; i < 8; i++) {
P1 = ~(1 << i);
delay();
}
}
if (flag) {
// 外中断0服务程序
int i;
for (i = 0; i < 5; i++) {
P1 = 0x0F;
delay();
P1 = 0xF0;
delay();
}
flag = 0; // 清除中断嵌套标志
IE0 = 1; // 允许外部中断0
}
if (flag1) {
// 外中断1服务程序
count++;
P1 = 0xFF;
delay();
P1 = 0x00;
delay();
if (count == 5) {
flag1 = 0; // 清除外中断1计数标志
count = 0; // 重置计数器
IE1 = 1; // 允许外部中断1
}
}
}
}
Keil软件中采用虚拟逻辑仪测试周期准确性
100次中断时间间隔差不多在0.5s左右,因此定时器定时较软件定时更为精确。
计数器中断控制LED
在51单片机中,可以通过设置定时器中断来控制LED的闪烁频率。以下是一个简单的示例代码:
假设LED连接在P1口的某一引脚上,使用定时器0来控制中断:
#include <reg52.h>
sbit LED = P1^0; // 假设LED连接在P1.0口
void timer0_init()
{
TMOD = 0x01; // 设置定时器0为工作方式1
TH0 = 0xFC; // 定时器初值,通过修改TH0和TL0可以设置定时时间
TL0 = 0x18;
ET0 = 1; // 允许定时器0中断
EA = 1; // 允许总中断
TR0 = 1; // 启动定时器0
}
void timer0_isr() interrupt 1
{
LED = ~LED; // 每次定时器中断时LED状态取反
}
void main()
{
timer0_init();
while(1)
{
// 主循环中可以进行其他操作
}
}