速通51单片机————数码管显示与模块化编程

数码管静态显示

先来看看74138译码器:

其中:P22-P24三个端口控制八个LED灯(2的3次方),采用进制法控制:

如下代码:P2_4=1,P2_3=0,P2_2=0

代表着100,也就是4,那么就是第四个LED灯亮,那么以为着这里的三个口从下往上对应着高位到低位

然后我们再控制第四个LED灯怎么亮:

共8个晶体管,就近原则对应,具体原理请看相关视频或者自行百度,这里就不一一赘述了

然后我们再控制P0端口,8个晶体管都是采用8个数字也就是二进制进行控制

原本我们控制完晶体管如何显示之后,那么八个晶体管都会统一显示该数字

但由于我们先前已经控制了某个LED灯亮,其余的都是暗,所以此时只会显示一个LED

需要注意的是控制晶体管显示的74HC245是从上往下对应高位到低位,与之前的相反

所以假如我们令P0=0x7D,则为二进制的:0111 1101 那么此时晶体管会显示6

具体代码如下:

cpp 复制代码
#include <REGX52.H>

void main()
{
	//高位对高
	//控制让哪个LED亮
	P2_4 = 1;
	P2_3 = 0;
	P2_2 = 0;
	//上面为100,说明是让LED4亮
	P0 = 0x7D;//二进制为0111 1101,也就是让晶体管显示6
	while(1)
	{
		
	}
}

现在再来优化上述的方法,我们采用解耦的形式:

先构建一个char数组,用来存放晶体管对应数字的进制表示

然后为了方便起见,我们构建一个函数,采用switch语句,输入1则表示第一个LED亮,2则表示第二个LED亮,以此类推

函数内部再令P0 = 我们想要显示的数字

好了,例如:此时我们需要在第七个LED灯显示数字7

那么就调用函数Nixie(7,7)即可

cpp 复制代码
#include <REGX52.H>

unsigned char NixieTable[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x00};

void Nixie(unsigned char Location, int Number)
{
	switch(Location)
	{
		case 1:
			P2_4 = 1; P2_3 = 1; P2_2 = 1; break;
		case 2:
			P2_4 = 1; P2_3 = 1; P2_2 = 0; break;
		case 3:
			P2_4 = 1; P2_3 = 0; P2_2 = 1; break;
		case 4:
			P2_4 = 1; P2_3 = 0; P2_2 = 0; break;
		case 5:
			P2_4 = 0; P2_3 = 1; P2_2 = 1; break;
		case 6:
			P2_4 = 0; P2_3 = 1; P2_2 = 0; break;
		case 7:
			P2_4 = 0; P2_3 = 0; P2_2 = 1; break;
		case 8:
			P2_4 = 0; P2_3 = 0; P2_2 = 0; break;
	}
	P0 = NixieTable[Number];
	
}

void main()
{
	Nixie(7,7);
	while(1)
	{
		
	}
}

数码管的动态显示

完成了静态显示,此时就再进行动态显示

我们知道人眼是会有视觉残留的,所以多个LED灯进行动态显示就是利用这个原理

我们再原本的代码上增加Delay函数,然后将其放进Nixie函数内部,这是为了防止代码执行过快使得显示出错**(因为先控制第几个亮再将显示数字传入,当语句执行过快时,某一个亮的LED应该显示的内容就会被传入下一个亮的LED里)**,所以我们需要让一个LED灯亮,然后显示完该数据,等待短暂时间然后清掉数据,再进行第二部,这是最稳妥的办法。

然后在while语句内多次调用Nixie函数,如下列函数的调用,此时晶体管就会无限循环显示123,又因为语句执行过快,人眼感受不到变化,则只能感觉到LED灯一直亮着123

cpp 复制代码
#include <REGX52.H>

unsigned char NixieTable[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x00};

void Delay(unsigned int xms)		//@12.000MHz
{
	unsigned char i, j;
	
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}


void Nixie(unsigned char Location, int Number)
{
	switch(Location)
	{
		case 1:
			P2_4 = 1; P2_3 = 1; P2_2 = 1; break;
		case 2:
			P2_4 = 1; P2_3 = 1; P2_2 = 0; break;
		case 3:
			P2_4 = 1; P2_3 = 0; P2_2 = 1; break;
		case 4:
			P2_4 = 1; P2_3 = 0; P2_2 = 0; break;
		case 5:
			P2_4 = 0; P2_3 = 1; P2_2 = 1; break;
		case 6:
			P2_4 = 0; P2_3 = 1; P2_2 = 0; break;
		case 7:
			P2_4 = 0; P2_3 = 0; P2_2 = 1; break;
		case 8:
			P2_4 = 0; P2_3 = 0; P2_2 = 0; break;
	}
	P0 = NixieTable[Number];
	Delay(1);
	P0 = 0x00;
}

void main()
{
	while(1)
	{
		Nixie(1,1);	
		//Delay(2);
		Nixie(2,2);	
		//Delay(2);
		Nixie(3,3);	
		//Delay(2);
		//Nixie(4,4);	
		//Delay(2);		
	}
}

