Linux入门DAY40(51 单片机入门:GPIO、中断、定时器、PWM、蜂鸣器完整梳理)

#51单片机 #GPIO #定时器 #中断 #PWM #单片机入门

前言

最近在学习 51 单片机基础,把 GPIO、外部中断、定时器、PWM、蜂鸣器这些核心概念做一次系统整理,同时结合代码踩坑记录,适合刚入门单片机的同学参考。硬件以 STC89C51/AT89C51 为主,晶振常用12MHZ11.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:

  1. return 0写死返回值,无论哪个按键按下永远返回 0;
  2. 错误使用P1 & (1<<8),P1 口只有 P1.0~P1.7,没有 P1.8;
  3. 缺少机械按键软件消抖,会出现误触发。

✅ 核心要点:读引脚前写 1;增加延时消抖;正确 return 按键编号。

二、中断系统

什么是中断

当 CPU 正在执行一个任务,外部紧急事件到来打断当前程序;CPU 保存现场,跳转执行中断服务函数;处理完毕回到原来代码继续执行。

51 单片机 5 大中断源

  1. 外部中断 0:P3.2
  2. 外部中断 1:P3.3
  3. 定时器 0 中断
  4. 定时器 1 中断
  5. 串口中断
  • 外部中断:引脚电平变化触发中断。
  • 中断优先级:多个中断同时到来,优先处理优先级高的中断。
  • 中断嵌套:处理中断过程中可以响应更高优先级中断,51 最多两层嵌套。

中断完整处理流程

  1. 中断源发起中断请求;
  2. 判断 CPU 总中断开关、该中断源子开关是否打开;
  3. 判断中断优先级;
  4. 保护现场;
  5. 执行中断服务函数;
  6. 恢复现场,回到主程序断点继续运行。

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

  1. 12MHZ 晶振: 计数次数 = 1000us /1us =1000 初值 = 65535 −1000 = 64535 TH0 = 64535 >> 8; TL0 = 64535;
  2. 11.0592MHZ 晶振: 计数次数 = 1000 /1.1 ≈909 初值 = 65535 −909 =64626

还有 8 位自动重装模式,多用于串口波特率生成。

定时器工作流程:

  1. 设置 TH0、TL0 装载初值
  2. 打开定时器,开始计数
  3. 计数器不断自增cnt++
  4. 计数到 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

五、蜂鸣器

  1. 有源蜂鸣器:自带振荡源,通电直接发出固定频率声音,只需要给高低电平控制开关。
  2. 无源蜂鸣器:内部没有震荡源,通电不会响;需要输入一定频率的方波(定时器 + PWM)才可以发声;改变 PWM 频率可以改变音调。

想要无源蜂鸣器发出指定音调:定时器输出对应频率 PWM,设置 50% 占空比驱动。

六、学习总结

  1. 51 准双向 IO 作为输入,一定要先写 1,否则读不到正确电平;
  2. 中断:中断请求→开关判断→优先级→保护现场→中断服务函数→恢复现场;
  3. 定时器核心:机器周期计算,初值公式 65535-计数次数
  4. PWM 依靠定时器定时翻转 IO,改变频率和占空比实现调光、无源蜂鸣器发声;
  5. 机械按键必须做消抖处理,延时消抖简单,但是阻塞程序;项目中优先用定时器做非阻塞消抖。
相关推荐
LCG元2 小时前
STM32F103 复位来源诊断实战:RCC_CSR 标志位判优、BKP 复位计数持久化与六种复位源注入实测
stm32·单片机·嵌入式硬件
HUI-4743 小时前
EG1177|SOP‑7 内置 100V‑NMOS 异步降压,20‑90V 高压恒压恒流小功率电源优选
嵌入式硬件·硬件工程
Doraemomo3 小时前
IMX6ULL裸机开发——I2C通信协议
arm开发·嵌入式硬件·imx6ull
国产HT1621B4 小时前
显示省不了电,休眠才见真章:1621 低功耗实操
驱动开发·单片机·嵌入式硬件·led驱动·lcd驱动
国科安芯4 小时前
低轨卫星姿轨控系统中高可靠嵌入式控制单元的设计与验证
单片机·mcu·低轨卫星·星间链路·卫星姿轨控
尼喃5 小时前
Type-C快充取电芯片工作流程:从适配器识别到电压输出
嵌入式硬件
昌原的儿子LEO6 小时前
ARM 汇编核心知识点总结
嵌入式硬件·学习
老当益壮梁奶奶6 小时前
ARM 汇编学习笔记(二)启动代码、指令、函数调用与 C 混合编程
c语言·arm开发·单片机·嵌入式硬件·51单片机
学习FPGA的电气小兴兴6 小时前
基于FPGA的CORDIC向量模式实现arctan运算,Verilog HDL实现
嵌入式硬件·fpga开发·数字信号处理·verilog·fpga·cordic·arctan