单片机学习笔记之LED流水灯

学习过程跟随B站up主@海创电子

  这里我们采用的开发板是大科电子工作室的FM-STC15开发板。

  LED部分的原理图如下:

  在开发板上实现流水灯,必须先了解开发板上的LED小灯是如何排列的。上图的LED小灯显然是属于“共阳”(即LED的“阳级”连在一起)。与之相反,也有的开发板上的LED小灯是属于“共阴”的,这时我们就需要判断LED灯的亮灭是需要高电平还是低电平,这与接下来编程时的“0”和“1”是有关系的。

  在单片机学习笔记(2)当中,我简单的介绍了关于利用单片机简单实现LED的亮灭,今天我们来学习如何制作流水灯。

方法1:利用十六进制数来制作流水灯

  具体代码如下:

#include <STC15.h>
#include <intrins.h> /*intrins.h,函数,应用于程序设计,一般出现于C51单片机编程中,一般程序中需要使用到空指令_nop_(),
字符循环移位指令_crol_等时使用。*/
#define LED P0 //用“define”语句来表示常量,即将"LED"定义为P0端口。
void delay();
void main()
{
while(1)
{
LED=0xFE; //这里使用了十六进制数来表示,对P0这个io口进行了统一的定义。
delay(); //之后就是使用延时函数来实现灯交换闪烁的间隔时间。
LED=0xFD;
delay();
LED=0xFB;
delay();
LED=0xF7;
delay();
LED=0xEF;
delay();
}
}
void delay()
{
unsigned int i,g;
_nop_(); /*这里使用“_nop_()”空指令的目的也是为了延时,
_nop_(); 程序运行到这里会出现一定的时间间隔且不做任何操作。
for(i=0;i<300;i++) 使用时需要先声明头文件“<intrins.h>”*/
{
for(g=0;g<1000;g++);
}
}

方法2:利用“for”循环语句实现流水灯

  代码大同小异,不同的是在“while”循环语句当中采用“for”循环语句,并且使用了位移取反的操作,略微麻烦,相关代码如下:

while(1)
{
unsigned int k;
for(k=0;k<8;k++)
{
LED=~(0x01<<k); //“<<”运算符做位移操作,表示数值向左位移。
delay();
}
}

  “~”作为取反符号,在“for”循环语句执行时,初始的十六进制数为“00000001”,由于第一次循环时k的值为0,所以不作位移操作,最后得到的十六进制数也是“00000001”。在第二次循环的时候,k的值为1,数值向左位移一位,即“00000010”,此时第二个灯开始亮,以此类推。

方法3:利用数组来实现流水灯

  同样的,使用数组也可以实现流水灯,代码如下:

unsigned char code table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//定义一个数组,数组内容则为十六进制数

void main(void)
{
P0M0=0X00;P0M1=0X00;
//这里对I/O口进行初始化

P1M0=0X00;P1M1=0X00;
P2M0=0X00;P2M1=0X00;
P3M0=0X00;P3M1=0X00;
P4M0=0X00;P4M1=0X00;
while(1)
{
P0=table[0]; /*依次输出数组内的内容
delay(); 也可以尝试采用“for”循环
P0=table[1]; 遍历数组的方法来实现流水灯*/
delay();
P0=table[2];
delay();
P0=table[3];
delay();
P0=table[4];
delay();
P0=table[5];
delay();
P0=table[6];
delay();
P0=table[7];
delay();
}
}

小技巧:在数组当中插入“标志数”进行循环

  同样的,在循环语句当中使用数组时,可以采用这样的写法:

#include <STC15.h>
unsigned char
LedChar[]={0xEF,0xDF,0xBF,0x7F,0xEE,0xDD,0x21,0x12,0x00};
void delay();
void main()
{
while(1)
{
unsigned char i=0;
while(LedChar[i]!=0x00)
{
P0=LedChar[i];
delay();
i++;
}
}
}
void delay()
{
*********
}

  在数组当中的“0x00”就是所谓的标志数,当数组循环到“0x00”时,程序执行到while内的判断,循环就会跳出,这样的写法相对于单纯的使用for语句会简单很多。在习惯上不在数组名后面填写元素个数的话,这个方法也可以巧妙的让循环跳出。

  注意,“标志数”作为标志作用,不应与数组内的其他元素相同。

C语言知识穿插——有参延时函数

  一般来说,延时函数延时的时间为1秒,如果延时的时间较长,我们可以将原来的延时函数进行改写:

void delay(unsigned int j)   //这里的“j”是形式参数
{
unsigned int i,j;
for(i=0;i<183;i++)
{
for(k=0;k<j;k++);
}
}

  在使用上只需改变函数括号内的数值即可:

dalay(1000);     //括号内的称之为“实际参数”

  注意,在使用时需要在主函数的前面修改函数声明:

void delay(unsigned int j);

  总结一句话就是在延时函数当中加入参数,通过改变参数的数值来实现对延时函数时间的控制。