目录

  • 一、LED闪烁
    • 1.1 编写代码
    • 1.2 延时函数
    • 1.3 由0和1控制实现
  • 二、LED流水灯
    • 2.1 流水灯基础版
    • 2.2 移位法实现LED流水灯

一、LED闪烁

昨天我们初识单片机,点亮了一个灯开启了我们51单片机的学习之旅。那么今天我们来一步步深入学习。

1.1 编写代码

会了点亮一个灯,那么闪烁应该就是一亮一灭循环,那代码应该如下

#include void main(){while(1){P2=0xFE;P2=0xFF;}}

将以上代码进行编译并无问题。
但是将以上代码烧写到单片机,你会发现单片机LED灯一直长亮。
这是为什么?使我们的代码有问题吗?
其实不是,代码正确,只是单片机晶振频率是12MHz,是M哦,那么一秒会闪几万次,我们的肉眼根本看不到
所以要在程序中加入延时函数

1.2 延时函数

延时函数有两种方法:
第一种方法:通过STC内的工具实现
选择软件演技计算器进行代码生成

延时代码如下

void Delay500ms()//@12.000MHz{unsigned char i, j, k;_nop_();i = 4;j = 205;k = 187;do{do{while (--k);} while (--j);} while (--i);}

将以上代码加入到刚刚写的程序中

#include #include void Delay500ms()//@12.000MHz{unsigned char i, j, k;_nop_();i = 4;j = 205;k = 187;do{do{while (--k);} while (--j);} while (--i);}void main(){while(1){P2=0xFE;Delay500ms();P2=0xFF;Delay500ms();}}

注意需要包含头文件

#include 

在while函数中进行调用

while(1){P2=0xFE;Delay500ms();P2=0xFF;Delay500ms();}

将以上代码编译烧进单片机,奇迹就出现了。

第二种方法:通过函数调用配合while语句实现

void delay(unsigned int i){while(i--);}

学过C语言的都知道什么意思,这里就不解释了
完整代码如下

#include void delay(unsigned int i){while(i--);}void main(){while(1){P2=0xFE;delay(50000);P2=0xFF;delay(50000);}}

这是不是比第一种方法代码要简单的多,越简单,计算越快

1.3 由0和1控制实现

代码如下,每一行代码都有解释,这里不做解释

#include  //定义单片机的一些特殊功能寄存器sbit led=P2^0;//定义指定LED灯的管脚 void delay(unsigned int i)//延时函数。unsigned int定义无符号整型,范围0-655535{while(i--);//i=1时,大约延时10us} void main() //主函数,程序从这里开始执行{while(1){led=0;//0表示低电平,共阳极二极管点亮delay(50000); //大约延时450msled=1;//1表示高电平,LED熄灭delay(50000); //大约延时450ms}}

二、LED流水灯

2.1 流水灯基础版

8个LED灯的定义,以共阳极为例,让某一个灯点亮就是让这个LED灯为低电平。从左到右依次为01111111、10111111、11011111、11101111、11110111、11111011、11111101、11111110。其中1就是高电平、0位低电平,为低电平时LED点亮。
代码如下

#include  //定义单片机的一些特殊功能寄存器 sbit led1=P2^0;//定义指定LED灯的管脚sbit led2=P2^1;sbit led3=P2^2;sbit led4=P2^3;sbit led5=P2^4;sbit led6=P2^5;sbit led7=P2^6;sbit led8=P2^7; void delay(unsigned int i)//延时函数。unsigned int定义无符号整型,范围0-655535{while(i--);//i=1时,大约延时10us} void main() //主函数,程序从这里开始执行{while(1){led1=0;//0表示低电平,led1点亮delay(5000); led1=1;//1表示高电平,led1熄灭delay(5000); led2=0;//0表示低电平,led2点亮delay(5000); led2=1;//1表示高电平,LED2熄灭delay(5000); led3=0;//0表示低电平,LED3点亮delay(5000); led3=1;//1表示高电平,LED3熄灭delay(5000); led4=0;//0表示低电平,LED4点亮delay(5000); led4=1;//1表示高电平,LED4熄灭delay(5000); led5=0;//0表示低电平,LED5点亮delay(5000); led5=1;//1表示高电平,LED5熄灭delay(5000);led6=0;//0表示低电平,LED6点亮delay(5000); led6=1;//1表示高电平,LED6熄灭delay(5000); led7=0;//0表示低电平,LED7点亮delay(5000); led7=1;//1表示高电平,LED7熄灭delay(5000); led8=0;//0表示低电平,LED8点亮delay(5000); led8=1;//1表示高电平,LED8熄灭delay(5000); }}

最基础最原始的流水灯方式,就是单纯让LED按照顺序依次点亮,从而达到流水灯的效果,看似笨拙、程序繁多,却突出流水灯的思想和原理,为后面库函数、左移右移、数组索引法奠定基础。

2.2 移位法实现LED流水灯

从左开始循环

#include  void delay(unsigned int i) //延时函数{while(i--);} void main(void) //主函数,程序从这里开始执行 { int j; //引入变量,定义字符 while(1){P2=0xfe; //即11111110,将8个LED的状态赋值给P2delay(50000);for(j=0;j<8;j++)//循环8次,因为有8个LED灯 {P2=P2<<1 | 0x01; //实现程序左移1位,或运算,有1为1,全0为0delay(50000); } } }

那么右循环就是与上面相反

#include  void delay(unsigned int i) //延时函数{while(i--);} void main(void) //主函数,程序从这里开始执行 { int j; //定义字符 while(1){P2=0x7f; //即01111111,将8个LED的状态赋值给P2delay(50000);for(j=0;j<8;j++)//循环8次,因为有8个LED灯 {P2=P2>>1 | 0x80; //实现程序右移1位,或运算,有1为1,全0为0delay(50000); } } }

还有其他方法可以实现流水灯,小伙伴们自己探索吧