单片机三种中断
1.外部中断
2.定时中断
3.串行口中断
中断概念:CPU暂停当前工作A,转去处理其他工作B,处理完毕再回到中断处继续工作A。
52单片机中断优先级
中断源 序号(C语言用)
INT0 外部中断0
T0 定时器/计数器0中断
INT1 外部中断1
T1 定时器/计数器1中断
T1/RI 串行口中断
T2 定时器/计数器2中断
C51的中断函数格式
void 函数名() interrupt 中断号 using 工作组
{
//中断服务程序内容
}
void T1_time() interrupt 3
{
TH1 = (65536-10000)/256;
TL1 = (65536-10000)%256;
}
外部中断程序示例
使用数码管显示学号,按键中断显示,执行中断函数,让LED灯亮。
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^7;
sbit s20=P3^7;
uchar a = 0xfe;
uchar code table[]={
0x3f, 0x4f, 0x3f, 0x5b, 0x3f, 0x7d,
};
void delayms(uint ms)
{
uint i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}
void display();
void LED();
void zhongduan();
void main()
{
EA = 1;
EX0 = 1;
while(1)
{
display(); //数码管显示
}
}
void zhongduan() interrupt 0 //外部中断0
{
while(s20 == 0)
{
P1 = a;
a=_cror_(a,1);
delayms(200);
}
}
void LED()
{
P1 = a;
a=_crol_(a,1);
}
void display()
{
int i = 0;
wela=1;
P0=0xc0;
wela=0;
for( i = 0; i < 6; i++)
{
dula=1;
P0=table[i];
dula=0;
P0=0xff;
P1 = a;
a=_crol_(a,1);
delayms(200);
}
}
定时器中断
数码管显示倒计时,流水灯每秒灭亮,60秒倒计时结束,蜂鸣器响
#include<reg52.h>
// #include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula = P2^6;
sbit wela = P2^7;
sbit didi = P2^3;
sbit LED_A = P1^0;
unsigned char TIME_BASE; //基础累加
unsigned char MACT_ENDB; //可重置
unsigned char Rece_Errp; //定时计数
//
// bit close;
//
uchar code table[] = {
0x3f,0x06,0x5b,0x4f,0x66, //0~4
0x6d,0x7d,0x07,0x7f,0x6f //5~9
};
void delayms(uint ms) //延时
{
uint i,j;
for(i = ms; i > 0; i--)
{
for(j = 110; j>0; j--)
;
}
}
// 定时器初始化
void SystemInit(void)
{
TMOD = 0x01;
TH0 = (65536 - 45872) / 256; // 定时50ms //晶振:11.0592MHZ
TL0 = (65536 - 45872) % 256;
ET0 = 1;
TR0 = 1;
EA = 1;
}
void main()
{
SystemInit();
while(1) //60秒
{
if(Rece_Errp < 60)
{
wela = 1;
P0 = 0xef; //5
wela = 0;
dula = 1;
P0 = table[5 - Rece_Errp/10];
dula = 0;
P0 = 0xff;
delayms(1);
wela = 1;
P0 = 0xdf; //6
wela = 0;
dula = 1;
P0 = table[9 - Rece_Errp%10];
dula = 0;
P0 = 0xff;
delayms(1);
}
else
{
//替换成蜂鸣器
while(1)
{
didi=~didi;
LED_A = ~LED_A;
delayms(500);
} //程序终止在此
}
}
}
void Timer0_IRQ(void) interrupt 1
{
TH0 = (655365 - 45872) / 256;
TL0 = (655365 - 45872) % 256;
// 进入中断50ms +1次
TIME_BASE++;
if(TIME_BASE == 20) // 20ms * 50ms = 刚好等于1000ms 也就是1秒
{
TIME_BASE = 0;
MACT_ENDB++; // 一秒加一次
if(MACT_ENDB == 1) // 等于刚好1秒时间到
{
MACT_ENDB = 0;
Rece_Errp++; // 用来切换LED A、B、C5秒灭
}
}
}