51单片机(二):GPIO、中断、定时器与PWM

1. GPIO输出模式与输入模式

GPIO(General Purpose Input/Output,通用目的输入输出)是单片机与外部世界交互的基本接口。每个GPIO引脚都可以配置为两种基本工作模式:

输出模式

  • 功能:由单片机主动控制引脚输出高电平(通常为VCC电压)或低电平(通常为GND电压)。
  • 应用场景
    • LED控制:输出高电平点亮LED,低电平熄灭LED
    • 数码管控制:动态扫描显示数字
    • 蜂鸣器控制:驱动有源蜂鸣器发声
    • 继电器控制:开关外部设备

输入模式

  • 功能:检测外部施加到引脚的电平状态(高电平或低电平)。
  • 应用场景
    • 按键检测:如独立按键,一端接GND,一端接GPIO引脚。按键按下时,引脚被拉低到GND电平
    • 传感器信号读取:如DHT11温湿度传感器的DATA信号
    • ADC信号检测:读取模拟电压值对应的数字信号

示例:DHT11传感器通信

c 复制代码
// 起始信号:主机(单片机)先拉低DATA线至少18ms,然后拉高20-40us
void dht11_start_signal(void) {
    DATA_PIN = 0;      // 输出低电平(GPIO输出模式)
    delay_ms(20);      // 保持低电平18ms以上
    DATA_PIN = 1;      // 输出高电平
    delay_us(30);      // 保持高电平20-40us
    // 随后切换为输入模式,等待传感器响应
}

2. 中断概念

中断是单片机处理紧急事件的重要机制。当CPU正在执行某个任务时,如果发生更紧急的外部事件,CPU会暂停当前任务,转去处理这个紧急事件,处理完毕后再返回原任务继续执行。

中断的比喻:就像你在看书(主程序)时,手机突然响了(中断请求),你暂停看书去接电话(执行中断服务函数),接完电话后继续看书(返回主程序)。

3. 51单片机中断源类型及个数

51单片机共有5个中断源,按优先级从高到低排列:

  1. 外部中断0(INT0):最高优先级,由P3.2引脚的电平变化触发
  2. 定时器0中断(TIMER0):定时器0溢出时触发
  3. 外部中断1(INT1):由P3.3引脚的电平变化触发
  4. 定时器1中断(TIMER1):定时器1溢出时触发
  5. 串口中断(UART):串口接收或发送完成时触发

4. 什么是外部中断

外部中断是由单片机外部引脚的电平变化所引发的中断。51单片机有两个外部中断:

  • INT0:对应P3.2引脚,可用于按键紧急处理、外部事件检测等
  • INT1:对应P3.3引脚,功能与INT0类似

触发方式

  • 低电平触发:引脚为低电平时持续产生中断请求
  • 下降沿触发:引脚电平从高变低时产生一次中断请求
  • 上升沿触发:引脚电平从低变高时产生一次中断请求
  • 高电平触发:引脚为高电平时持续产生中断请求

51单片机的外部中断通常配置为下降沿触发,避免因电平持续而重复进入中断。

5. 中断处理流程

当中断事件发生时,CPU按以下流程处理:

  1. 中断请求:中断源(如定时器溢出、引脚电平变化)向CPU发出中断请求
  2. 中断使能检查
    • 检查总中断开关(EA)是否打开
    • 检查该中断源的中断使能位是否打开
  3. 优先级比较:如果同时有多个中断请求,CPU优先处理优先级高的中断
  4. 保护现场:将当前程序计数器(PC)和其他重要寄存器值压入堆栈
  5. 执行中断服务函数:跳转到中断向量表指定的地址,执行用户编写的中断处理代码
  6. 恢复现场:从堆栈恢复寄存器值,返回原程序继续执行

中断嵌套:51单片机支持最多两层中断嵌套。当CPU正在处理一个低优先级中断时,如果发生更高优先级的中断,CPU会暂停当前中断,转去处理更高优先级的中断。

