数码管静态显示
先来看看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