51单片机-02-中断系统

一、GPIO --- 通用输入输出

GPIO(General Purpose Input Output)是单片机与外部世界交互的基本通道,每个引脚均可配置为输入或输出模式。

1.1 GPIO 输入模式(检测引脚电平变化)

|----------|--------------------------|
| 输入模式 | 说明 |
| 悬空输入 | 引脚未连接任何上下拉,电平不确定,容易受干扰 |
| 上拉输入 | 通过电阻连接到VCC,默认高电平;按键按下时拉低 |
| 下拉输入 | 通过电阻连接到GND,默认低电平 |
| 模拟输入 | 用于ADC采样,读取模拟电压值 |

1.2 GPIO 输出模式(给定引脚高电平/低电平,控制引脚输出高电平/低电平)

|----------|------------------|
| 输出模式 | 说明 |
| 推挽输出 | 可主动输出高/低电平,驱动能力强 |
| 开漏输出 | 只能拉低,高电平需外部上拉电阻 |

1.3 检测引脚电平 --- 实例

检测 P3_2 是否为低电平(按键是否按下):

bash 复制代码
// 读取P3第2位

if ((P3 & (1 << 2)) == 0)

{

    // P3_2 为低电平

}

// 位运算示意:

// P3      = 1111 1011

// (1<<2)  = 0000 0100

// 结果    = 0000 0000  → 等于0,说明该位为低

|--------|-----------------------------------------------------------|
| 💡 | 51单片机的P3口引脚默认为高电平(上拉输入)。检测按键时,按键一端接GND,另一端接P3引脚,按下时引脚被拉低。 |

二、中断系统

中断是单片机实时响应外部事件的核心机制,避免了CPU不断轮询的资源浪费。

2.1 核心概念

|--------|-----------------------------------|
| 概念 | 解释 |
| 中断 | CPU暂停当前任务,转去处理更紧急的事件,处理完后回到原处继续执行 |
| 中断源 | 能够触发中断的事件或硬件信号 |
| 中断优先级 | 多个中断同时请求时,优先处理级别高的 |
| 中断嵌套 | 处理一个中断时,被更高优先级中断再次打断(51最多嵌套2层) |
| 中断向量表 | 存放各中断服务函数入口地址的数组 |
| 中断向量 | 中断服务函数在向量表中的编号标识 |

2.2 51单片机的5个中断源

|---------------------|---------------------|
| 中断源 | 中断号 interrupt N |
| 外部中断 0(INT0,P3.2引脚) | interrupt 0 |
| 定时器 0 溢出中断 | interrupt 1 |
| 外部中断 1(INT1,P3.3引脚) | interrupt 2 |
| 定时器 1 溢出中断 | interrupt 3 |
| 串口中断(UART) | interrupt 4 |

2.3 中断处理流程

  1. 中断源发起中断请求

  2. CPU检查中断总开关(EA)及子开关是否打开

  3. 比较中断优先级,决定是否响应

  4. 保护现场(自动压栈保存PC、PSW等寄存器)

  5. 跳转并执行中断服务函数(ISR)

  6. 恢复现场,返回被打断处继续执行

    图1 中断处理流程

    2.4 外部中断0 --- 代码实现

bash 复制代码
// 外部中断0 初始化

void int0_init(void)

{

    P3 |= (1 << 2);      // P3.2 拉高(上拉输入,等待下降沿)

    IE  |= (1 << 7);     // EA=1  打开CPU中断总开关

    IE  |= (1 << 0);     // EX0=1 打开外部中断0子开关

    TCON |= (1 << 0);    // IT0=1 设置为下降沿触发

}



// 外部中断0 服务函数(下降沿触发一次,g_n自增)

void int0_handler(void)  interrupt 0

{

    g_n++;

}

|---------------|---------------------------------------------------------------------|
| ⚠️ 注意 | 中断服务函数不能有参数和返回值,函数名后必须加 interrupt N(N为中断号)。TCON寄存器的IE0位由硬件在响应后自动清零。 |

三、定时器

定时器用于产生精准时间间隔,对PWM、通信时序等时间敏感任务至关重要。

3.1 定时器原理

  • 51单片机有 Timer0 和 Timer1,均为 16位自增计数器(0 ~ 65535)
  • 从初值开始向上计数,溢出(超过65535归0)后向CPU发起中断请求
  • 计数速率 = 晶振频率 ÷ 12(机器周期)

3.2 定时器计算公式(晶振 11.0592MHz)

|----------|------------------|----------------|
| 工作频率 | 11.0592 MHz ÷ 12 | 0.9216 MHz |

|------------|----------------|----------------|
| 每次计数时间 | 1 ÷ 0.9216 MHz | ≈ 1.085 μs |

