蓝桥杯单片机第二周第一讲:点亮你的第一个LED
就像第一次拼好乐高玩具会亮灯一样,今天我们要让单片机世界里的“小灯泡”听我们的话!
1.1 新建工程:为程序安个“家”
想象一下,你要组装一台玩具,首先得有个干净的工作台吧?新建工程就是为单片机程序准备这样一个专属工作空间。
操作步骤很简单:
-
新建文件夹 → 每个项目一个“房间”,互不干扰
-
选择芯片 → 告诉电脑:“我要用AT89C52这款单片机”
-
填写信息 → 在“品”字工具栏写上项目名字(如Test_01 User)
-
生成HEX文件 → 在魔术棒设置里打个勾
,这是烧录到单片机的“通行证”
1.2 认识LED原理图:看看“灯泡”怎么接
先看两张原理图(想象成电路世界的“地图”):
图1,2: 展示了LED(发光二极管)如何连接到单片机的P1口
图3: 具体显示了8个LED分别接到P1.0到P1.7这八个“开关”上
关键理解:
-
这些LED采用共阳接法 → 想象所有灯泡的“火线”都接在一起(接正极)
-
想要哪个LED亮,就把对应的“零线”接通(给低电平)
-
比如:
P1_0 = 0;就是让接在P1.0上的LED亮起
1.3 编写程序:给单片机下“命令”
方法一:整体指挥(像同时按下多个开关)
/* 头文件区域 - 相当于“工具箱”声明 */
#include <REGX52.H> // 这个文件里定义了单片机的各种“零件”
/* 主程序 - 单片机上电后就从这里开始执行 */
void main()
{
while(1) // 让程序一直循环运行,不会停止
{
P1 = 0xAA; // 给P1口整体赋值
// 0xAA的二进制是1010 1010
// 从右往左看:0亮、1灭、0亮、1灭...
// 结果:间隔亮起的“斑马线”效果
}
}
小知识: 0x开头表示十六进制数,这是单片机编程中常用的“ shorthand”(简写)。
方法二:单独点名(像一个个打开开关)
#include <REGX52.H>
void main()
{
while(1)
{
P1_0 = 0; // 点亮第一个LED(P1.0对应的灯)
P1_7 = 0; // 点亮最后一个LED(P1.7对应的灯)
// 注意:其他引脚默认是高电平(1),对应的LED是熄灭状态
}
}
1.4 LED灯闪烁:让灯“眨眼睛”
实现原理: 亮 → 等一会儿 → 灭 → 等一会儿 → 再亮……循环下去就是闪烁!
但有个问题: 单片机执行指令太快了(微秒级别),一眨眼就过去了,我们根本看不到变化。所以需要延时函数——让单片机“发会儿呆”。
获取延时函数的“秘籍”:
-
打开STC-ISP烧录软件(单片机的“传送门”)
-
找到“软件延时计算器”(就像定时器生成器)
-
设置参数:
-
系统频率:12MHz(告诉它单片机跑多快)
-
定时长度:500ms(想要延迟半秒钟)
-
指令集:STC-Y1(选择适合的“方言”)
-
-
点击“生成C代码”,复制到你的程序中
闪烁灯完整代码:
#include <REGX52.H>
/* 延时函数 - 让单片机“数羊”一会儿 */
void Delay(unsigned char xms) // xms是要延迟的毫秒数
{
unsigned char i, j;
while(xms--) // 数xms次
{
i = 2;
j = 239;
do
{
while(--j); // 内层循环:数239次
} while(--i); // 外层循环:数2次
}
// 这些特定的数字组合起来,正好产生1毫秒的延迟
}
void main()
{
while(1) // 无限循环
{
P1_0 = 0; // 开灯
Delay(500); // 等500毫秒(半秒)
P1_0 = 1; // 关灯
Delay(300); // 等300毫秒
// 这样就会亮0.5秒,灭0.3秒,不断循环
}
}
1.5 LED流水灯:让灯光“流动”起来
效果想象: 像电影院的跑马灯,或者警车顶灯那样,灯光依次亮起移动。
方法一:手动指挥每个灯
#include <REGX52.H>
void Delay(unsigned char xms) // 沿用之前的延时函数
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do { while(--j); } while(--i);
}
}
void main()
{
while(1)
{
// 方案A:逐个控制每个引脚
P1_0 = 0; // 第一个灯亮
Delay(500);
P1_0 = 1; // 第一个灯灭
P1_1 = 0; // 第二个灯亮
Delay(500);
P1_1 = 1; // 第二个灯灭
// 以此类推...
// 方案B:给P1口整体赋值(更简洁)
P1 = 0xFE; // 1111 1110 → 只有第一个灯亮
Delay(500);
P1 = 0xFD; // 1111 1101 → 只有第二个灯亮
Delay(500);
P1 = 0xFB; // 1111 1011 → 只有第三个灯亮
Delay(500);
// 继续改变数值,灯光就会“流动”
}
}
方法二:用“神奇函数”自动流动(更高级!)
单片机有个很酷的功能:循环移位。就像一队人报数,喊“向左转”时,每个人都移到左边位置。
#include <REGX52.H>
#include <intrins.h> // 这个头文件里有循环移位函数
void Delay(unsigned char xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do { while(--j); } while(--i);
}
}
/* 变量声明 */
unsigned char ucLed = 0xFE; // 初始值:1111 1110(第一个灯亮)
//unsigned int time = 1000; 实现流水灯速度逐渐变快
void main()
{
while(1)
{
ucLed = _crol_(ucLed, 1); // 关键魔法!
// _crol_:循环左移函数
// 把ucLed的二进制位整体向左移动1位
// 最左边的位“掉下来”接到最右边
// 举例:
// 第一次:1111 1110 → 1111 1101(第二个灯亮)
// 第二次:1111 1101 → 1111 1011(第三个灯亮)
// ...依次循环,形成流水效果
P1 = ucLed; // 把移动后的值赋给P1口
Delay(100); // 控制流动速度(100毫秒)
//或者将Delay(100)改为Delay(time)
//time=time-100;//实现流水灯逐渐变快
}
}
小提示:
-
_crol_:循环左移(像向左传递火炬) -
_cror_:循环右移(像向右传递火炬) -
这两个函数都在
intrins.h这个“魔法库”里
总结一下
今天你学会了:
-
新建工程 - 给程序安家 -
看懂原理图 - 知道LED怎么连接的 -
控制单个/多个LED - 用赋值语句指挥灯光 -
制作闪烁灯 - 用延时函数控制时间 -
制作流水灯 - 用循环移位实现酷炫效果
核心思想: 单片机编程就像指挥一支“电子乐队”,你写代码就是乐谱,LED灯就是乐器,而P1口就是你的指挥棒。多练习,你就能奏出更复杂的“光之交响曲”!
下一步挑战: 尝试改变延时时间,让流水灯流动更快或更慢;或者尝试让灯光从两边向中间流动,再从中间向两边扩散。发挥你的创意吧!



