51单片机编程开发(三)之第一个例程

这篇内容的是51单片机点灯实验视频教程的文字版说明,看完视频还有疑惑朋友不妨再参考一下这篇文章。
51单片机最小系统
今天我们开始进行51单片机编程学习,首先我们要了解一下单片机工作需要的基本条件。前面的内容中我们知道了51单片机的引脚有电源引脚,时钟引脚,控制引脚,以及通用输入输出端口。那要怎样才能让单片机工作呢?
如果将单片机与人类比,那它的电源就像人的心脏;时钟信号就像人的脉搏;控制引脚就如人的五官;通用端口就如人的四肢;芯片内部的控制逻辑就如我们的神经系统。这么说的话我们就很容易确定单片机的最小系统了吧。首先我们需要给单片机供电,再给他提供时钟,然后配置它的控制电路,最后给它的引脚接上一些外部电路,据此我们就可以绘制出下图这个最小系统电路了。

例程实图
以上最小系统电路图中使用的是89C51单片机,因为它的功能没有现在市场上具有更多拓展功能的增强版单片机那么多,我们就以C52单片机来进行实验。考虑到接下来我们需要讲解一些程序延伸内容,因此额外又添加了几个LED电路。

说到新版的增强版51系单片机就再讲个题外话,现在的生产51内核单片机的芯片制造商已经在原来的基础上开发出了其他丰富的功能,比如STC 有1T 型的51单片机,甚至还有了32位内核的51单片机,它们的内核时钟提升到了最高72MHz,其他方面RAM,FLASH,电压参数等等。这些单片机各种功能,外设相对传统51单片机更丰富,我工作中没用过这些芯片,所以具体效果怎么样不清楚,如果有使用过的朋友可以在文后谈谈使用感受。接下来我们还是继续讲解今天的知识点。
点亮一个灯的程序
我们先来看看这个最简单的例程之后我在具体解释程序功能:
#include <reg52.h>
sbit led1 = P1^0;
void main()
{
//以下代码最好在死循环(以后会做说明)中执行!这里只做演示用
led1 = 0;
}
可以看到程序内容是不是非常简单?就这么几行代码即可。
#include <reg52.h> 这是单片机开发必须包含的头文件,它是KEIL公司自己编写的文件,里面包含对单片机特殊功能寄存器地址声明以及部分寄存器位的声明,搞不清楚的朋友可以打开该文件看一下。

以后的工作或学习过程中我们碰到的其他单片机在对其进行程序开发时都需要调用编译器平台对单片机基础声明的头文件。即现在我们使用keil编译器就使用他们提供的头文件,如果我们使用其他编译器平台,如IAR,则调用它们平台提供的头文件,不同平台编写的头文件是不一样的,使用这些头文件是保障程序功能正常的前提。
sbit led1 = P1^0; 这一句程序是使用单片机的位操作异或运算对单片机P1端口寄存器第一位进行声明,把它定义为一个叫led1的变量。如果是设置其他引脚也是以此类推。

void main() 就是我们之前说的主函数,注意不要写错了哟,否则你就不会得到想要的效果。
最后这句主函数中的内容led1 = 0; 就是我们需要的实现点灯的代码,它就是将刚刚声明的变量led1,即P1端口寄存器的第一位写入0,意思就是然他输出低电平。为什么这样就达到目的了呢?因为我们原理图中二极管的阴极接的是单片机,阳极接的是电源,所以要使LED发光,它阴极就必须是低电平,所以我们把对应的单片机引脚输出低电平他就可以点亮了。如果要把它熄灭那将他改成led1 = 1; 即对应的寄存器位被置位了,该引脚就会输出高电平,这时灯自然就灭了。
整个控制过程代码就讲解完了,是不是非常简单,很容易就能接受吧?如果还有问题的话自己一定要动手多试试,或者看看视频内容。
点亮一排灯
有了以上的基础讲解,可能有人就会问,如果要点亮一排灯呢?
是不是马上就有办法了,直接把前面的内容都重复一遍,想点亮哪个就控制哪个就行了。
#include <reg52.h>
sbit led1 = P1^0;
sbit led2 = P1^1;
sbit led3 = P1^2;
sbit led4 = P1^3;
sbit led5 = P1^4;
sbit led6 = P1^5;
sbit led7 = P1^6;
sbit led8 = P1^7;
void main()
{
led1 = 0;
led2 = 0;
led3 = 0;
led4 = 0;
led5 = 0;
led6 = 0;
led7 = 0;
led8 = 0;
}
这么看程序确实都很简单,但就是有点怪怪的吧,差不多的代码非要写那么多,即使复制,粘贴,修改起来也麻烦呀。有没有更好的办法呢,少写几行也行呀。办法当然是有的,只是理解起来就相对上面的难一点。
我们都知道P0~P3这4个端口寄存器本来在reg52.h这个头文件中是定义好的呀,它本来就可以当做一个整体使用的吧。初学者可能不好理解这个意思,详细说明就是P0~P3这4个端口寄存器都是8位寄存器,每个刚好是一个字节,每个字节上的0~7位也一一对应每组端口上的0~7位引脚,这也是我们上面使用异或运算来定义led1~led8这些变量的初衷吧。那当我们使用多个引脚时,我们也可以直接对这个寄存器进行赋值的吧比如我们编写代码P1 = 0xf0;这样就可以对寄存器的所有位进行输出赋值了吧,上面代码中将0xf0由十六进制转化为二进制就是11110000B对应的就是将P1寄存器中高四位赋值1,低四位赋值0,那么此时P1端口信息就是P1.0~P1.3输出低电平,对应的LED灯亮,P1.4~P1.7引脚输出高电平,对应的LED不亮。
这时我们输入如下代码:
#include <reg52.h>
void main()
{
P1 = 0x00;
}
执行这段程序我们就可以点亮所有LED了吧。代码量瞬间少了很多了吧,是不是看起来更顺眼了
当然如果修改一下:P1 = 0xff;就是熄灭所有灯吧
如果修改成P1 = 1;那会变成什么结果呢?1是不是就是0x01这么转换就明白什么意思了吧,它对应的就是除P1.0外其他引脚对应的LED都点亮。其他情况当然也可以以此类推。后面我们的例程中会经常这样操作寄存器,并且还会涉及更多的编程技能。
思考:
P1 &= 0xf2;
P1 |= 0x23;
P1 ^= 0x8;
这几句是什么意思呢?
前面内容看懂的朋友这几句应该能够看懂是什么意思吧。
下一节内容我们再具体分析。
小结
以上内容就是初学者入门不可不学的点灯实验例程,通过前面的仿真视频相信很多朋友都能看的明白了,单片机开发也就是这么回事。现在回顾一下是否发现之前讲的基础内容其实都是在讲解编程思维?学技术和说话一样,都是掌握基础逻辑原理了后面就是顺理成章了吧,所以不管怎样一定要打好底层基础,基础不好,盖楼不稳,基础夯实,才是高楼的保障。学英语最快的办法是到说英语的国家去生活一段时间,学编程也是一样,自己要用计算机的思维和它交流你才能学得快。最后还是祝愿每位初学者早日学成,如有疑问欢迎一起交流探讨。