文章目录
- 前言
- 一、先搞懂本质:单片机芯片内部有什么?
- [1. 核心模块一览](#1. 核心模块一览)
- [2. 容易混淆的概念:内部架构 ≠ 最小系统](#2. 容易混淆的概念:内部架构 ≠ 最小系统)
- 二、数码管动态扫描:从电路到代码彻底搞懂
- [1. 电路结构拆解](#1. 电路结构拆解)
- [2. 三极管的两个核心作用](#2. 三极管的两个核心作用)
- [3. 怎么判断共阴极还是共阳极?](#3. 怎么判断共阴极还是共阳极?)
- [4. 动态扫描核心原理](#4. 动态扫描核心原理)
- [5. 标准共阴极段码表(0-9)](#5. 标准共阴极段码表(0-9))
- 三、定时器系统:从原理到计算完整掌握
- [1. 核心本质](#1. 核心本质)
- [2. 核心控制寄存器](#2. 核心控制寄存器)
- [3. 四种工作方式](#3. 四种工作方式)
- [4. 定时时间计算公式(方式1)](#4. 定时时间计算公式(方式1))
- [5. 定时器中断完整工作流程](#5. 定时器中断完整工作流程)
- 四、中断系统:三个"I"彻底分清
- [1. IT0 / IE / IE0 核心区别](#1. IT0 / IE / IE0 核心区别)
- [2. 中断函数为什么加 interrupt 0 ?](#2. 中断函数为什么加 interrupt 0 ?)
- 五、今日踩坑与易错点总结
- 学习总结
前言
今天是学习硬件的第二天,从第一天的寄存器、外部中断入门,深入到了数码管动态扫描原理、定时器系统完整工作机制、单片机内部架构三大核心模块。不再是只会抄代码改参数,而是对着原理图搞懂了每一个元件的作用、每一行代码对应的硬件变化,也理清了软件和硬件之间是怎么通过寄存器交互的。
这篇博客把今天所有知识点系统梳理一遍,既是自己的学习沉淀,也希望能帮到同样入门的同学。
一、先搞懂本质:单片机芯片内部有什么?
之前写代码只知道P0、P1、定时器这些名字,今天对着架构图终于搞懂了它们在芯片里的位置和关系。一颗51单片机芯片内部,本质上就是「CPU内核 + 存储 + 各类外设」的集合,全部集成在一块硅片上。
1. 核心模块一览
| 模块 | 位置与本质 | 核心作用 | 对应代码 |
|---|---|---|---|
| kernel内核 | 左上角,计算控制中心 | 取指令、运算、控制所有外设协同工作 | 所有C代码最终都交给它执行 |
| GPIO模块 | 右上角,P0~P3四组IO口 | 芯片和外部硬件的唯一桥梁,输入输出电平 | 数码管段选P0、位选P1、按键P3 |
| 定时器模块 | 中间,2个独立定时器 | 硬件自动计数/计时,溢出触发中断 | 50ms定时、秒闪LED、数码管扫描 |
| RAM | 左下角,数据存储器 | 运行时临时存放变量、栈、寄存器映射,掉电丢失 | cnt、LedState、局部变量 |
| Flash | 底部中间,程序存储器 | 永久存放烧录的程序代码,掉电不丢失 | main函数、中断函数、段码数组 |
| UART控制器 | 右下角,串行通信外设 | 和电脑/其他设备双向串行通信 | 烧录程序、串口调试打印 |
2. 容易混淆的概念:内部架构 ≠ 最小系统
很多初学者会搞混:
- 图里的是芯片内部架构:芯片本身已经集成好的硬件,我们写代码就是操控这些内部模块
- 最小系统是外部电路:让芯片能跑起来最少需要的外部电路,包括电源、晶振、复位、下载电路
简单说:图里讲的是「芯片里面有什么」,最小系统讲的是「芯片外面最少要接什么才能用」。
二、数码管动态扫描:从电路到代码彻底搞懂
今天对着原理图把数码管驱动扒透了,不再是只会调用DisplayNum函数。
1. 电路结构拆解
四位动态数码管电路分成位选控制 和段选控制两部分:
- 位选电路:4个S8050 NPN三极管做电子开关,P1.0~P1.3通过1K电阻控制基极,发射极接地,集电极接数码管COM公共端。P1.x输出高电平时三极管导通,对应位公共端接地,具备点亮条件。
- 段选电路:4位数码管的同名段全部并联,通过100Ω排阻接到P0口。P0输出的段码同时送到所有位,但只有被选中的那位才会发光。
2. 三极管的两个核心作用
这是之前一直疑惑的点,今天彻底搞懂:
- 电子开关:受单片机引脚控制,快速切换每一位的通断,实现轮流点亮
- 电流放大:单片机IO口驱动能力弱,三极管用小电流控制大电流,给数码管提供足够工作电流,保证亮度
3. 怎么判断共阴极还是共阳极?
看公共端的接法:
- 公共端通过三极管接GND,导通时接地,段脚高电平点亮 → 共阴极
- 公共端接VCC,段脚低电平点亮 → 共阳极,三极管要用PNP型,段码全部取反
对应我们的电路:P1.x写1 → 三极管导通 → COM端接地(0)→ 段脚高电平点亮,就是标准共阴极。
4. 动态扫描核心原理
因为段选是共用的,同一时间只能亮一位。利用人眼视觉暂留效应(约100ms),快速轮流点亮每一位,只要一轮扫描时间小于100ms,看起来就是四位同时常亮。
标准扫描流程:
- 关闭上一位位选
- P0输出当前位的段码
- 打开当前位位选
- 延时1~2ms
- 循环切换下一位
规范顺序:先关位选、再换段码、最后开位选,可以彻底消除鬼影。
5. 标准共阴极段码表(0-9)
unsigned char NumCode[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
// 对应数字: 0 1 2 3 4 5 6 7 8 9
三、定时器系统:从原理到计算完整掌握
定时器是51单片机最核心的外设,今天从本质到计算、从寄存器到中断流程完整走通了。
1. 核心本质
定时器本质是可预置初值的16位加1计数器,每来一个脉冲自动加1,加到最大值溢出时,硬件自动置溢出标志,可触发中断。
两种工作模式:
- 定时器模式:计数内部系统时钟脉冲,用于精确定时
- 计数器模式:计数外部引脚脉冲,用于统计事件个数
2. 核心控制寄存器
定时器的所有功能都通过寄存器配置,对应代码逐行对应:
- TMOD寄存器:设置工作模式和工作方式,低4位控T0,高4位控T1。规范写法「先清后或」,避免覆盖另一个定时器的配置。
- TCON寄存器:控制启停(TRx位)、标记溢出状态(TFx位)。
- THx/TLx:16位计数器的高低8位初值寄存器,决定定时时长。
- IE寄存器:控制定时器中断开关(ETx位)和全局中断总开关(EA位)。
3. 四种工作方式
| 工作方式 | M1 M0 | 位数 | 核心特点 | 典型应用 |
|---|---|---|---|---|
| 方式0 | 0 0 | 13位 | 历史兼容,基本不用 | - |
| 方式1 | 0 1 | 16位 | 计数范围0~65535,溢出需手动重装初值 | 精确定时、延时(最常用) |
| 方式2 | 1 0 | 8位 | 自动重装初值,无需手动赋值 | 串口波特率发生器 |
| 方式3 | 1 1 | 两个8位 | 仅T0可用,T1停止工作 | 特殊场景 |
4. 定时时间计算公式(方式1)
51单片机计数脉冲 = 机器周期 = 12个时钟周期 \\text{机器周期} = \\frac{12}{\\text{晶振频率}} \\text{初值} = 65536 - \\frac{\\text{定时时间}}{\\text{机器周期}}
以11.0592MHz晶振、50ms定时为例:
- 机器周期 ≈ 1.085μs
- 计数次数 = 50000 / 1.085 ≈ 46080
- 初值 = 65536 - 46080 = 19456 = 0x4C00
- 即
TH0=0x4C; TL0=0x00;
5. 定时器中断完整工作流程
- 初始化:配置TMOD、装载初值、开中断、启动定时器
- 计数溢出:硬件自动计数,溢出后置TF0标志,发中断请求
- 中断响应:CPU跳转到中断服务函数
- 中断处理:手动重装初值、计数累加、置业务标志位
- 主循环处理:检测标志位,执行对应业务逻辑
核心设计思想:中断只做计时和置标志,业务逻辑放主循环,中断函数尽量短。
四、中断系统:三个"I"彻底分清
昨天初步接触了外部中断,今天把最容易混淆的三个概念彻底理清楚了。
1. IT0 / IE / IE0 核心区别
| 名称 | 所在位置 | 本质 | 作用 | 操作主体 |
|---|---|---|---|---|
| IT0 | TCON寄存器bit0 | 配置位 | 设置中断触发方式(下降沿/低电平) | 代码手动配置 |
| IE | 独立8位寄存器 | 开关组 | 全局总闸+各中断分闸 | 代码手动配置 |
| IE0 | TCON寄存器bit1 | 标志位 | 标记中断请求有没有发生 | 硬件自动置1/清0 |
最大误区:IE寄存器的第0位叫EX0,不叫IE0!90%初学者都会记错。
2. 中断函数为什么加interrupt 0?
interrupt是Keil C51的扩展关键字,作用有三个:
- 告诉编译器这是中断函数,自动生成保护现场、恢复现场的代码
- 生成
RETI中断返回指令,通知硬件中断处理完毕 - 把函数绑定到对应中断号的中断向量表,硬件触发时能准确跳转
中断号对应:0-外部中断0、1-定时器0、2-外部中断1、3-定时器1、4-串口。
五、今日踩坑与易错点总结
坑1:数码管扫描放在if条件里
最开始把DisplayNum放在了if(LedState)里面,只有1秒才刷新一次,导致数码管严重闪烁甚至熄灭。 教训:动态扫描必须放在主循环最外层,无条件持续刷新;标志位只控制数字更新,不控制显示刷新。
坑2:段码表缺少数字4
最开始的段码表漏掉了数字4的0x66,导致显示4的时候变成了5。 教训:直接套用标准段码表,写完核对0-9共10个值。
坑3:定时器方式1忘记重装初值
方式1没有自动重装功能,如果中断里不手动写TH0、TL0,溢出后从0开始计数,定时就完全不准了。 教训:方式1的中断函数第一行就先重装初值。
坑4:TMOD直接赋值
直接写TMOD=0x01会覆盖定时器1的配置,规范写法是先清后或:TMOD &= ~0x03; TMOD |= 0x01;
学习总结
第二天的学习,最大的收获是建立了「从硬件电路到寄存器再到代码」的完整对应关系。不再是对着代码猜硬件,而是看着原理图就能知道代码该怎么写、每一行在操控什么。
核心收获:
- 搞懂了单片机内部的六大模块,分清了片上外设和外部最小系统
- 彻底理解数码管动态扫描原理,知道了三极管的作用、共阴共阳的判断
- 完整掌握定时器系统,从原理、寄存器到计算、中断流程全链路打通
- 理清了中断系统三个易混概念,知道了中断关键字的底层作用
接下来计划学习串口通信,把UART控制器用起来,实现单片机和电脑的双向数据交互。