蓝桥杯单片机学习3——数码管静态显示

上期我们学习了如何控制蜂鸣器和继电器,那么这次就开始来学习数码管的静态显示

效果展示

在这里插入图片描述

结果就是在数码管上显示了一列数字,当然也可以显示一部分字母,至于怎么显示,接着往下看,心急吃不了热豆腐

原理图

在这里插入图片描述

数码管

既然要学会使用数码管的静态显示,当然我们要知道数码管的工作原理:
在这里插入图片描述
数码管本质上就是一堆相同的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译码器来控制,所有我才把它们都放在了一个头文件里,同时也是为了以后自己写代码的便捷性。
以上的代码都已经写好了注释,逻辑应该都挺简单的,大家自行食用吧,有不懂的也可以留言评论。

>总结:都看到这了,给个关注不过分吧。

在这里插入图片描述

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不想写代码的我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值