|--------------------|------------------|-----------------|
| 1ms 定时计数次数 | 1000μs ÷ 1.085μs | ≈ 922 |

|------------------|-------------|-----------|
| 1ms 定时初值 | 65535 - 922 | 64613 |

例1:

3.3 关键寄存器

|-----------------|--------------------------|
| 寄存器 / 位 | 作用 |
| TH0 / TL0 | 定时器0高8位/低8位初值,溢出后需重新装载 |
| TMOD bit0 | 设置Timer0工作模式(1 = 16位定时器) |
| TCON TR0 (bit4) | 置1启动Timer0开始计数 |
| IE EA (bit7) | CPU中断总开关,必须置1才能响应任何中断 |
| IE ET0 (bit1) | 允许Timer0产生中断 |

3.4 工作模式2 --- 8位自动重装

  • 实际计数只用 TL0(0~255),溢出后自动把 TH0 的值重新装入 TL0
  • 优点:无需在中断服务函数中手动重装初值,精度更高

3.5 定时器0 初始化代码

bash 复制代码
void timer0_init(void)

{

    TMOD &= ~(0x0F << 0);  // 清除低4位

    TMOD |= (1 << 0);      // 设置16位定时器模式(M0=1)

    TH0 = g_i >> 8;        // 装入初值高8位

    TL0 = g_i;             // 装入初值低8位

    TCON |= (1 << 4);      // TR0=1 启动定时器

    IE |= (1 << 7);        // EA=1  总中断开关

    IE |= (1 << 1);        // ET0=1 允许Timer0中断

}



// 定时器0 中断服务函数

void timer0_handler(void)  interrupt 1

{

    TH0 = g_i >> 8;        // 重装初值(防止误差累积)

    TL0 = g_i;

    P2 ^= (1 << 5);        // 翻转P2.5引脚(产生方波)

}

四、PWM --- 脉冲宽度调制

PWM(Pulse Width Modulation)通过控制方波的高/低电平时间比,实现对亮度、速度、音调等的调节。

|----------------|-----------------------------|
| PWM 参数 | 定义 |
| PWM 周期 | 一个完整方波所经历的时间(从一个上升沿到下一个上升沿) |
| PWM 占空比 | 高电平时间 ÷ 周期 × 100% |
| 频率 | 1 ÷ 周期,单位 Hz |

|---------------|----------------------------------------------------------------------|
| 🔑 关键 | 占空比决定平均电压。LED: 占空比50% → 半亮;电机: 占空比越大转速越高。51单片机通过定时器中断翻转引脚电平来软件模拟PWM。 |

五、蜂鸣器

5.1 两种蜂鸣器对比

|--------|---------------------------|
| 类型 | 特点 |
| 有源蜂鸣器 | 内置震荡源,通电即持续发出固定频率声音,控制简单 |
| 无源蜂鸣器 | 无内置震荡源,需外部提供PWM方波驱动,可改变音调 |

5.2 蜂鸣器音调计算(200Hz 为例)

|--------|-----------|------------------|
| 周期 | 1 ÷ 200Hz | 0.005s = 5ms |

|---------------|---------|---------------------|
| 半周期(定时时间) | 5ms ÷ 2 | 0.0025s = 2.5ms |

|----------|-----------------|------------------|
| 计数次数 | 2.5ms ÷ 1.085μs | ≈ 2304 |

|-----------|--------------|-----------|
| 定时器初值 | 65535 - 2304 | 63231 |

5.3 常用频率初值对照

|-------------|----------------|
| 频率 (Hz) | 定时器初值(宏定义) |
| 200 Hz | HZ_200 = 63231 |
| 400 Hz | HZ_400 = 64382 |
| 600 Hz | HZ_600 = 64767 |
| 800 Hz | HZ_800 = 64959 |

六、综合示例:按键控制蜂鸣器音调

本示例通过4个按键选择不同频率,驱动无源蜂鸣器发出不同音调。

6.1 按键检测 --- key.c

bash 复制代码
void key_init(void)

{

    P3 |= (0x0F << 0);  // P3.0~P3.3 设为高电平(上拉输入)

}



int key_press(void)

{

    if ((P3 & (1 << 1)) == 0) return 1;  // KEY1: P3.1低 → 按下

    if ((P3 & (1 << 0)) == 0) return 2;  // KEY2: P3.0低 → 按下

    if ((P3 & (1 << 2)) == 0) return 3;  // KEY3: P3.2低 → 按下

    if ((P3 & (1 << 3)) == 0) return 4;  // KEY4: P3.3低 → 按下

    return 0;

}

6.2 主程序 --- main.c

