单片机基础教程【肆】:流水灯

-回复 -浏览
楼主 2020-09-15 14:48:06
举报 只看此人 收藏本贴 楼主

 最近比较忙..更新比较慢哦


上节我们了解了如何利用单片机点亮一颗LED,但是实际上这样的功能并没有什么用处,我们这节要利用单片机控制多颗LED,做出稍微高级一点点的操作。

 

回顾与拓展


首先,我们回顾一下上节的程序。


程序:点亮一颗LED

 

接下来,我们先了解另一种实现方法。



程序:点亮一颗LED (第二种方法)

 

下载程序后,现象同上一个实验:P1.0端口的LED点亮

 

P1 要用大写字母
与第一个程序不同,这里更简单,直接对 P1 口整体操作,我们使用的是 8 位单片机,所以一个口占的宽度是 8 位,用二进制表示 xxxx xxxx 。 0xFF 和 0xff 相同即二进制的 1111 1111, c 语言中数值不区分大小写, 标识符一定要区分大小写。 0x前缀表示这个是十六进制数, 如果直接用十进制则可以用下面方式表示: P1=255 此句等效于 P1=0xff, 单片机中常用的进制是: 十进制、 二进制和十六进制, 三种进制只是表现形式不同, 可以相互转换。

同学们学过大学生计算机基础的话,应该都会吧..

在写程序之前需要详细了解这 3 种进制并能熟练进行换算。

最简单的换算办法可以通过电脑自带的计算器。这里演示一下:


打开电脑自带的计算器

 

下面,我们利用这种方法,看看我们上节的课后作业如何实现?

尝试使8颗LED间隔点亮


 
程序:使8颗LED间隔点亮

 

下载程序后, 可以看到连接在P1.0 P1.2 P1.4 P1.6 口的 LED 点亮, 其他 LED 熄灭。

大家可以在此基础上,尝试给P1赋其他值,观察现象。

借此可以熟悉二进制、十六进制、十进制之间的转换。

 

闪烁的LED


前面我们做的实验只是点亮或熄灭LED,都是一种静态的操作,这体现不出单片机的智能之处,现在我们来看看如何让LED闪烁起来!

首先,我们要弄清楚操作流程,即流程图。

可以看到,闪烁LED比我们简单的点亮熄灭多了一个延时。

这个延时该如何实现呢?

这里我贴出一个实现方法,下面对其进行讲解。


程序:闪烁一颗LED


下载程序后,可以看到连接在 P1.0 的 LED 闪烁,其他 LED 熄灭。

 

void delay(unsigned int t)  延时函数。


许多程序设计语言中,可以将一段经常需要使用的代码封装起来,在需要使用时可以直接调用,这就是程序中的函数。

所以,我们现在将delay函数视为一段打包的程序段,暂且不管它具体的事项方法,我们能够知道()括号里的数字,即表示这句话延时的毫秒数。

下面,我们需要理解函数的意义:

C 语言的函数可以分为两类:

带参数的函数和不带参数的函数,一般类型如下:

类型标示符+ 函数名 +(类型标示符+参数)
void delay (unsigned int t )

void 的字面意思是 “无类型 ”, 如何函数没有返回值, 则声明为 void 类型, 如果函数没有输入参数,也需要声明为 void 类型。

可以看出 delay() 函数有输入参数,输入参数是无符号整型变量 t,但没有返回值。

在主调函数中调用某函数之前应对该被调函数进行说明(声明),这与使用变量之前要先进行变量说明是一样的。

在主调函数中对被调函数作说明的目的是使编译系统知道被调函数返回值的类型,以便在主调函数中按此种类型对返回值作相应的处理。其一般形式为:

类型说明符 被调函数名(类型 形参,类型 形参…) ;

或为:

类型说明符 被调函数名(类型,类型…) ;

括号内给出了形参的类型和形参名, 或只给出形参类型。 这便于编译系统进行检错, 以防止可能出现的错误。

 

函数声明:

C语言中又规定在以下几种情况时可以省去主调函数中对被调函数的函数说明。
1) 如果被调函数的返回值是整型或字符型时,可以不对被调函数作说明,而直接调用。 这时系统将自动对被调函数返回值按整型处理。
2) 当被调函数的函数定义出现在主调函数之前时,在主调函数中也可以不对被调函数再作说明而直接调用。

3) 如在所有函数定义之前,在函数外预先说明了各个函数的类型,则在以后

各主调函数中,可不再对被调函数作说明。例如:

char str(int a);
float f(float b);
main()
{……}
char str(int a)
{……}
float f(float b)
{……}

其中第一,二行对 str 函数和 f 函数预先作了说明。因此在以后各函数中无须对str和 f 函数再作说明就可直接调用。

4) 对库函数的调用不需要再作说明, 但必须把该函数的头文件用 include 命令包含在源文件前部。

 

函数调用:

程序中是通过对函数的调用来执行函数体的,其过程与其它语言的子程序调用相似。

C语言中,函数调用的一般形式为:

函数名(实际参数表)

对无参函数调用时则无实际参数表。 实际参数表中的参数可以是常数, 变量或其它构造类型数据及表达式。各实参之间用逗号分隔。
在C语言中,可以用以下几种方式调用函数:

 

1.函数表达式:函数作为表达式中的一项出现在表达式中,以函数返回值参与表达式的运算。 这种方式要求函数是有返回值的。

例如:

z=max(x,y)

是一个赋值表达式, 把 max 的返回值赋予变量 z。
2. 函数语句:函数调用的一般形式加上分号即构成函数语句。

例如:

printf("%d",a);

scanf ("%d",&b);

都是以函数语句的方式调用函数。
3. 函数实参:函数作为另一个函数调用的实际参数出现。这种情况是把该函数的返回值作为 实 参 进 行 传 送,因 此 要 求 该 函 数 必 须 是 有 返 回 值 的。

例如:

printf("%d",max(x,y));

即是把 max 调用的返回值又作为 printf 函数的实参来使用的。 在函数调用中还应该注意的一个问题是求值顺序的问题。 所谓求值顺序是指对实参表中各量是自左至右使用呢,还是自右至左使用。对此,各系统的规定不一定相同。

了解完函数的用法,大家可以尝试改变delay(500)中括号里的数值,观察现象有何不同。

流水灯


流水灯,即LED从一边依次亮至另一边,光像流水一样流动。

流水灯的实现方法很多,我们这里先了解一下其中一种方法。


程序:单颗流水灯

下载程序后,可以看到连接在 P1 的 8 个 LED 有顺序点亮。

如果明白前面的讲解内容,该程序的原理大家应该一看就懂了吧~

就是简单对P1进行赋值

然后利用延迟函数delay控制时间

这种方法实现流水灯,简单且直接,但是程序往往会写的很长。

当然还有更高级的方法,我们会在下节进行讲解!


本节讲解了I/O口的操作、进制转换及函数的使用等内容,初学的同学应尽可能掌握熟练,这样后面的学习会更加轻松。

课后练习:

1.以不同频率闪烁1颗LED

2.实现多种不同的流水灯方式

(左流水、右流水、中间往两边,两边往中间等)

我要推荐
转发到

友情链接