1. GPIO(通用输入输出)
GPIO(Genral Purpose Input Output)是单片机与外界交互最基本的形式,每个 GPIO 引脚可独立配置为输入 / 输出模式。
1.1 输出模式(控制外部设备)
核心作用:主动控制引脚输出高电平 / 低电平(给外部设备发控制信号)。常见输出类型(51 单片机核心以推挽输出为主,扩展型支持以下类型):
- 推挽输出:可输出强高 / 低电平,驱动能力强(如直接驱动 LED);
- 开漏输出:仅能输出低电平,高电平需外接上拉电阻(用于 I2C 总线等);
- 复用开漏 / 推挽:引脚复用为外设功能(如串口、定时器)时的输出模式。
1.2 输入模式(检测外部信号)
核心作用:被动检测引脚的电平状态(接收外部设备的信号)。
- 上拉输入:引脚默认高电平,外部拉低时检测为低电平(51 按键常用);
- 下拉输入:引脚默认低电平,外部拉高时检测为高电平;
- 浮空输入:引脚电平由外部电路决定,易受干扰(少用);
- 模拟输入:用于 ADC 采样(51 基础款无 ADC,增强型支持)。
2. 独立按键
2.1 工作原理(51 单片机最常用)
- 未按下:按键引脚通过上拉电阻接 VCC,呈现高电平;
- 按下时:引脚与 GND 短路,呈现低电平;
- 核心判断逻辑:检测引脚是否为低电平,即可判断按键是否按下(需加防抖处理)。
2.2 简易防抖代码示例
c
运行
#include <reg51.h>
// 按键引脚定义(P3.2为按键1)
#define KEY1 P3_2
// 按键检测函数(带防抖,返回1表示按下,0表示未按下)
unsigned char key_scan(void)
{
if(KEY1 == 0) // 检测到引脚低电平
{
// 防抖延时(10ms,11.0592MHz晶振)
unsigned int i;
for(i=0; i<1000; i++);
if(KEY1 == 0) // 再次确认按下
{
while(KEY1 == 0); // 等待按键释放
return 1;
}
}
return 0;
}
void main(void)
{
while(1)
{
if(key_scan() == 1)
{
P1_0 = ~P1_0; // 按下按键翻转LED电平
}
}
}
3. 中断系统
3.1 中断核心概念
CPU 执行当前任务时,外界发生紧急事件,CPU 暂停当前任务→执行紧急事件→返回原任务继续执行,这个过程就是中断。核心优势:无需 CPU 轮询检测,实时响应外部事件(如按键、定时器溢出)。
3.2 中断源(51 单片机基础款)
| 中断源 | 对应引脚 / 功能 | 中断号 |
|---|---|---|
| 外部中断 0(INT0) | P3.2 引脚 | 0 |
| 外部中断 1(INT1) | P3.3 引脚 | 1 |
| 定时器 0 溢出中断 | Timer0 计数溢出 | 2 |
| 定时器 1 溢出中断 | Timer1 计数溢出 | 3 |
| 串口中断 | 串口收发完成 | 4 |
3.3 中断优先级与嵌套
- 中断优先级:多个中断同时请求时,CPU 优先处理优先级高的中断(51 可通过 IP 寄存器配置);
- 中断嵌套:CPU 处理低优先级中断时,可被高优先级中断打断(51 最多支持 2 层嵌套)。
3.4核心中断寄存器
(1)中断允许寄存器(IE)
| 位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| 符号 | EA | - | - | ES | ET1 | EX1 | ET0 | EX0 |
| 功能 | 总中断开关(1 = 开) | - | - | 串口中断允许 | 定时器 1 中断允许 | 外部中断 1 允许 | 定时器 0 中断允许 | 外部中断 0 允许 |
(2)定时器 / 计数器控制寄存器(TCON)(外部中断触发方式)
| 位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| 符号 | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
| 功能 | 定时器 1 溢出标志 | 定时器 1 启动位 | 定时器 0 溢出标志 | 定时器 0 启动位 | 外部中断 1 标志 | 外部中断 1 触发方式 | 外部中断 0 标志 | 外部中断 0 触发方式 |
- IT0/IT1=1:下降沿触发中断;
- IT0/IT1=0:低电平触发中断。
4. 定时器
4.1 核心作用
产生精准的时间基准,用于定时、延时、波特率发生器(串口)等场景。51 基础款有 2 个定时器:Timer0、Timer1,均为自增型(计数器从初值递增)。
4.2 工作原理
- 定时器内部有 16 位计数器(范围 0~65535);
- 给计数器设置初值,计数器按固定速率自增(12MHz 晶振下,1 个机器周期 = 1μs);
- 计数器递增到 65535 时溢出,向 CPU 发起中断请求;
- CPU 响应中断,执行定时器中断服务函数(需手动重装初值)。
4.3 定时器配置核心步骤(以 Timer0 为例)
c
运行
#include <reg51.h>
// 定时器0初始化(12MHz晶振,1ms中断)
void timer0_init(void)
{
TMOD &= 0xF0; // 1. 清空TMOD低4位(Timer0配置位)
TMOD |= 0x01; // 2. 配置Timer0为16位定时器模式(M1=0,M0=1)
TH0 = 0xFC; // 3. 加载初值(1ms:65536-1000=64536 → 0xFC18)
TL0 = 0x18;
ET0 = 1; // 4. 允许Timer0中断
EA = 1; // 5. 开启总中断
TR0 = 1; // 6. 启动Timer0
}
// 定时器0中断服务函数
void timer0_isr(void) interrupt 1
{
TH0 = 0xFC; // 重装初值(16位模式无自动重装,必须手动加)
TL0 = 0x18;
// 此处写定时任务(如LED翻转、计数等)
P1_0 = ~P1_0;
}
void main(void)
{
timer0_init();
while(1);
}
5. PWM 与蜂鸣器
5.1 PWM(脉冲宽度调制)
核心:让引脚产生周期性翻转的方波,通过调整周期和占空比控制外设。
- PWM 周期:一个方波的完整时间(如 1ms 周期 = 1000Hz 频率);
- PWM 占空比:高电平在一个周期内的占比(如 50% 占空比 = 高电平 0.5ms,低电平 0.5ms)。
51 单片机实现 PWM(软件模拟)
c
运行
#include <reg51.h>
// 配置PWM周期1ms(1000Hz),占空比50%
void pwm_output(void)
{
P1_0 = 1; // 高电平
unsigned int i;
for(i=0; i<500; i++); // 高电平持续0.5ms
P1_0 = 0; // 低电平
for(i=0; i<500; i++); // 低电平持续0.5ms
}
void main(void)
{
while(1)
{
pwm_output();
}
}
5.2 蜂鸣器
蜂鸣器发声原理:通过震荡产生声波,频率决定音调(高频 = 高音,低频 = 低音),占空比影响音量。
| 类型 | 核心区别 | 使用方式 |
|---|---|---|
| 有源蜂鸣器 | 内置震荡源 | 接 VCC 和 GND 即可发声(固定频率) |
| 无源蜂鸣器 | 无内置震荡源 | 需外部输入 PWM 方波(可调节频率) |
6. 核心知识点速记
- GPIO:输出模式控电平,输入模式检测电平;
- 独立按键:未按高电平,按下低电平,检测需防抖;
- 中断:紧急事件打断 CPU,51 基础款有 5 个中断源;
- 定时器:51 有 2 个自增型定时器,16 位计数器溢出触发中断;
- PWM:周期 = 方波总时间,占空比 = 高电平占比;
- 蜂鸣器:有源固定频率,无源需 PWM 驱动。