bash 复制代码
#define HZ_200  63231
#define HZ_400  64382
#define HZ_600  64767
#define HZ_800  64959

int main(void)

{

    timer0_init();

    key_init();

    while (1)

    {

        int ret = key_press();

        if      (ret == 1) g_i = HZ_200;  // 低音

        else if (ret == 2) g_i = HZ_400;

        else if (ret == 3) g_i = HZ_600;

        else if (ret == 4) g_i = HZ_800;  // 高音

        else               g_i = 0;        // 无按键,停止发声

    }

}

|----------|--------------------------------------------------------------------------------------|
| 工作原理 | g_i 是全局变量,在定时器中断中用于重装初值。g_i越大,定时时间越短,翻转越快,频率越高,音调越高。g_i=0时不重装初值,定时器停止产生规律方波,蜂鸣器停止发声。 |

七、LED 驱动 --- led.c 补充

bash 复制代码
void led_all_on(void)  { P2 = 0x00; }     // 全亮(低电平有效)

void led_all_off(void) { P2 = 0xFF; }     // 全灭

// 点亮第n个LED(其余熄灭)

void led_on(unsigned char n) { P2 = ~(1 << n); }

// 所有LED取反(全亮变全灭,全灭变全亮)

void led_nor(void) { P2 = P2 ^ 0xFF; }

八、关键寄存器速查表

|---------------|----------------------------------------------------------|
| 寄存器 | 功能描述 |
| P0 ~ P3 | 4组通用I/O口(8位),可读可写,操控外设引脚 |
| IE(中断允许) | bit7=EA总开关;bit0=EX0;bit1=ET0;bit2=EX1;bit3=ET1;bit4=ES |
| TCON(定时/中断控制) | TR0(bit4)=启动Timer0;TR1(bit6)=启动Timer1;IT0(bit0)=INT0触发方式 |
| TMOD(定时器工作模式) | 低4位控制Timer0,高4位控制Timer1;bit0置1=16位定时器模式 |
| TH0 / TL0 | Timer0高8位/低8位计数寄存器 |
| TH1 / TL1 | Timer1高8位/低8位计数寄存器 |

附录:

一,TCON --- 定时器/中断控制寄存器

地址:88H 可位寻址(每个bit可以单独用位地址操作)

作用:控制 Timer0 / Timer1 的启停,以及外部中断 INT0 / INT1 的触发方式和请求标志。

|---------|---------|---------|---------|---------|---------|---------|---------|
| B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
| TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |

|--------|---------|-------------------------------------------------------------------------------------------------------|
| | 名称 | 功能说明 |
| B7 TF1 | TF1 | Timer1 溢出标志位。Timer1 计数溢出时由硬件自动置1,CPU 响应中断后自动清0。也可软件清0。 |
| B6 TR1 | TR1 | Timer1 运行控制位。置1 → 启动 Timer1 开始计数;清0 → 停止 Timer1。 操作:TCON |= (1 << 6) 启动 / TCON &= ~(1 << 6) 停止 |
| B5 TF0 | TF0 | Timer0 溢出标志位。Timer0 计数溢出时由硬件自动置1,CPU 响应中断后自动清0。也可软件清0。 |
| B4 TR0 | TR0 | Timer0 运行控制位。置1 → 启动 Timer0 开始计数;清0 → 停止 Timer0。 操作:TCON |= (1 << 4) 启动 / TCON &= ~(1 << 4) 停止 |
| B3 IE1 | IE1 | 外部中断1(INT1,P3.3)请求标志。检测到触发信号后由硬件置1,CPU 响应后自动清0。 |
| B2 IT1 | IT1 | 外部中断1 触发方式。IT1=0:低电平触发;IT1=1:下降沿触发(推荐,不会误触发)。 操作:TCON |= (1 << 2) 设置下降沿触发 |
| B1 IE0 | IE0 | 外部中断0(INT0,P3.2)请求标志。检测到触发信号后由硬件置1,CPU 响应后自动清0。 |
| B0 IT0 | IT0 | 外部中断0 触发方式。IT0=0:低电平触发;IT0=1:下降沿触发(推荐)。 操作:TCON |= (1 << 0) 设置下降沿触发 |

|---------------|----------------------------------------------------------------------------------------|
| ⚠️ 注意 | TCON 可位寻址,也可用位运算直接操作整个字节。TF0/TF1/IE0/IE1 均由硬件自动置1、自动清0,不需要手动操作。TR0/TR1/IT0/IT1 需要手动配置。 |

二、TMOD --- 定时器工作模式寄存器

地址:89H 不可位寻址(只能整字节操作,不能单独访问某一位)

作用:设置 Timer0 / Timer1 的工作模式(16位/8位/自动重装等)。