模块化编程

这个是C语言的内容,大家可以去B站看相关视频,或者看5-1 模块化编程_哔哩哔哩_bilibili

具体来说就是将声明(.h)定义(.c)实现(main.c)分别在三个不同的文件,解耦化,方便处理。

这里仅提供我们的解耦化后的代码,大家需要注意文件名与引用的头文件:

Delay.h

cpp 复制代码
#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);
	
#endif

Delay.c

cpp 复制代码
void Delay(unsigned int xms)		//@12.000MHz
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
				while (--j);
		} while (--i);
	}
}

Nixie.h

cpp 复制代码
#ifndef __NIXIE_H__
#define __NIXIE_H__

void Nixie(unsigned char Location, int Number);

#endif

Nixie.c

cpp 复制代码
#include <REGX52.H>
#include "Delay.h"


unsigned char NixieTable[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x00};

void Nixie(unsigned char Location, int Number)
{
	switch(Location)
	{
		case 1:
			P2_4 = 1; P2_3 = 1; P2_2 = 1; break;
		case 2:
			P2_4 = 1; P2_3 = 1; P2_2 = 0; break;
		case 3:
			P2_4 = 1; P2_3 = 0; P2_2 = 1; break;
		case 4:
			P2_4 = 1; P2_3 = 0; P2_2 = 0; break;
		case 5:
			P2_4 = 0; P2_3 = 1; P2_2 = 1; break;
		case 6:
			P2_4 = 0; P2_3 = 1; P2_2 = 0; break;
		case 7:
			P2_4 = 0; P2_3 = 0; P2_2 = 1; break;
		case 8:
			P2_4 = 0; P2_3 = 0; P2_2 = 0; break;
	}
	P0 = NixieTable[Number];
	Delay(1);
	P0 = 0x00;
}

main.c

cpp 复制代码
#include <REGX52.H>
#include "Delay.h"
#include "Nixie.h"

void main()
{
	while(1)
	{
		Nixie(1,1);	
		//Delay(2);
		Nixie(2,2);	
		//Delay(2);
		Nixie(3,3);	
		//Delay(2);
		//Nixie(4,4);	
		//Delay(2);		
	}
}

LCD1602调试工具

下图是简单介绍该调试工具的函数作用,我们只需要了解如何使用即可,具体原理可不深究

LCD_Init()

在使用该调试工具时必须要调用该函数进行初始化!

LCD_ShowChar()

cpp 复制代码
LCD_ShowChar(x,y,'A');//在第x行第y列显示'A'字符

LCD_ShowString()

cpp 复制代码
LCD_ShowString(x,y,"Hello");//在第x行第y列显示"Hello"字符串

LCD_ShowNum()

cpp 复制代码
LCD_ShowNum(x,y,123,n);
//在第x行第y列显示123的后n位
//n=2,则显示23
//n=3,则显示123
//n=4,则显示0123

LCD_ShowSignedNum()

cpp 复制代码
LCD_ShowSignedNum(x,y,-66,n);//在第x行第y列显示-66的后n位(不包含负号)

LCD_ShowHexNum()

cpp 复制代码
LCD_ShowHexNum(x,y,0xA8,n);
//在第x行第y列显示后n位16进制字符,n用法相同
//因为0xA8是两位,所以n一般位2

LCD_ShowBinNum()

cpp 复制代码
LCD_ShowBinNum(x,y,0xA8,n);
//在第x行第y列显示n位的二进制的字符
//因为诸如0xA8的十六机制一般为两组4位二进制表示,所以n一般为8
相关推荐
国科安芯9 小时前
航天器多路并联大功率电源系统设计与ASP4644均流特性分析
单片机·嵌入式硬件·fpga开发·安全性测试
茯苓gao11 小时前
嵌入式开发笔记:CANopen相关移位运算与通信协议术语详解
网络·嵌入式硬件·学习·信息与通信
梁朝辉14 小时前
STM32H750VBT6中ADCINP与INN什么区别
stm32·单片机·嵌入式硬件
省四收割者15 小时前
一文详解信号完整性(1)
python·嵌入式硬件·数学建模·信息与通信·信号处理·智能硬件
崇山峻岭之间15 小时前
单片机无感FOC驱动之ADC
单片机·嵌入式硬件
Ligocious16 小时前
1.点亮一颗小小的LED
单片机·嵌入式硬件
KaifuZeng20 小时前
通信与接口协议面试八、CAN通信
单片机·嵌入式硬件·面试·通信与接口协议
智源单片机设计21 小时前
基于单片机的直流电机双闭环调速系统设计
单片机·嵌入式硬件
KaifuZeng1 天前
通信与接口协议面试一、基本概念
嵌入式硬件·通信与接口协议
wuyk5551 天前
24. C 语言模块化:不是拆几个.c 文件那么简单
c语言·开发语言·stm32·单片机