6. 51单片机中有几个定时器

51单片机内置2个16位定时器/计数器

  • 定时器0(Timer0)
  • 定时器1(Timer1)

这两个定时器功能相同,可以独立配置为定时器模式或计数器模式。

7. 定时器工作模式

51单片机的定时器有4种工作模式:

模式0:13位定时器/计数器

  • 高8位(THx)和低5位(TLx的低5位)组成13位计数器
  • 计数值范围:0-8191(2¹³-1)
  • 兼容早期8048单片机,现在较少使用

模式1:16位定时器/计数器(最常用)

  • THx和TLx组成完整的16位计数器
  • 计数值范围:0-65535(2¹⁶-1)
  • 溢出后需要软件重新装载初值

模式2:8位自动重装载定时器

  • TLx作为8位计数器(0-255)
  • THx保存重装载值
  • TLx溢出后自动从THx重装载,无需软件干预
  • 特别适合产生精确的波特率(串口通信)

模式3:两个8位定时器(仅Timer0)

  • Timer0被拆分为两个独立的8位定时器
  • TL0作为定时器/计数器,使用Timer0的控制位
  • TH0作为定时器,使用Timer1的控制位
  • Timer1在此模式下停止计数

8. 定时器配置流程

以模式1(16位定时器)为例,配置流程如下:

c 复制代码
void timer0_init(void) {
    // 1. 设置定时器工作模式
    TMOD &= 0xF0;      // 清零Timer0的模式位
    TMOD |= 0x01;      // 设置Timer0为模式1(16位定时器)
    
    // 2. 计算并设置定时器初值
    // 假设使用12MHz晶振,定时1ms
    // 机器周期 = 12 / 12MHz = 1μs
    // 需要计数值 = 1000μs / 1μs = 1000
    // 初值 = 65536 - 1000 = 64536
    TH0 = (65536 - 1000) / 256;  // 高8位
    TL0 = (65536 - 1000) % 256;  // 低8位
    
    // 3. 开启定时器中断
    ET0 = 1;           // 允许Timer0中断
    EA = 1;            // 开启总中断
    
    // 4. 启动定时器
    TR0 = 1;           // 启动Timer0
}

// Timer0中断服务函数
void timer0_isr(void) interrupt 1 {
    // 重新装载初值
    TH0 = (65536 - 1000) / 256;
    TL0 = (65536 - 1000) % 256;
    
    // 用户定时任务
    static unsigned int count = 0;
    if (++count >= 1000) {  // 1秒到
        count = 0;
        // 执行1秒任务
    }
}

9. 8位自动重装载定时器工作原理

模式2(8位自动重装载)的工作原理:

  1. 计数器:TLx作为8位加1计数器,范围0-255
  2. 重装载寄存器:THx保存重装载值(8位)
  3. 工作过程
    • TLx从初值开始计数,每个机器周期加1
    • 当TLx计数到255后,再加1变为0,产生溢出
    • 溢出瞬间,硬件自动将THx的值重新装载到TLx
    • 同时置位TFx标志,请求中断
  4. 优点
    • 无需在中断服务函数中重装初值,减少中断响应时间
    • 定时精度高,适合产生固定频率的脉冲

应用:串口通信的波特率发生器通常使用Timer1的模式2。

10. PWM周期

PWM(Pulse Width Modulation,脉冲宽度调制)是一种通过调节脉冲宽度来控制模拟信号的技术。

PWM周期:一个完整PWM波形所经历的时间,即从上升沿(或下降沿)到下一个上升沿(或下降沿)的时间间隔。

计算公式

复制代码
PWM周期(T) = 1 / PWM频率(f)

示例

  • 如果PWM频率为200Hz,则周期 T = 1/200 = 0.005秒 = 5ms
  • 如果PWM频率为1kHz,则周期 T = 1/1000 = 0.001秒 = 1ms

11. PWM占空比

PWM占空比:在一个PWM周期内,高电平时间占总周期的比例。

