速通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
相关推荐
benjiangliu3 小时前
STM32教程-02-STM32复习C语言
c语言·stm32·嵌入式硬件
Nautiluss3 小时前
一起调试XVF3800麦克风阵列(三)
linux·人工智能·嵌入式硬件·音频·语音识别·dsp开发·智能音箱
LCG米4 小时前
嵌入式Python开发:MicroPython在物联网硬件上的实战应用案例
python·单片机·物联网
云山工作室4 小时前
基于zigbee的广告牌安全监测系统设计与实现(论文+源码)
单片机·毕业设计·毕设
DIY机器人工房4 小时前
简单理解:为什么错误计数器一般要选 uint32_t 类型?
stm32·单片机·嵌入式硬件·嵌入式·diy机器人工房
上大科技蔡生4 小时前
CS5567:具有宽占空比范围的60V同步降压DCDC控制器
单片机·嵌入式硬件·fpga开发·dcdc
lingzhilab5 小时前
零知IDE——基于STM32F103RBT6的PAJ7620U2手势控制WS2812 RGB灯带系统
stm32·单片机·嵌入式硬件
三佛科技-187366133975 小时前
BP85956D集成VCC电容电机驱动BUCK电源芯片(12V300mA应用电路)
stm32·单片机·物联网
爱睡觉的王宇昊5 小时前
PCB设计完全指南:从软件选择到基础规范(通用电路篇详解)
笔记·stm32·单片机·嵌入式硬件·学习