day42 51单片机中断系统与8×8 LED点阵扫描显示
一、51单片机引脚位操作 —— sbit
关键字
作用
sbit
是专用于 51 单片机架构的 C 语言扩展关键字,用于定义特殊功能寄存器(SFR)中的某一位,从而实现对单个 I/O 引脚的直接位操作。
示例代码
#include <reg51.h> // 包含51单片机寄存器定义头文件// 定义74HC595芯片控制引脚
sbit SER = P3^4; // 串行数据输入引脚,连接P3.4
sbit RCLK = P3^5; // 存储寄存器时钟引脚,连接P3.5
sbit SRCLK = P3^6; // 移位寄存器时钟引脚,连接P3.6
- SER = P3^4:将 P3 端口第 4 位(即 P3.4 引脚)命名为
SER
,后续可直接用SER = 1;
或SER = 0;
控制电平。 - RCLK = P3^5:控制 74HC595 的存储寄存器锁存时钟。
- SRCLK = P3^6:控制 74HC595 的移位寄存器时钟。
✅ 应用场景:精准控制单个引脚,如驱动外设芯片、LED、按键检测等。
二、74HC595 串转并芯片工作原理
功能概述
74HC595 是一个 8 位串行输入、并行输出的移位寄存器芯片,通过 3 根控制线(SER、SRCLK、RCLK)即可控制 8 路输出,极大节省单片机 I/O 资源。
关键引脚说明
引脚名 | 功能说明 |
---|---|
SER | 串行数据输入端,逐位送入数据 |
SRCLK | 移位寄存器时钟,上升沿将 SER 数据移入内部寄存器 |
RCLK | 存储寄存器时钟,上升沿将移位寄存器数据锁存到输出端口 |
行选通函数实现
/*** 选择8*8点阵的行* @param num 要选择的行号(0-7)* 通过74HC595串行输入数据,控制对应行的选通*/
void led_rect_select(unsigned char num)
{unsigned char i = 0;RCLK = 0; // 拉低存储寄存器时钟,准备接收数据SRCLK = 0; // 拉低移位寄存器时钟,准备移位操作// 循环8次,串行输入8位数据for(i = 0; i < 8; i++){SRCLK = 0; // 拉低移位时钟,准备输入数据// 当i等于要选择的行号时,SER置1,否则置0(num == i) ? (SER = 1) : (SER = 0);SRCLK = 1; // 拉高移位时钟,将SER数据移入移位寄存器}RCLK = 1; // 拉高存储寄存器时钟,将移位寄存器数据锁存到输出寄存器
}
- 运行理想结果:调用
led_rect_select(3)
时,74HC595 输出端口第 3 位为高电平,其余为低,即选通第 3 行 LED。
三、8×8 LED点阵扫描显示原理
硬件结构
- 8 行 × 8 列共 64 个 LED,采用“行选通 + 列数据”方式控制。
- 本例使用共阴极点阵:行选通为低电平有效,列数据为高电平时对应 LED 点亮。
逐行扫描 + 视觉暂留
- 原理:每次只选通一行,输出该行的列数据,快速循环扫描 8 行(每行约 1ms),利用人眼视觉暂留效应(约 10~20ms)形成完整稳定图像。
- 优势:节省 I/O 资源,仅需 3 个引脚(74HC595)控制 8 行 + 8 个引脚(P0)控制 8 列。
显示函数实现
/*** 在8*8点阵上显示图案* 通过逐行扫描的方式,显示预设的图案(此处为数字"1")*/
void led_8_8_show(void)
{// 存储8*8点阵每行要显示的数据,对应显示数字"1"unsigned char led_1_array[8] = {0x0, 0x10, 0x30, 0x10, 0x10, 0x10, 0x38, 0x0};unsigned char i = 0;// 逐行扫描显示for(i = 0; i < 8; i++){ P0 = 0xff; // 关闭当前行显示,避免串扰(共阴极,全高电平熄灭)led_rect_select(i); // 选择第i行P0 = ~led_1_array[i]; // 输出第i行的列数据(取反是因为共阴极点阵:数据1=高电平=点亮)delay(1); // 延时1ms,保持当前行显示,利用视觉暂留形成稳定图像}
}
- 图案数组说明:
led_1_array[8] = {0x0, 0x10, 0x30, 0x10, 0x10, 0x10, 0x38, 0x0};
- 例如
0x10
=00010000B
,表示该行第 5 列 LED 点亮。
- 取反原因:共阴极点阵中,列需输出高电平才能点亮 LED,而数组中
1
表示“点亮”,故需~
取反后送 P0 口。 - 理想运行结果:点阵稳定显示数字“1”的图案。
四、延时函数实现与作用
功能
通过空循环消耗 CPU 时间,实现软件延时,用于控制扫描频率、稳定显示亮度。
实现代码
/*** 延时函数* @param i 延时参数,控制延时时间长短* 通过双重循环实现延时,外层循环10次,内层循环由i控制*/
void delay(unsigned int i)
{unsigned int num = i;int j = 0;for(j = 0; j < 10; j++){num = i;while(num--); // 内层循环,通过递减计数实现延时}
}
- 调节方式:增大
i
值可延长延时。 - 应用场景:
- 点阵扫描中,每行延时约 1ms(
delay(1)
),总周期约 8ms,刷新率约 125Hz,远高于视觉暂留阈值(约 50Hz),显示稳定无闪烁。 - 延时过短 → 亮度不足;过长 → 闪烁明显。
- 点阵扫描中,每行延时约 1ms(
五、数组在硬件控制中的应用
1. 数码管段码数组(备用)
/*** 共阴极数码管段码数组* 索引0-9分别对应数字0-9的十六进制段码*/
unsigned char digit_data[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
- 虽未在主逻辑中使用,但体现“用数组存储固定硬件控制数据”的设计思想。
2. 点阵图案数组
unsigned char led_1_array[8] = {0x0, 0x10, 0x30, 0x10, 0x10, 0x10, 0x38, 0x0};
- 每个元素对应一行 LED 的亮灭状态。
- 修改数组即可切换显示图案,如改为
0x7F, 0x49, 0x49, 0x49, 0x36, 0x0, 0x0, 0x0
可显示字母“E”。
六、中断系统详解
中断基本概念
- 中断源:引起中断产生的事件(如外部信号、定时器溢出、串口接收完成等)。
- 中断服务程序(ISR):中断产生后 CPU 跳转执行的处理函数。
- 程序计数器(PC):指向当前执行指令地址,中断发生时自动压栈保存,中断返回时恢复。
中断系统作用
使 CPU 具备实时响应外部紧急事件的能力,提高系统效率与实时性。
中断响应流程
- 当前指令执行完毕。
- PC 值压入堆栈。
- 现场保护(可选,由程序员实现)。
- 屏蔽同级/低级中断。
- PC 装载中断向量地址(跳转至 ISR)。
- 执行中断服务程序。
RETI
指令返回:恢复 PC,恢复中断设置,继续原程序。
✅ 中断服务程序特点:无参数、无返回值、执行要快、尽量简短。
七、STC89C51RC/RD+ 中断系统特性
中断源(共8个)
中断源 | 中断号 | 中断向量地址 | 查询优先级 |
---|---|---|---|
外部中断0 (INT0) | 0 | 0003H | 最高 |
定时器0 | 1 | 000BH | |
外部中断1 (INT1) | 2 | 0013H | |
定时器1 | 3 | 001BH | |
UART 串口中断 | 4 | 0023H | |
定时器2 | 5 | 002BH | |
外部中断2 (INT2) | 6 | 0033H | |
外部中断3 (INT3) | 7 | 003BH | 最低 |
中断优先级
- 支持 4 级优先级(通过
IPH
寄存器设置)。 - 若仅使用
IP
或XICON
,则为传统 8051 的 2 级优先级。 - 高优先级可打断低优先级 → 支持中断嵌套。
- 同级中断按查询次序响应。
中断控制寄存器
- EA (IE.7):总中断允许位,置 1 开启全局中断。
- EX0 (IE.0):外部中断 0 允许位。
- IT0 (TCON.0):外部中断 0 触发方式(0=低电平,1=下降沿)。
八、C语言中断编程示例
初始化与主函数
// 外部中断0初始化函数
void eint0_init(void)
{IT0 = 1; // 设置外部中断0为边沿触发方式(下降沿触发)EX0 = 1; // 使能外部中断0EA = 1; // 使能总中断
}// 主函数
void main(void)
{unsigned char i = 0;eint0_init(); // 调用外部中断0初始化函数while(1) // 无限循环,等待中断发生{// 主程序可执行其他任务,中断发生时自动跳转处理}
}
中断服务程序(ISR)
// 外部中断0处理函数,interrupt 0 表示该函数为外部中断0的中断服务程序
void eint0_handler(void) interrupt 0
{P2 = 0xaa; // 中断发生时,P2口输出0xAA(10101010B),控制外部LED或指示灯
}
- interrupt 0:指定该函数为中断号 0(外部中断 0)的服务程序。
- 理想运行结果:当外部中断 0 引脚(P3.2)检测到下降沿,CPU 跳转执行
eint0_handler()
,P2 口输出0xAA
,之后自动返回主循环。
📌 注意:ISR 中避免使用延时函数或复杂操作,防止阻塞其他中断。
九、中断向量表与响应机制图示
- 中断向量表:包含各中断服务函数入口地址(如
fun0() interrupt 0
对应 0003H)。 - CPU 响应中断时,根据中断源自动跳转至对应向量地址。
- 中断响应步骤:
- 当前指令执行完。
- PC 压栈。
- 现场保护(程序员手动)。
- 屏蔽同级中断。
- PC = 中断向量地址。
- 执行 ISR。
RETI
返回,恢复现场。
- 中断触发流程:中断源(如 eint0)→ CPU 查询中断向量表 → 跳转 ISR(如
eint0_handler()
)→ 执行 →RETI
返回。
十、总结
本节内容涵盖 51 单片机两大核心模块:
1. 硬件驱动层
- 使用
sbit
精准控制 I/O 引脚。 - 驱动 74HC595 实现串转并,节省 I/O。
- 8×8 LED 点阵逐行扫描 + 视觉暂留显示技术。
- 延时函数调节扫描频率。
- 数组存储硬件控制数据,便于图案切换。
2. 中断系统层
- 中断源、中断向量、中断优先级机制。
- 中断响应流程与现场保护。
- C 语言中断服务程序编写规范(
interrupt n
)。 - 外部中断初始化与触发方式设置。
- 支持中断嵌套与多级优先级。
✅ 综合应用价值:掌握本节内容,可独立完成“按键中断控制点阵显示切换”、“定时器中断动态刷新图案”等复杂嵌入式项目,是迈向高级单片机开发的坚实基础。