1. 实验目的
- 学习定时器中断:单片机内部硬件溢出触发,后台计时;
- 学习外部中断 0(INT0,P3.2 引脚):外部按键信号触发;
- 功能:定时器自动计数;按下 P3.2 按键,计数清零。
2. 硬件电路
plaintext
按键外部中断电路
VCC → 按键一端
按键另一端 → P3.2(INT0)
P3.2 再接 10K 下拉电阻到 GND
显示电路:复用上面 2 位共阴极数码管
P0 段码,P1.0 个位位选,P1.1 十位位选
IT0 = 1,配置为下降沿触发。按键按下时电平从高变低,产生下降沿触发外部中断。
⚠️ 本实验不做软件消抖,实际会出现按一次多次触发,仅用于学习原理。
3. 示例核心代码
c
#include <reg52.h>
sbit EN1 = P1^0;
sbit EN2 = P1^1;
unsigned char code seg[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
volatile unsigned char cnt=0;
unsigned int num=0;
void delay(unsigned int t){ while(t--); }
void display(unsigned int n)
{
unsigned char shi = n/10;
unsigned char ge = n%10;
EN1=1; P0=seg[ge]; delay(400); EN1=0;
EN2=1; P0=seg[shi]; delay(400); EN2=0;
}
//定时器0中断,中断号1
void Timer0_ISR(void) interrupt 1
{
TH0=0x3C; TL0=0xAF;
cnt++;
if(cnt >= 20){
cnt = 0;
num++;
}
}
//外部中断0,中断号0,P3.2,【无消抖】
void Int0_ISR(void) interrupt 0
{
num = 0;
cnt = 0;
}
void Timer0_Init(void)
{
TMOD |= 0x01;
TH0=0x3C; TL0=0xAF;
ET0 = 1;
TR0 = 1;
}
void Ext0_Init(void)
{
IT0 = 1; //下降沿触发
EX0 = 1; //使能外部中断0
EA = 1; //总中断开关
}
void main(void)
{
Timer0_Init();
Ext0_Init();
while(1)
{
display(num);
}
}
4. 实验现象
- 定时器后台工作,数码管数字每秒加一;
- 按下 P3.2 按键,触发外部中断,计数值清零;
- 因为没有消抖:按键机械抖动会导致偶尔按一次清零好几次,这是正常现象,工程实际需要增加消抖。
5. 知识点对比表格
| 中断 | 中断号 | 触发来源 |
|---|---|---|
| 定时器 0 中断 | 1 | 单片机内部计数器溢出,不需要外部引脚 |
| 外部中断 0 INT0 | 0 | P3.2 引脚外部信号(按键) |
6. 重要要点
- EA=1 总中断,缺少则全部中断无效;
- 中断服务函数硬件自动调用,代码里不能手动调用;
- 本次实验故意去掉消抖,仅学习中断原理;
- 真实项目建议增加软件或者硬件消抖。