公告:

51单片机学习之LED灯、数码管、按键原理图及程序

作者:智凡单片机 / 时间:4个月前 (08/07) / 分类:51单片机 / 阅读:23126 / 评论:0

在芯片的学习中,51可以说是入门级的芯片,它易学好用,可以为以后的学习打下良好的基础。在51单片机的学习中。我们应当一步一步慢慢来,不要好高骛远。

首先我们第一个开始学习的应当是各种元器件的认识,电容电阻电位器等的辨别与功能。接下来就是学习如何写程序,来控制单片机做一些应用。点亮一颗led灯,我们首先要看原理图51单片机学习之LED灯、数码管、按键原理图及程序 51单片机 第1张
在这张图中我们就可以看到每一个led灯的链接引脚,利用引脚产生高低电平来点亮led灯(我们需要知道它们是共阴极VCA还是共阳极VCC),当时共阴极,接高电平(1)产生电位差,形成电流流动,可以点亮,同理共阳极接低电平(0)来点亮led灯。然后就可以据此来写程序。
#include "reg52.h"    //此文件中定义了单片机的一些特殊功能寄存器
sbit led=P2^0;    //将单片机的P2.0端口定义为led
void main()
{
while(1)
{
led=0; //P2.0端口设置为低电平
}
}
然后我们就可以根据这个代码改变让led灯变得闪烁,只要加一个眼石函式delay来控制亮的时间和灭的时间,由此就可以达到闪烁的效果,delay函数的编写是非常简单的:
void delay(unsigned int i)//我们需要定义无字符类型的数据
{
while(i--); //只需要进行数的循环使延时单片机的数据时间
}

接下来我们就可以先让灯亮,延时之后再让灯灭了,让后无限循环就可以了。

然后上一个代码就可以改成:
led = 0;
delay(10);//可以增大或减小来控制它的闪烁速度;
led = 1;
也就可以控制每一个灯的亮灭来做一个流水灯,他们的原理都是一样的,我们就可以重复写他们的亮灭及其间隔时间来控制。
当led灯学的差不多之后就可以使用数码管了,数码管和led灯的原理都一样,只是位数多一点,我们要经过位选,再用段选控制每一个数码管中某个或几个led灯的亮与灭来显示数字。51单片机学习之LED灯、数码管、按键原理图及程序 51单片机 第2张
从这张图片我们就可以直观的看到每一个数码管中每一个led灯的引脚的选择,我们就可以控制他的亮与灭来显示数字了,首先进行位置的选择,总共8位,在进行灯的选择。现在多数单片机都用到了138译码器来控制位选,我们可以用原理图来看怎样控制。51单片机学习之LED灯、数码管、按键原理图及程序 51单片机 第3张

由此我们就可以对138译码器有着3个引脚控制8个位置的能力有了认识。然后我们就可以开写代码了:

#include
typedef unsigned int u16;
typedef unsigned char u8;
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;
u8 code duan[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//从0——f,单片机多数都用16进制
u8 DisplayData[8];
void delay(u16 sum)//延时函数
{
while(sum--);
void DigDisplay()
{
u8 i;
for(i=0;i<8;i++)
{
switch(i)  
{
case(0):
LSA=0;LSB=0;LSC=0; break;//显示第0位
case(1):
LSA=1;LSB=0;LSC=0; break;//显示第1位
case(2):
LSA=0;LSB=1;LSC=0; break;//显示第2位
case(3):
LSA=1;LSB=1;LSC=0; break;//显示第3位
case(4):
LSA=0;LSB=0;LSC=1; break;//显示第4位
case(5):
LSA=1;LSB=0;LSC=1; break;//显示第5位
case(6):
LSA=0;LSB=1;LSC=1; break;//显示第6位
case(7):
LSA=1;LSB=1;LSC=1; break;//显示第7位
}
P0=DisplayData[i];//发送段码
delay(10); //间隔一段时间扫描
P0=0x00;//消隐
}
}
void main()
{ u16 i;
while(1)
{
  DigDisplay();
    for(i=0;i<8;i++)//循环位选
{
DisplayData[i] = duan[i];//进行段选
}
}
}
经过了单片机的循环,就可以开始我们独立按键,及矩阵的学习。用独立按键去控制led灯,用点阵在数码管显示点阵的键值。51单片机学习之LED灯、数码管、按键原理图及程序 51单片机 第4张


51单片机学习之LED灯、数码管、按键原理图及程序 51单片机 第5张
独立按键已经连接了高低电平,只是高低电平并未接通,我们按下之后高低电平接通,高电平由于接了低电平变成低电平,我们就可以写判断语句:

if(K1 == 0)
{
led = 1;
}
else 
{
led = 0;
}
这样就可以在按键按下的时候熄灭led灯,松开的时候点亮led灯。在按键的使用中,我们还需要用到消抖和松键检测。也就可以把这个程序改为
         if(k1==0)   //检测按键K1是否按下
delay(1000);   //消除抖动 一般大约10ms
if(k1==0) //再次判断按键是否按下
{
led=~led;   //led状态取反
}
while(!k1); //检测按键是否松开
而在矩阵中,我们需要将每个键赋值(0——f),然后按键后在数码管显示数值。
#include
typedef unsigned int u16;
typedef unsigned char u8;
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;
#define GIFO P1
#define GG P0
u16 Key;
u8 code duan[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};  //0--z
void delay(u16 sum)
{
while(sum--);
}
void anjian() //判断按下的按键,并且将对应的键值赋给Key
{
GIFO = 0x0f;
if(GIFO!=0x0f)
{
delay(10);
if(GIFO!=0x0f)
{
switch(GIFO)
{
case(0X07): Key=0;break;//键值的判断
case(0X0b): Key=1;break;
case(0X0d): Key=2;break;
case(0X0e): Key=3;break;
   }
   GIFO=0xf0;
   switch(GIFO)
           {
        case(0X70): Key=Key;break;
case(0Xb0): Key=Key+4;break;
case(0Xd0): Key=Key+8;break;
case(0Xe0): Key=Key+12;break;
   }
   while(GIFO!=0xf0)
   delay(10);
}
}
}
void main()
{  
LSA=0; //给一个数码管提供位选
LSB=0;
LSC=0;
while(1)
{
anjian();
GG = duan[Key]; //将键值应显示数字赋给数码管
}
}
然后就可以学习点阵显示数字字符字母,点阵一般是由8*8或者16*16的led灯阵组成,由一组引脚或两组引脚控制。我们在学习时候一定要看一下原理图,经过自己缜密的思考后在进行学习,我们要明白单片机的学习离不开看原理图,这是非常重要的,我们可以从原理图看出,这是共阴极还是共阳极,他的引脚都接在了那里,我们应当怎样控制它的亮与灭。51单片机学习之LED灯、数码管、按键原理图及程序 51单片机 第6张
51单片机学习之LED灯、数码管、按键原理图及程序 51单片机 第7张
我们就可以看到,我们这个单片机是由74HC595来控制的,由3个引脚和P0组的引脚来发送数据来进行点亮点阵中的某一个led灯,然后我们就可以看一下74HC595的原理 74HC595是具有8位移位寄存器和一个存储器,三态输出功能。 移位寄存器和存储器是分别的时钟。 数据在SHcp(移位寄存器时钟输入)的上升沿输入到移位寄存器中,在STcp(存储器时钟输入)的上升沿输入到存储寄存器中去。如果两个时钟连在一起,则移位寄存器总是比存储寄存器早一个脉冲。 移位寄存器有一个串行移位输入(Ds),和一个串行输出(Q7’),和一个异步的低电平复位,存储寄存器有一个并行8位的,具备三态的总线输出,当使能OE时(为低电平),存储寄存器的数据输出到总线。

8位串行输入/输出或者并行输出移位寄存器,具有高阻关断状态。三态。

然后明白原理我们就可以点亮点阵了

#include

#include//移位的头文件

#define GG P0

typedef unsigned int u16;   //对数据类型进行声明定义

typedef unsigned char u8;

sbit SRCLK=P3^6;

sbit LCLK=P3^5;

sbit SER=P3^4;

u8 code duan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

                  0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

u8 code wei[8]= {0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};

u8 code CHARCODE[1][8]={0x00,0x66,0xff,0xff,0xff,0x7e,0x3c,0x18};//在我的单片机是个心形,单片机                                                                                                                      //的不同可能有所不同

void delay(u8 sum)

{

   while(sum--);

void HC595(u8 dat)

{

    u8 a;

SRCLK = 0;

LCLK = 0;

for(a=0;a<8;a++)

{

SER = dat>>7;//右移7位

dat<<=1;//左移一位

SRCLK=1;

_nop_();

_nop_();

SRCLK=0;


}

    LCLK=1;

_nop_();

_nop_();

LCLK=0;


}

void main()

{

u8 tab;

while(1)

{

for(tab=0;tab<8;tab++)

{

HC595(0x00);      //消隐

GG = wei[tab]; //输出字码

HC595(CHARCODE[0][tab]);

delay(2);

}

 

}

}



没有评论,留下你的印记,证明你来过。


发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。