#51单片机 #GPIO #定时器 #中断 #PWM #单片机入门
前言
最近在学习 51 单片机基础,把 GPIO、外部中断、定时器、PWM、蜂鸣器这些核心概念做一次系统整理,同时结合代码踩坑记录,适合刚入门单片机的同学参考。硬件以 STC89C51/AT89C51 为主,晶振常用12MHZ和11.0592MHZ。
知识点来源课堂笔记,包含基础概念、计算公式、代码示例、常见踩坑点。
一、GPIO 通用输入输出
GPIO(General Purpose Input/Output)通用目的输入输出,是单片机和外部设备交互最基础的方式。
1. 输入模式
作用:检测引脚电平变化,典型应用:按键检测、外部电平信号采集。
51 是准双向口:做输入前,必须先向引脚写 1,内部上拉开启,才能正确读取外部电平。
// 将P1.4~P1.7设置为输入,写1开启上拉
P1 |= (0x0F << 4);
P3 |= (1 << 5);
按键按下,引脚被拉到 GND,引脚读到低电平;按键松开,内部上拉维持高电平。
其他 MCU (STM32) 输入模式区分:上拉输入、下拉输入、浮空输入、模拟输入;输出模式:推挽输出、开漏输出、复用推挽、复用开漏。51 没有这么多模式,为准双向 IO。
2. 输出模式
输出高低电平,控制 LED、继电器、蜂鸣器等外设。
按键驱动踩坑回顾
之前写独立按键代码遇到两个致命 BUG:
return 0写死返回值,无论哪个按键按下永远返回 0;- 错误使用
P1 & (1<<8),P1 口只有 P1.0~P1.7,没有 P1.8; - 缺少机械按键软件消抖,会出现误触发。
✅ 核心要点:读引脚前写 1;增加延时消抖;正确 return 按键编号。
二、中断系统
什么是中断
当 CPU 正在执行一个任务,外部紧急事件到来打断当前程序;CPU 保存现场,跳转执行中断服务函数;处理完毕回到原来代码继续执行。
51 单片机 5 大中断源
- 外部中断 0:
P3.2 - 外部中断 1:
P3.3 - 定时器 0 中断
- 定时器 1 中断
- 串口中断
- 外部中断:引脚电平变化触发中断。
- 中断优先级:多个中断同时到来,优先处理优先级高的中断。
- 中断嵌套:处理中断过程中可以响应更高优先级中断,51 最多两层嵌套。
中断完整处理流程
- 中断源发起中断请求;
- 判断 CPU 总中断开关、该中断源子开关是否打开;
- 判断中断优先级;
- 保护现场;
- 执行中断服务函数;
- 恢复现场,回到主程序断点继续运行。
IE 寄存器:中断允许寄存器;中断向量:相当于标号,CPU 依靠中断向量找到对应的中断服务函数。
外部中断 0 简单初始化模板:
void int0_init(void)
{
// IT0、EX0、EA 配置,开启外部中断0
}
三、定时器原理
定时器用来做精准定时,不依赖软件延时,不阻塞主循环。
51 定时器模式 1 为16 位自增计数器 ,
THx存高 8 位,TLx存低 8 位;从初值不断向上计数,计到 65535 再加 1 就溢出,溢出触发定时器中断。
时钟计算(重点公式)
51 单片机:机器周期 = 晶振频率 /12
- 晶振
12MHZ:机器周期 =12M/12 = 1MHZ,计数 + 1 花费时间:1us - 晶振
11.0592MHZ:机器周期≈0.9MHZ,计数 + 1≈1.1us
定时时间 = 需要计数次数 × 机器周期 定时器初值 = 65535 − 需要计数次数
示例:1ms 定时计算
1ms = 1000us
- 12MHZ 晶振: 计数次数 = 1000us /1us =1000 初值 = 65535 −1000 = 64535
TH0 = 64535 >> 8; TL0 = 64535; - 11.0592MHZ 晶振: 计数次数 = 1000 /1.1 ≈909 初值 = 65535 −909 =64626
还有 8 位自动重装模式,多用于串口波特率生成。
定时器工作流程:
- 设置 TH0、TL0 装载初值
- 打开定时器,开始计数
- 计数器不断自增
cnt++ - 计数到 65535 溢出,向 CPU 申请定时器中断
四、PWM 脉冲宽度调制
PWM 输出周期性方波,不断翻转引脚电平。
- PWM 周期:一个完整方波的时间,从上升沿到下一次上升沿。
- 占空比:一个周期内高电平时间占整个周期的百分比。
应用场景:LED 亮度调节、屏幕背光调节、无源蜂鸣器发声、电机调速。
例题:无源蜂鸣器 200HZ,占空比 50%
周期 T = 1 / 200HZ = 0.005s 50% 占空比:高电平 = 2.5ms,低电平 = 2.5ms 12M 晶振,1us 计数一次 计数次数 = 2500 初值 = 65535 − 2500 = 63035
再举例:400HZ,占空比 50% 周期 = 1/400 =0.0025s;半周期 = 0.00125s 计数次数 = 1250;初值 = 65535‑1250=64285
五、蜂鸣器
- 有源蜂鸣器:自带振荡源,通电直接发出固定频率声音,只需要给高低电平控制开关。
- 无源蜂鸣器:内部没有震荡源,通电不会响;需要输入一定频率的方波(定时器 + PWM)才可以发声;改变 PWM 频率可以改变音调。
想要无源蜂鸣器发出指定音调:定时器输出对应频率 PWM,设置 50% 占空比驱动。
六、学习总结
- 51 准双向 IO 作为输入,一定要先写 1,否则读不到正确电平;
- 中断:中断请求→开关判断→优先级→保护现场→中断服务函数→恢复现场;
- 定时器核心:机器周期计算,初值公式
65535-计数次数;- PWM 依靠定时器定时翻转 IO,改变频率和占空比实现调光、无源蜂鸣器发声;
- 机械按键必须做消抖处理,延时消抖简单,但是阻塞程序;项目中优先用定时器做非阻塞消抖。