标题: 不怎么讲原理的51单片机应用入门(2)点亮一个LED灯 [打印本页]

作者: 51黑黑黑    时间: 2016-2-23 15:59
标题: 不怎么讲原理的51单片机应用入门(2)点亮一个LED灯
出自:西漂sky的博客

没错,跟所有教程一样,第一个学习的外设是LED灯。其实在下起初也很奇怪为什么所有教程的第一个实验不是流水灯就是点亮一个LED。现在就个人认为,主要原因就是LED是一个只要一个输出引脚就可以驱动的外设元件,而且现象明显,容易进一步引发学习者的学习兴趣。与其叫“点亮一个LED灯”,不如叫“输出端口的操作”。上一篇讲过,单片机输出的方式就是把IO口输出引脚的电压按要求改变。IO口引脚的电压在理想的情况只能为两个值——要么在Vcc附近,要么在GND附近。在电压在Vcc附近的情况被视为逻辑1,电压在GND附近的情况被视为逻辑0。
大部分的开发板/学习板的LED外设如下图:

Vcc指电源,R2与R3分别是限流电阻,最右侧LED1与LED2分别直接与IO口的引脚相连。
现在想想如何让这两个LED发光,我们知道LED全称为发光二极管,当正负极之间的电压超过一定值时,发出光亮。这个定值一般在2~3V左右。LED1与LED2的电压只能在Vcc附近和GND附近——也就是逻辑1或逻辑0。我们分类讨论一下:当LED1为逻辑1时,发光二级管的两端电压几乎相同,不会导通,也就不会发光;当LED1为逻辑0时,发光二极管正负极间的正向电压较大,在电阻选取合适的情况下超过那个定值,也就会发光。于是,我们得出一个等效——LED发光=单片机输出端口输出逻辑0;LED不发光=单片机输出端口输出逻辑1。
于是,我们知道若想要D1发光,只要使标号为LED1的输出端口输出逻辑0就可以了。我们假设标号LED1的输出端口是P1的最低位P1^0。
第一种方法,就是对IO口P1整体进行操作。若想让最低位输出0,那么P1要输出的值就是1111_1110(不考虑P1的其他位)16进制就是0xFE。那么如上一章所说,只要一句语句“P1=0xFE;”就可以了。
第二种方法,就是单独对P1的最低位操作。其本质就是“P1^0=0;”这样一句。但是这样写编译器会报错。原因是编译并不认识P1^0是个什么玩意,在进行对IO口的位单独操作前,必须告诉编译器P1^0是什么。于是有了这样一个定义:
sbit P10 = P1^0;
这条语句一般是写在main函数之外的。这个玩意看上去有点像宏定义#define,作用也像,不过作用的原理不同。sbit表示对位定义,“P10”是在下给P1最低位取得名字,这个名字可以随便取,只要不与关键字冲突就行。“P1^0”表示IO口P1的第0位。这个是有固定格式的,IO口位的固定格式为“Px^y”,x是指第几个IO口,y是指IO口的第几位。再举个例子:“sbitABC=P3^5;”这条语句就是把IO口P3的第5位命名为ABC。
命名后,你起的名字编译器就可以识别了。在“sbitP10 =P1^0;”语句之后,再写“P10=0;”,编译器就知道你想让被命名为P10的输出引脚输出逻辑0了。
现在来一个完整的程序:
#include<reg52.h>
sbit LED1=P1^0;
void main(void)
{
LED1=0;
for(;;);
}
想必第2和5行的意思已经解释的很清楚了,4和7行是大括号。第1行是头文件,这个头文件就像C语言中的stdio.h一样,一般都会用到。第6行是一个死循环,阻止程序结束的。对于单片机的程序,我们是不希望结束的,若是没有无限运行的部分,需要在最后加一个死循环(想知道没有死循环有什么后果......去掉死循环上单片机跑一下就知道了)。就这样,IO口的基本操作就结束了,也就是说,用Px=0xyz或sbit定义+对位操作的方法,就可以自由的操作IO口的输出了。
(如需转载,在下感激不敬,也请注明出处)






欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1