STC单片机 闪烁灯,LED流水灯 程序讲解
原创
©著作权归作者所有:来自51CTO博客作者达帮主的原创作品,请联系作者获取转载授权,否则将追究法律责任
闪烁灯
所谓的闪烁灯就像警车一样,哔哩哔哩闪烁。
LED闪烁首先你先得看懂我上一篇文章
LED闪烁其实就是将一个灯开一下,关一下。
在循环中不断的进行开关,这就是逻辑其实挺简单的,但是中间需要有一个延时,如果不延时就不会看到效果。
在这里需要用到C语言里面的一个重定义关键字:
unsigned and signed
int 分为无符号 unsigned 和有符号 signed 两种类型,默认为signed。二者的区别就是无符号类型能保存2倍于有符号类型的数据。32位下,signed int 的表示范围为:-2147483648 ~ 2147483647 (最高位做符号位)。unsigned int 的表示范围为:0 ~ 4294967295 (不保留符号位)。我们都知道,两个不同的数据类型在进行混合使用时,会自动进行类型转换
typedef使用
我们这里采用一个unsigned进行命名范围在0~429496... 之间
typedef重定义一些常用的关键字,可以增强程序的可移植性,因为在不同的编译软件上,C语言的数据类型的关键字的位宽是不一样的。
typedef unsigned char u8; //表示将char重定义一下 u8表示char类型
开始程序
向上面所说中间需要加入一个delay()函数
coding:
#include "reg51.h"
sbit ledP20 = P2^0;//D1 LED等的拐脚
typedef unsigned int u16;//重定义一个int类型
//延迟函数
void delay(u16 delay){//大约减少10us的样子
while(--delay){}
}
main(){
while(1){
ledP20 = 1;//关灯
delay(50000);//延迟
ledP20 = 0;//开灯
delay(50000);//延迟
}
}
效果:
设置断点查看闪烁时间
首先双击代码左侧的数码栏:
进入断点,这我们打断的的位置需要注意,关灯,然后开灯。中间会延迟,我们可以通过开始的时间和结束时间来计算中间花了多少时间。
断点窗口:
我们可以看到当前时间点
下一步进入延迟
我们这一步还没有进入延迟方法可以记住时间 0.00019500而后下一步
通过0.20029550 - 0.00019500 = 0.200毫秒
这个速度也跟开发工具有关如果设置Xtal(MHz) = 12.0时间就会慢,如果我们设置成12 会从开始计算到结束会显示大约0.4.50毫秒左右,这个不确定的。
流水灯
流水灯就是从D1-D8
其实流水灯也是围绕着闪烁灯这个逻辑继续跟踪的。
首先我们需要动的 ,循环左移右移函数。
可以通过C语音的预处理命令来定义 #define A P2(不需要加分号)
通过定义如果我们使用了P2拐脚我们可以通过define A P2 来代替P2拐脚,通过调用A来处理P0拐脚
循环左移循环右移函数
方法
| 描述
|
_crol_(a,b)
| 循环左移函数,a是左移的值,b是左移的位数。包含在intrins.h函数库里面,left |
_cror_(a,b)
| 循环右移函数,a是右移的值,b是右移的位数。包含在intrins.h函数库里面,right |
开始程序
这里有一个点非常重要,一个16进制转2进制的一个操作。
流水灯从左开始
先看代码吧:
#include "reg51.h"
#include "intrins.h"
typedef unsigned int u16; //重定义一个int类型
#define led P2 //表示所有的P2口
//延迟函数
void delay(u16 delay){//大约减少10us的样子
while(--delay){}
}
void main(){
int i;
led = 0xfe; //1111 1110 //这里表示点亮第一个D1灯 可以看出这个16进制
while(1){
for(i = 0;i <7;i++){
/**
*当 i = 0 crol 右移一位 1111 1101
*当 i = 1 crol 右移一位 1111 1011
*当 i = 1 crol 右移一位 1111 0111
*..以此类推到7的时候就完了01111 111
*/
led = _crol_(led,1);//左移
delay(50000);
}
}
}
效果:
从下面留出可以看出流水灯的一个流程
流水灯从左右开始
这个程序流程是往回跑
代码:
#include "reg51.h"
#include "intrins.h"
typedef unsigned int u16; //重定义一个int类型
#define led P2 //表示所有的P2口
//延迟函数
void delay(u16 delay){//大约减少10us的样子
while(--delay){}
}
void main(){
int i;
led = 0xfe; //1111 1110 //这里表示点亮第一个D1灯 可以看出这个16进制
while(1){
for(i = 0;i <7;i++){
/**
*当 i = 0 crol 右移一位 1111 1101
*当 i = 1 crol 右移一位 1111 1011
*当 i = 1 crol 右移一位 1111 0111
*..以此类推到7的时候就完了0111 1111
*/
led = _crol_(led,1);//左移
delay(50000);
}
for(i = 0;i <7;i++){
/**
*当 i = 0 crol 右移一位 0111 1111
*当 i = 1 crol 右移一位 1011 1111
*当 i = 1 crol 右移一位 1101 1111
*..以此类推到7的时候就完了1111 1110
*/
led = _cror_(led,1);//右移
delay(50000);
}
}
}
效果: