目录
[2.0 LED原理图](#2.0 LED原理图)
[2.1 项目示例1:点亮一个LED](#2.1 项目示例1:点亮一个LED)
[2.2 项目示例2: LED闪烁](#2.2 项目示例2: LED闪烁)
[✅STC-ISP 软件自动生成软件延时函数:](#✅STC-ISP 软件自动生成软件延时函数:)
[✅LED 闪烁主函数](#✅LED 闪烁主函数)
[2.3 项目示例3:LED流水灯](#2.3 项目示例3:LED流水灯)
2.0 LED原理图

LED 电平规则 : 低电平 = LED点亮 、 高电平 = LED熄灭
2.1 项目示例1: 点亮一个LED
✅点亮LED主函数
cpp
#include <REGX52.H>// 引入52单片机寄存器头文件,REGX52兼容所有51/52内核单片机
void main()
{
// P2=0xFE; // 二进制11111110,仅点亮P2.0
P2=0x55; // 二进制01010101,P2口LED 隔一个亮一个(偶脚亮、奇脚灭)
while(1); // 死循环,保持引脚电平状态,防止程序跑飞
}
2.2 项目示例2: LED闪烁
✅ STC-ISP 软件自动 生成软件延时函数:

✅ LED 闪烁主函数
cpp
#include <REGX52.H> // 51/52单片机寄存器定义头文件,必备,用于操作P2口等IO引脚
#include <INTRINS.H> // 内核函数头文件,必须包含,因为代码中用到了 _nop_() 空操作函数
/************************** 延时函数 **************************/
void Delay500ms(void) // 延时函数名:延时500毫秒
{ // @12MHz :该延时函数的适配条件【晶振=12MHz】,精准延时500ms
unsigned char i, j, k; // 定义3个无符号字符型变量,用于三层循环计数实现延时
_nop_(); // 执行1个空操作指令,作用:延时微调,保证500ms延时精度,无实质逻辑
i = 4; // 外层循环初始化计数值
j = 205; // 中层循环初始化计数值
k = 187; // 内层循环初始化计数值
do // 三层嵌套循环:通过变量自减+循环,消耗CPU运行时间实现软件延时
{
do
{
while (--k); // 内层k自减到0,再执行中层
} while (--j); // 中层j自减到0,再执行外层
} while (--i); // 外层i自减到0,延时函数执行完毕
}
/************************** 主函数-程序入口 **************************/
void main(void)
{
while(1) // 死循环,程序上电后一直重复执行循环内的代码,永不停止
{
P2=0xFE; // 赋值二进制 1111 1110 → P2.0引脚置低电平点亮对应LED,其余引脚高电平灯灭
Delay500ms();// 调用延时函数,保持LED点亮状态 500毫秒
P2=0xFF; // 赋值二进制 1111 1111 → P2口所有引脚置高电平,熄灭全部LED
Delay500ms();// 调用延时函数,保持LED熄灭状态 500毫秒
}
}
STC小程序生成软件延时函数中包含 代码 nop ,要引入头文件: #include ,否则会报错
2.3 项目示例3: LED流水灯
✅ 基础版主函数:
cpp
#include <REGX52.H> // 51/52单片机寄存器头文件,用于操作P2口IO引脚,必备头文件
#include <INTRINS.H> // 单片机内核函数头文件,必须包含,因为延时函数中用到了_nop_()空操作函数
/********************* 延时函数:软件延时500毫秒 *********************/
void Delay500ms() // 函数名:延时500ms,单位:毫秒(ms)
{ // @12MHz :该延时函数适配【12MHz晶振】,延时精度准确,51单片机标配
unsigned char i, j, k; // 定义3个无符号字符型变量,用于三层嵌套循环计数,消耗CPU时间实现延时
_nop_(); // 执行1个CPU空操作,仅用于延时精度微调,不影响程序逻辑
i = 4; // 外层循环计数初始化
j = 205; // 中层循环计数初始化
k = 187; // 内层循环计数初始化
do // 三层do-while嵌套循环,通过变量自减至0实现精准延时
{
do
{
while (--k); // 内层k自减,减到0后执行下一层循环
} while (--j); // 中层j自减,减到0后执行外层循环
} while (--i); // 外层i自减,减到0后延时函数执行完毕
}
/********************* 主函数:程序入口,流水灯核心逻辑 *********************/
void main()
{
while(1) // 死循环,无限重复执行循环内代码,实现LED持续流水灯效果
{
P2=0xFE; // 二进制:1111 1110 → 仅P2.0引脚置低电平,对应第一个LED点亮
Delay500ms();// 保持当前点亮状态500ms,肉眼可见的亮灯时长
P2=0xFD; // 二进制:1111 1101 → 仅P2.1引脚置低电平,对应第二个LED点亮
Delay500ms();
P2=0xFB; // 二进制:1111 1011 → 仅P2.2引脚置低电平,对应第三个LED点亮
Delay500ms();
P2=0xF7; // 二进制:1111 0111 → 仅P2.3引脚置低电平,对应第四个LED点亮
Delay500ms();
P2=0xEF; // 二进制:1110 1111 → 仅P2.4引脚置低电平,对应第五个LED点亮
Delay500ms();
P2=0xDF; // 二进制:1101 1111 → 仅P2.5引脚置低电平,对应第六个LED点亮
Delay500ms();
P2=0xBF; // 二进制:1011 1111 → 仅P2.6引脚置低电平,对应第七个LED点亮
Delay500ms();
P2=0x7F; // 二进制:0111 1111 → 仅P2.7引脚置低电平,对应第八个LED点亮
Delay500ms();
}
}
✅ 升级版主函数:
修改延时函数,实现流水灯任意切换速度
cpp
#include <REGX52.H> // 51/52单片机寄存器核心头文件,用于操作P2口IO引脚,必备
#include <INTRINS.H> // 51内核函数头文件,软件生成的延时代码标配,兼容所有延时模板
/********************* 通用毫秒级延时函数 (重点核心) *********************/
void Delay1ms(unsigned int xms) // @12MHz 晶振 精准延时
{ // 函数功能:自定义延时【xms 毫秒】,xms是延时的毫秒数,可调参数
unsigned char i, j; // 定义局部变量,用于1ms基准延时的循环计数
while(xms--) // 外层循环:执行 xms 次【1ms延时】,总延时 = xms * 1ms
{
i = 2;
j = 239;
do
{
while (--j); // 内层双层循环:执行一次 = 精准延时1毫秒
} while (--i);
}
}
/********************* 主函数 - 正向流水灯核心逻辑 *********************/
void main()
{
while(1) // 死循环:无限重复执行流水灯代码,实现持续流水效果
{
P2=0xFE; // 二进制:1111 1110 → 仅P2.0引脚低电平 → 第一个LED点亮
Delay1ms(200);// 保持亮灯状态 200毫秒
P2=0xFD; // 二进制:1111 1101 → 仅P2.1引脚低电平 → 第二个LED点亮
Delay1ms(200);
P2=0xFB; // 二进制:1111 1011 → 仅P2.2引脚低电平 → 第三个LED点亮
Delay1ms(200);
P2=0xF7; // 二进制:1111 0111 → 仅P2.3引脚低电平 → 第四个LED点亮
Delay1ms(200);
P2=0xEF; // 二进制:1110 1111 → 仅P2.4引脚低电平 → 第五个LED点亮
Delay1ms(200);
P2=0xDF; // 二进制:1101 1111 → 仅P2.5引脚低电平 → 第六个LED点亮
Delay1ms(200);
P2=0xBF; // 二进制:1011 1111 → 仅P2.6引脚低电平 → 第七个LED点亮
Delay1ms(200);
P2=0x7F; // 二进制:0111 1111 → 仅P2.7引脚低电平 → 第八个LED点亮
Delay1ms(200);
}
}
为什么参数用 unsigned int xms****而不是 unsigned char**?**
- unsigned char****取值范围: 0 ~ 255 → 最多只能延时 255ms;
- unsigned int****取值范围: 0 ~ 65535→ 最大可延时65 秒,完全满足 51 单片机所有项目的延时需求(流水灯、按键消抖、数码管、蜂鸣器都够用);