|----------|---------|--------|--------|----------|---------|--------|--------|
| B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
| GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |

高4位控制 Timer1 → 低4位控制 Timer0 →

|--------------|----------|-----------------------------------------------------------------------------------------------------|
| | 名称 | 功能说明 |
| B7 / B3 GATE | GATE | 门控位。GATE=0(常用):只要 TR0/TR1 置1,定时器就启动。GATE=1(少用):需同时满足 TR0/TR1=1 且 INT0/INT1 引脚为高电平,定时器才启动(用于测量脉冲宽度)。 |
| B6 / B2 C/T | C/T | 功能选择位。C/T=0:定时器模式(对内部机器周期计数,用于定时)。C/T=1:计数器模式(对外部引脚T0/T1的脉冲计数,用于测量外部事件次数)。 |
| B5 / B1 M1 | M1 | 工作模式高位(与M0组合选择模式,见下表) |
| B4 / B0 M0 | M0 | 工作模式低位(与M1组合选择模式,见下表) |

M1 M0 工作模式选择

|--------|--------|----------------------|----------------------------------------------------------|
| M1 | M0 | 模式 | 说明 |
| 0 | 0 | 模式0 --- 13位定时器 | 由TH(高8位)+ TL(低5位)组成13位计数器,兼容老式8048,很少用 |
| 0 | 1 | 模式1 --- 16位定时器 ★ | TH(高8位)+ TL(低8位)组成16位计数器,范围0~65535,最常用!溢出后需手动重装初值 |
| 1 | 0 | 模式2 --- 8位自动重装 ★ | 只有TL(0~255)参与计数,溢出后自动把TH的值重新装入TL,无需中断里手动重装,适合波特率发生器/PWM |
| 1 | 1 | 模式3 --- 分裂为两个8位 | 仅Timer0支持:TL0独立作8位定时器,TH0也独立作8位定时器,较少使用 |

三、IE --- 中断允许寄存器(顺带整理)

地址:A8H 可位寻址

|--------|---------|---------|--------|---------|---------|---------|---------|
| B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
| EA | --- | ET2 | ES | ET1 | EX1 | ET0 | EX0 |

|--------|---------|-------------------------------------------------------------------------------|
| | 名称 | 功能说明 |
| B7 EA | EA | 中断总开关。EA=1 → 允许CPU响应所有中断(还需各子开关打开);EA=0 → 关闭所有中断,无论子开关状态。操作:IE |= (1 << 7) |
| B6 --- | 保留 | 该位保留,无实际功能,读取值为0。 |
| B5 ET2 | ET2 | Timer2 中断允许位(STC89C52 有 Timer2)。ET2=1 允许 Timer2 中断。 |
| B4 ES | ES | 串口(UART)中断允许位。ES=1 允许串口中断。操作:IE |= (1 << 4) |
| B3 ET1 | ET1 | Timer1 中断允许位。ET1=1 允许 Timer1 溢出中断。操作:IE |= (1 << 3) |
| B2 EX1 | EX1 | 外部中断1(INT1,P3.3)允许位。EX1=1 允许外部中断1。操作:IE |= (1 << 2) |
| B1 ET0 | ET0 | Timer0 中断允许位。ET0=1 允许 Timer0 溢出中断。操作:IE |= (1 << 1) |
| B0 EX0 | EX0 | 外部中断0(INT0,P3.2)允许位。EX0=1 允许外部中断0。操作:IE |= (1 << 0) |

相关推荐
逐步前行3 小时前
STM32_SysTick_寄存器操作
stm32·嵌入式硬件·fpga开发
DLGXY4 小时前
STM32(二十四)——PWR电源控制
stm32·单片机·嵌入式硬件
csg11074 小时前
PIC单片机高阶实战(五):PIC32MX系列的数据存储
单片机·嵌入式硬件·物联网
GreenGoblin4 小时前
12.DSP学习记录之SCI
单片机·dsp开发·电机控制
爱喝纯牛奶的柠檬5 小时前
基于STM32的GPS NMEA解析驱动设计与实现
stm32·单片机·嵌入式硬件
v先v关v住v获v取5 小时前
茶树修剪机结构设计2张cad+设计说明书+三维图
科技·单片机·51单片机
大志出奇迹6 小时前
STM32常用变量类型位数及取值范围
stm32·单片机·嵌入式硬件
LCG元7 小时前
STM32项目实战:基于STM32F103的智能循迹避障小车
stm32·单片机·嵌入式硬件
v先v关v住v获v取7 小时前
NEXUS卡丁车前悬挂控制臂的结构建模与多工况受力分析5张cad+三维图+设计说明书
科技·单片机·51单片机