计算公式

复制代码
占空比(D) = (高电平时间 / PWM周期) × 100%

示例

  • 50%占空比:高电平和低电平时间各占一半
  • 25%占空比:高电平时间占1/4,低电平时间占3/4
  • 75%占空比:高电平时间占3/4,低电平时间占1/4

应用

  • LED亮度调节:改变占空比即可调节亮度
  • 电机速度控制:占空比越大,电机转速越快
  • 蜂鸣器音调控制:结合频率和占空比控制声音特性

12. 有源蜂鸣器与无源蜂鸣器

有源蜂鸣器

  • 内部结构:内置振荡电路,只需通电即可发声
  • 驱动方式:直流电压驱动,正负极接对即可
  • 声音特性:固定频率,不能改变音调
  • 控制简单:GPIO输出高电平即响,低电平即停
  • 应用场景:报警提示、按键音等不需要变化音调的场合
c 复制代码
// 有源蜂鸣器控制
#define BEEP_PIN P1_0

void beep_on(void) {
    BEEP_PIN = 1;  // 输出高电平,蜂鸣器响
}

void beep_off(void) {
    BEEP_PIN = 0;  // 输出低电平,蜂鸣器停
}

无源蜂鸣器

  • 内部结构:不含振荡电路,相当于一个微型扬声器
  • 驱动方式:需要方波信号驱动,频率决定音调
  • 声音特性:可通过改变频率产生不同音调,可播放简单音乐
  • 控制复杂:需要PWM或定时器产生特定频率的方波
  • 应用场景:电子琴、音乐播放、多音调报警等
c 复制代码
// 无源蜂鸣器驱动示例(产生1kHz声音)
void passive_beep_1kHz(void) {
    // 1kHz方波,周期1ms,高电平0.5ms,低电平0.5ms
    while(1) {
        BEEP_PIN = 1;
        delay_us(500);   // 高电平500μs
        BEEP_PIN = 0;
        delay_us(500);   // 低电平500μs
    }
}

对比总结

特性 有源蜂鸣器 无源蜂鸣器
内部振荡源
驱动信号 直流电平 方波信号
音调 固定,不可调 可调,可编程
控制复杂度 简单(GPIO输出) 复杂(需要PWM/定时器)
成本 较低 较低
应用 简单报警提示 音乐播放、多音调报警
相关推荐
尼喃3 小时前
HDMI/DP高速差分接口ESD保护:0.3pF超低电容PWESD-5VSDF方案详解
嵌入式硬件
ACP广源盛139246256733 小时前
GSV6155@ACP# 搭配 AI 服务器、AI PC 完整适配方案
大数据·服务器·人工智能·分布式·单片机·嵌入式硬件
Saniffer_SH4 小时前
NAND技术(二):从 Channel、Die/LUN、P/E Cycle 到 LDPC,一次讲透 NAND 里那些最容易误解的概念
人工智能·驱动开发·嵌入式硬件·测试工具·fpga开发·计算机外设·压力测试
辰哥单片机设计5 小时前
STM32音乐播放器
stm32·单片机·嵌入式硬件
周洲08305 小时前
STM32 串口指令控制系统|上位机下发命令控制 LED、继电器,通用指令解析框架
stm32·嵌入式硬件·mongodb
集芯微电科技有限公司6 小时前
PC3100H 专为TFT-LCD面板偏置电源设计双输出100m电流
人工智能·单片机·嵌入式硬件·神经网络·生成对抗网络
广州灵眸科技有限公司7 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) 系统操作-线进程操作
数据库·单片机·嵌入式硬件·算法·php
集芯微电科技有限公司8 小时前
各种大小尺寸TFT-LCD面板供电偏压电源方案IC
人工智能·单片机·嵌入式硬件·神经网络·生成对抗网络
FREEDOM_X8 小时前
嵌入式——定时器工作原理
linux·c语言·单片机·嵌入式硬件·ubuntu