无意中发现另一种实现LED亮灭的方法
注意
本篇文章的功能实现基于 STC89C52RC 芯片,八颗LED灯接于P2口,使用Keil4原版编译环境,借鉴时注意不要一昧照搬。
前言
在上一篇《单片机C语言第一篇之”Hello LED”》中,实现LED灯亮灭的方法是直接用进制转换的8421法计算对应I/O口的LED亮灭的十六进制数,而这个程序用的是另一种方法,我之前也没有学过。
正文
该程序代码如下:
#include "reg52.h" //这里的头文件写法与#include<reg52.h>相同
//IO引脚定义:
sbit LED9 = P2^0; //管脚定义 类似于起名字
//用led 来代替P2.0
void main(void)
{
LED9=0; //P2.0引脚输出0,因LED是共阳接法,因此是输出0来吸收电流点亮LED灯
while(1)
{
} //主程序循环,即程序要停止在这里
}
代码注意事项
sbit
是用来定义管脚名字的,除了程序里的LED,数码管的管脚、蜂鸣器的管脚都可以定义- 我们所说的
P2.0
口在程序中不能写作P2.0
,而应该是P2^0
- 如果LED是共阴极接法,则LED = 0为高电位,LED = 1为低点位,这个根据单片机PCB板的设计不同而不同
while(1)
{
} //主程序循环,即程序要停止在这里
//这个程序要不要这个while,不是很清楚,因为我试过不放这个while
//程序也是正常运作,不会跑飞
总结
这个程序很简单,甚至没有延迟函数让LED闪烁,但是他实现了用sbit
定义所需使用的组件的管脚来实现对组件的控制,是非常方便的,起码不用算十六进制数,个人觉得是十分不错的改进。
进阶再进阶
让它闪烁
还是上面那个程序,把之前的延迟函数加进去,让LED灯闪烁。
实现代码如下:
#include <reg52.h>
sbit led9 = P2^0; //管脚定义
void delay(unsigned int time) //延时子函数,定义延时参数time。time的大小决定延时时间长短
{
while(time--); //减1循环,减到0退出
}
void main(void)
{
while(1) // 主程序循环
{
led9=1; // LED灯灭
delay(30000); // 延时,改变参数则改变变化时间
led9=0; // LED灯亮
delay(30000); // 延时
}
}
是不是很简单?但是这只是让一个灯亮。我的PCB板上可是有8颗LED灯呢,如何让他全部闪烁?
多个LED灯闪烁
我已经教了两种方法,一种是直接用8421法算出对应的十六进制数,另一种是先给LED管脚定义然后进行位操作。那么就来看看实现4颗LED灯闪烁的代码哪种更易读、易理解
8421法
#include <reg52.h>
void delay(unsigned int t)
{
while(t--);
}
void main()
{
while(1)
{
P2=0xa6;
delay(30000);
P2=0xFF;
delay(30000);
}
}
管脚定义法
我对这个方法的设想,是定义sbit数组,在循环中进行初始化,并进行位控制,结果并不能。在网上查找资料后也是不能。原因可能是以下几种,我自己也不懂
- Keil C51编译器不支持
- sbit特殊寄存属于直接寻址,而数组、调用数组时简介寻址
- sbit用来定义特殊寄存器中可以寻位的位,占1位,不能定义指针,也不能定义数组(我觉得是这种)
总结
用sbit定义管脚的方法是昨天才看到的,觉得十分新奇,于是想用sbit同时控制多个LED灯闪烁,但是很明显失败了。即使每一个LED管脚都单独定义,按照程序执行的顺序,也不能同时闪烁,所以只能用十六进制方法实现,写了几十行代码都没法用,唉。这也是比课堂上更快地自学C51单片机的乐趣和痛苦吧。