上期我们学习了如何控制蜂鸣器和继电器,那么这次就开始来学习数码管的静态显示
效果展示
结果就是在数码管上显示了一列数字,当然也可以显示一部分字母,至于怎么显示,接着往下看,心急吃不了热豆腐
原理图
数码管
既然要学会使用数码管的静态显示,当然我们要知道数码管的工作原理:
数码管本质上就是一堆相同的LED组成的,当我们要通过数码管显示不同的数字时,只需要将不同位置的LED点亮即可,比如我们要显示一个数字‘2’,则只需要让编号为a、b、d、e、g的LED亮起,就可以实现,原理是很简单的。
根据数码管点亮的逻辑不同,又可以将数码管分为共阴极和共阳极的数码管,我们板子上的数码管是负逻辑点亮的,因此可以知道是共阳极的数码管。
总结:数码管为共阳极数码管,写0点亮对应的LED(负逻辑点亮)
段码
什么是段码呢?虽然我们知道了怎么去在数码管上显示对应的数字,但是如果让我们一个一个的推出对应的LED状态,难免有些头大,为了方便,我们就搞出了一个段码,来方便对LED显示不同的数字。
这个就是我总结出来的段码,只针对于我们板子上面的这种共阳极数码管。每个段码对应一个字节的内容,在数码管上可以显示与注释上对应的数字或字母。
数码管的位选
问题又来了,我们的板子上一共有八个数码管,我们怎么能实现在八个数码管上显示不同的数字呢,
这个就要提到数码管的位选了,在原理图上我们只需要在标注了位选的com口上输出高电平就可以选择需要显示内容的数码管,那么我们只需要不断的切换需要显示内容的数码管,并且在不同的数码管上显示不同的内容。就可以实现数码管的静态显示。当然干讲大半天也没啥用,大家可以到后面去看我的代码,这里就不给大家展示了.
>具体的思路就是:
打开数码管1—>显示数字0—>打开数码管2—>显示数字1—>打开数码管3—>显示数字2…….
[注]:这里我们一次只能选择一个com口点亮,当同时选择多个Com口时可能会导致在不同的数码管上显示相同的数字或者显示不正常
位选实现的原理
关于这个数码管是怎么实现位选的,我这里去找了一些资料,不过很遗憾,我没有找到和我们这个板子相匹配的,不过我们可以参考一下下面这个电路图
这个电路和我们板子和逻辑刚好相反,不过如果搞懂了这个,那么板子上的数码管也是一样的理解,
具体原理,大家可以自行理解,没啥好讲的
总结:自己看吧,没啥总结的了[doge]
代码实现
1. main函数
#include <STC15F2K60S2.H>
#include <INTRINS.h>
#include "LS138.h"
unsigned char SEG[]={0,1,2,3,4,5,6,7};//从左往右写入
void main()
{
LS138_Init(); //初始化函数
while(1)
{
SEG_Write(SEG); //将SEG数组内的数字写入数码管
}
}
2. LS138.h
#ifndef __LS138_H_
#define __LS138_H_
#include <STC15F2K60S2.H>
#include <INTRINS.h>
//#define SEG_Number_ON 7
//#define SEG_Com_ON 6
//#define BUZZER_ON 5
//#define RELAY_ON 5
//#define LED_ON 4
sbit LS138_A = P2^5;
sbit LS138_B = P2^6;
sbit LS138_C = P2^7;
//延时函数,延时2ms @11.0592MHz
static void Delay2ms();
//延时函数,延时300ms @11.0592MHz
static void Delay300ms();
//初始化函数,默认为设置数码管全亮
void LS138_Init(void);
//清除ls138的位选
void LS138_Clear(void);
//设置ls138的位选,控制Data号引脚输出低电平,输入参数范围为4~7有效
void LS138_Set(unsigned int Data);
//在数码管上显示对应的数字,显示内容为数组p[i]对应到NixieTube[]数组中的数子或英文字符,
//显示方向为从左向右显示,p为传入数组的地址,
//原理图上数码管为共阴极数码管
void SEG_Write(unsigned char* p);
//控制LED的亮和灭,写0为灭,写1亮。
void LED_Contrl(int Flag);
//LED流水灯函数,写1时开始流水灯,写0时停止流水灯
void LED_Run(int Flag);
//控制蜂鸣器的开关。写1时打开,写0时关闭
void BEEP_Contrl(int Flag);
//控制继电器的开关。写1时打开,写0时关闭
void Relay_Control(int Flag);
#endif /*__LS138_H_*/
3.LS138.c
#include "LS138.h"
//这个数组为数码管显示函数对应的数组,可在SEG_Write()函数中显示对应的内容,每一行共十个元素
/*0 1 2 3 4 5 6 7 8 9 */
unsigned char code NixieTube[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,
/* A B C D E F H L N P */
0x88,0x83,0xC6,0xA1,0x86,0x8E,0x89,0xC7,0xC8,0x8C,
/* U - ' ' */
0xC1,0xBF,0xFF};
unsigned char code NixieTube_Init[]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
//延时函数,延时2ms
static void Delay2ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 22;
j = 128;
do
{
while (--j);
} while (--i);
}
static void Delay300ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 13;
j = 156;
k = 83;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
//初始化函数,
void LS138_Init(void)
{
SEG_Write(NixieTube_Init);
LED_Contrl(0);
BEEP_Contrl(0);
Relay_Control(0);
LS138_A=LS138_B=LS138_C=0;
P0 = 0xFF;
}
//清除ls138的位选
void LS138_Clear(void)
{
LS138_A=LS138_B=LS138_C=0;
P0 = 0xFF;
}
//设置ls138的位选,控制输出端Data号引脚输出低电平,输入参数范围为4~7有效
void LS138_Set(unsigned int Data)
{
switch(Data)
{
case 0: LS138_A=LS138_B=LS138_C=0;
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 4: LS138_A=0;LS138_B=0;LS138_C=1;
break;
case 5: LS138_A=1;LS138_B=0;LS138_C=1;
break;
case 6: LS138_A=0;LS138_B=1;LS138_C=1;
break;
case 7: LS138_A=1;LS138_B=1;LS138_C=1;
break;
}
}
//在数码管上显示对应的数字,显示内容为数组p[i]对应到NixieTube[]数组中的数子或英文字符,
//显示方向为从左向右显示,p为传入数组的地址
//原理图上数码管为共阴极数码管
void SEG_Write(unsigned char* p)
{
unsigned char i =0;
for(i=0;i<8;i++)
{
LS138_Clear();
LS138_Set(7); //ls138译码器位选为数字输入
P0 = NixieTube[*(p+i)];
LS138_Clear();
LS138_Set(6); //ls138译码器位选为管脚选择,对应位为1,则对应的数码管亮起
P0 = (unsigned char )0x01<<i;
Delay2ms();
P0=0xFF;
}
}
//控制LEDl的亮和灭,写0为灭,写1亮。
void LED_Contrl(int Flag)
{
if(Flag)
{
LS138_Clear();
LS138_Set(4);
P0 = 0x00;
}
else
{
LS138_Clear();
LS138_Set(4);
P0 = 0xFF;
}
}
//LED流水灯函数,写1时开始流水灯,写0时停止流水灯
void LED_Run(int Flag)
{
unsigned char i=0;
LS138_Clear();
if(Flag)
{
for(i=0;i<8;i++)
{
LS138_Set(4);
P0 = ~(unsigned char )(0x01<<i);
LS138_Clear();
Delay300ms();
}
}
else
{
LS138_Clear();
LS138_Set(4);
P0 = 0xFF;
}
}
//控制蜂鸣器的开关。写1时打开,写0时关闭
void BEEP_Contrl(int Flag)
{
if(Flag)
{
LS138_Clear();
LS138_Set(5);
P0 |= 0x40;
LS138_Clear();
}
else
{
LS138_Clear();
LS138_Set(5);
P0 = P0 & 0xBF;
LS138_Clear();
}
}
//控制继电器的开关。写1时打开,写0时关闭
void Relay_Control(int Flag)
{
if(Flag)
{
LS138_Clear();
LS138_Set(5);
P0 |= 0x10;
LS138_Clear();
}
else
{
LS138_Clear();
LS138_Set(5);
P0 = P0 & 0xEF;
LS138_Clear();
}
}
以上就是我这个工程的所有代码,细心的小伙伴可能发现这次的代码很长,这是因为我把前几期的代码都给封装成了库函数,可以实现流水灯,蜂鸣器和继电器的控制等功能,之所以怎么是做是因为这些外设都有一个共同的特点,就是都需要通过LS138译码器来控制,所有我才把它们都放在了一个头文件里,同时也是为了以后自己写代码的便捷性。
以上的代码都已经写好了注释,逻辑应该都挺简单的,大家自行食用吧,有不懂的也可以留言评论。
>总结:都看到这了,给个关注不过分吧。