一、LED实际应用场景
LED即发光二极管,生活中随处可见:显示屏、广告牌、指示灯、装饰灯带。单片机最基础、经典的入门实验就是点亮LED。
二、LED点灯基础原理
插件LED灯珠长引脚=正极,短引脚=负极。
LED只有两端形成电压差、流过合适大小电流的时候才会发光。
⚠️LED不能直接接电源!必须串联限流电阻,电流过大直接烧毁灯珠。
限流电阻计算公式
R=VCC−VLEDIR=\frac{V_{CC}-V_{LED}}{I}R=IVCC−VLED
- 插件LED常规工作电流:20mA
- 贴片LED常规工作电流:5mA
- 红/黄光压降约1.8V,蓝/白光压降约3V
举个例子:3.3V供电、黄色贴片LED
R=(3.3−1.8)/0.005=300ΩR=(3.3-1.8)/0.005=300ΩR=(3.3−1.8)/0.005=300Ω
实际产品指示灯经常选用几千欧的大电阻,牺牲亮度换取更低功耗。
三、单片机GPIO控制LED
GPIO全称General‑purpose input/output通用输入输出引脚,可以配置输出高低电平,以此控制LED亮灭。
STC89C51的IO分组:
- P0口:P0.0~P0.7
- P1口:P1.0~P1.7
- P2口:P2.0~P2.7
- P3口:P3.0~P3.7
- P4口:P4.0~P4.6
两种硬件接法
- IO口直接输出高电平点亮LED(不推荐):单片机IO输出驱动能力弱,亮度不足
- VCC供电,LED负极接IO引脚,IO输出低电平点亮LED(开发板标准接法)
本实验开发板硬件:LED1、LED2、LED3分别接
P2.7、P2.6、P2.5,引脚输出低电平 → LED点亮
方式1:整体操作IO寄存器
直接给整个端口寄存器赋值,一次性控制8个引脚电平
P2=0x53;0x53是十六进制,对应二进制0101 0011,对应控制P2口8个引脚电平。
进制简单科普
- 十进制:0‑9,逢十进一,适合人阅读
- 二进制:只有0、1,对应硬件高低电平,但是数字太长不好写
- 十六进制:0‑9、A‑F,
0x前缀,紧凑表达二进制,单片机代码最常用
一键点亮P2口全部LED示例代码
#include<reg52.h>voidmain(){P2=0x00;//全部输出低电平while(1){}}
while(1)死循环,单片机程序运行到这里永久停留
方式2:单独控制某一个引脚(sbit位定义)
sbit是C51编译器独有的关键字,可以单独操作寄存器其中某一个IO引脚,语法格式
sbit led1=P2^7;代表:把P2.7引脚别名定义为led1,后续代码直接操作led1即可控制引脚电平。
单颗LED点亮完整代码
#include<reg52.h>sbit led=P2^7;voidmain(void){led=0;//输出低电平,点亮LEDwhile(1){}}四、LED闪烁实验
闪烁逻辑:点亮 →延时一段时间 →熄灭 →延时一段时间,循环往复。
51单片机时间基础概念
- 时钟周期:晶振频率的倒数,12M晶振,时钟周期=1/12 us
- 机器周期:51单片机默认12时钟周期 =1个机器周期
- 指令周期:CPU执行一条汇编指令花费的总机器周期
软件延时原理:让CPU空循环,消耗时间,达到延时效果
通用毫秒延时函数(12M晶振)
voiddelay_ms(unsignedintxms)//@12MHz{unsignedinti,j;for(i=xms;i>0;i--){for(j=124;j>0;j--){}}}也可以使用STC‑ISP软件自动生成精准延时代码,省去手动计算
LED闪烁完整可运行代码
#include<reg52.h>sbit led=P2^7;//带参延时函数 12M晶振voiddelay_ms(unsignedintxms){unsignedinti,j;for(i=xms;i>0;i--){for(j=124;j>0;j--){}}}voidmain(){while(1){led=0;delay_ms(500);//亮500msled=1;delay_ms(500);//灭500ms}}五、流水灯实现
硬件:LED1(P2.7)、LED2(P2.6)、LED3(P2.5)依次循环点亮
版本1:单独位操作写法,可读性高
#include"reg52.h"#include"intrins.h"sbit LED1=P2^7;sbit LED2=P2^6;sbit LED3=P2^5;voidDelay1000ms()//@11.0592MHz{unsignedchari,j,k;_nop_();i=8;j=1;k=243;do{do{while(--k);}while(--j);}while(--i);}voidmain(){while(1){LED1=0;LED2=1;LED3=1;Delay1000ms();LED2=0;LED1=1;LED3=1;Delay1000ms();LED3=0;LED1=1;LED2=1;Delay1000ms();}}版本2:端口寄存器整体赋值写法,代码简洁
#include<reg52.h>voiddelay_ms(unsignedintxms){unsignedinti,j;for(i=xms;i>0;i--){for(j=124;j>0;j--)}}voidmain(){while(1){P2=0xDF;//1101 1111 P2.7输出低delay_ms(500);P2=0xBF;//1011 1111 P2.6输出低delay_ms(500);P2=0x7F;//0111 1111 P2.5输出低delay_ms(500);}}版本3:位运算封装函数,扩展性最强
#include<reg52.h>voiddelay_ms(unsignedintxms){unsignedinti,j;for(i=xms;i>0;i--){for(j=124;j>0;j--)}}//点亮指定P2端口引脚voidopen_led(unsignedintnum){P2=0xFF&~(1<<num);}voidmain(){while(1){open_led(7);delay_ms(500);open_led(6);delay_ms(500);open_led(5);delay_ms(500);}}六、拓展知识点 bit / sbit / sfr区别
- bit:C51扩展基础数据类型,1位布尔变量,值只能是
0或1,在单片机RAM空间分配存储空间,类似bool
bit flag=0;- sbit:位别名定义,用来直接操作特殊寄存器的某一个引脚,不占用RAM内存,直接绑定硬件地址
sbit OV=PSW^2;sbit三种标准写法
sbit OV=0xd2;sbit OV=PSW^2;sbit OV=0xD0^2;- sfr:定义8位特殊功能寄存器,直接绑定硬件寄存器地址,
reg52.h头文件内部大量使用sfr定义P0‑P3等端口
sfr P1=0x90;七、本章小结
1、LED必须串联限流电阻,防止烧毁
2、可以整体赋值寄存器或者sbit单独控制单个IO引脚
3、软件空循环实现延时,完成LED闪烁效果
4、流水灯可以使用3种不同编码思路实现
下一章预告:独立按键检测,软件消抖原理与代码实现