LED灯
1、点亮一个LED灯
2、LED闪烁
3、LED流水灯
法一:
#include <REGX52.H>
#include<intrins.h>
void Delay500ms(void) //@12.000MHz
{
unsigned char data i, j, k;
_nop_();
i = 4;
j = 205;
k = 187;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
P2=0xfe; //1111 1110
Delay500ms() ;
P2=0Xfd; //1111 1101
Delay500ms();
P2=0xfb; //1111 1011
Delay500ms() ;
P2=0Xf7; //1111 0111
Delay500ms();
P2=0xef; //1110 1111
Delay500ms() ;
P2=0Xdf; //1101 1111
Delay500ms();
P2=0Xbf; //1011 1111
Delay500ms();
P2=0X7f; //0111 1111
Delay500ms();
}
法二:这个函数可以修改任意灯的延时时间,通过修改xms的值即可。
#include <REGX52.H>
#include<intrins.h>
void Delay1ms(unsigned int xms) //@12.000MHz
{
unsigned char data i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
void main()
{
P2=0xfe; //1111 1110
Delay1ms(500) ;
P2=0Xfd; //1111 1101
Delay1ms(500) ;
P2=0xfb; //1111 1011
Delay1ms(500) ;
P2=0Xf7; //1111 0111
Delay1ms(500) ;
P2=0xef; //1110 1111
Delay1ms(500) ;
P2=0Xdf; //1101 1111
Delay1ms(500) ;
P2=0Xbf; //1011 1111
Delay1ms(500) ;
P2=0X7f; //0111 1111
Delay1ms(500) ;
}
4、独立按键控制LED
#include <REGX52.H>
#include<intrins.h>
void Delay1ms( int xms) //@12.000MHz
{
unsigned char data i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
if( P3_1==0) //单片机上电默认高电平,按键按下,接地,电平拉低,等于0,按键按下
{
P2_0=0;
Delay1ms( 10000);
}
else
{
P2_0=1;
}
}
5、独立按键控制LED----软件消抖
#include <REGX52.H>
#include<intrins.h>
void Delay(xms) //@12.000MHz
{
unsigned char data i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
if(P3_1==0)
{ Delay(20); //按键按下延时,消除抖动
while(P3_1==0);
Delay(20); //按键松掉延时,消除抖动
P2_0=~P2_0; //默认高电平,取反则为0
Delay(10000);
P2_0=1; //亮10s自动熄灭,这里改成P2_0=P2_0;不行
}
}
6、独立按键控制LED显示二进制
法一:
#include <REGX52.H>
#include<intrins.h>
void Delay(xms) //@12.000MHz
{
unsigned char data i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
unsigned char LEDNum=0;
while(1)
{
if(P3_1==0)
{
Delay(20); //按键按下延时,消除抖动
while(P3_1==0);
Delay(20); //按键松掉延时,消除抖动
LEDNum++;
P2=~LEDNum;
}
}
}
ps:设想是定义char类型为8位,单片机IO口也是8位,lednum=0000 0000,加1后变成lednum=0000 0001,取反后P2_0=1111 1110,点亮第一个灯。再按lednum=0000 0010,取反后P2_0=1111 1101,第一个灯灭,第二个灯点亮。再按lednum=0000 0011,取反后P2_0=1111 1100,此时两个灯一起亮;再按lednum=0000 0100,取反后P2_0=1111 1011,此时第三个灯亮,以此类推。
有几个点要注意:一开始我没有写while(1)循环,结果一个灯都不亮。把P2写成了P2_0,结果也不行。 P2包含P2.0-P2.7,有八位。
法二:
#include <REGX52.H>
#include<intrins.h>
void Delay(xms) //@12.000MHz
{
unsigned char data i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
unsigned char LEDNum=1; //修改为1 ,用char类型也行
while(1)
{
if(P3_1==0)
{
Delay(20); //按键按下延时,消除抖动
while(P3_1==0);
Delay(20); //按键松掉延时,消除抖动
--LEDNum; //修改为自减 ,改成LEDNum++也行
P2=LEDNum;//不取反
}
}
}
ps:这个方法也能实现相同操作,但是会有点不同,按下第一次按键时,8个灯全部点亮,再按一次全部熄灭,这里不是很懂,感觉应该是时序问题?第三次开始和上面的指令是一样的。这里lednum=1111 1111,第一次自减后为1111 1110,第二次为1111 1101,第三次为1111 1100,第四次为 1111 1011,第五次1111 1010,依次类推。
7、独立按键控制LED移位
先插入一个运算符优先级链接http://t.csdnimg.cn/XdN7o
全局变量默认为0;
#include <REGX52.H>
#include<intrins.h>
void Delay(xms) //@12.000MHz
{
unsigned char data i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
unsigned char lednum;//全局变量,默认初始值为0
void main()
{
P2=~0x01;//因为下面描述的原因,进行调整,一上电就亮第一个灯
while(1)
{
//注意P2=~0x01;不放到while(1)循环来,具体原因自己试一下就知道了。
// 当while(1)循环体内执行完,继续从当while(1)循环体执行,而不会再执行P2=~0x01;这条命令,此命令只执行一次
if(P3_1==0)
{
Delay(20);
while(P3_1==0);
Delay(20);
lednum++;
if(lednum>=8)
{
lednum=0; //当按了7次后重新赋值为0,开始循环,没有这一步的话,按7次后灯就灭了,再按也没用。
}
P2=~(0X01<<lednum); //加括号,因为取反运算优先级高于移位,当if语句只有一条时,可以不写大括号。
//0000 0001移1位后0000 0010再取反1111 1101 所以第一个灯忽略了
}
}
}
8、两个独立按键分别控制LED左移和右移
#include <REGX52.H>
#include<intrins.h>
void Delay(xms) //@12.000MHz
{
unsigned char data i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
unsigned char lednum;//全局变量,默认初始值为0
void main()
{
P2=~0x80;
while(1)
{
if(P3_1==0)
{
Delay(20);
while(P3_1==0);
Delay(20);
lednum++;
if(lednum>=8)
{
lednum=0;
}
P2=~(0X80>>lednum);
}
if(P3_0==0)
{
Delay(20);
while(P3_0==0);
Delay(20);
if(lednum==0)
lednum=7;
else
lednum--;
P2=~(0X80>>lednum);
}
}
}
数码管
1、基本知识讲解
高电平驱动能力弱,低电平相对驱动能力强。
无返回值
有返回值
共阴极不带小数点
2、静态数码管显示
#include <regx52.h>
unsigned char nixieTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void nixie (unsigned char location,number)
{
switch(location)
{
case 0:P2_2=1;P2_3=1;P2_4=1;break;
case 1:P2_2=0;P2_3=1;P2_4=1;break;
case 2:P2_2=1;P2_3=0;P2_4=1;break;
case 3:P2_2=0;P2_3=0;P2_4=1;break;
case 4:P2_2=1;P2_3=1;P2_4=0;break;
case 5:P2_2=0;P2_3=1;P2_4=0;break;
case 6:P2_2=1;P2_3=0;P2_4=0;break;
case 7:P2_2=0;P2_3=0;P2_4=0;break;
}
P0=nixieTable[number];
}
void main()
{
nixie (2,15); //效果:第二位数码管显示F,如果不显示的话,要注意空格,调用的格式要与形参保持一致
//包括空格 ,建议直接复制,自己敲可能空格的位置没对上,导致实现不了想要的效果
while(1)
{
}
}
3、动态数码管显示
#include <regx52.h>
void Delay( int xms) //@12.000MHz
{
unsigned char data i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
unsigned char nixieTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void nixie (unsigned char location,number)
{
switch(location)
{
case 0:P2_2=1;P2_3=1;P2_4=1;break;
case 1:P2_2=0;P2_3=1;P2_4=1;break;
case 2:P2_2=1;P2_3=0;P2_4=1;break;
case 3:P2_2=0;P2_3=0;P2_4=1;break;
case 4:P2_2=1;P2_3=1;P2_4=0;break;
case 5:P2_2=0;P2_3=1;P2_4=0;break;
case 6:P2_2=1;P2_3=0;P2_4=0;break;
case 7:P2_2=0;P2_3=0;P2_4=0;break;
}
P0=nixieTable[number];
Delay(1); //消影,延时1s
P0=0x00;//数码管归零,什么都不显示,不加这一步也行,效果一样
}
void main()
{
while(1)
{
nixie (0,1);
nixie (1,2);
nixie (2,3);
}
}