1、数码管基本原理

数码管是一种常见的显示装置,用于显示数字或字符。在51单片机中,我们可以使用数码管来显示数字、字母、符号等信息。

51单片机通过控制数码管的引脚,来控制数码管的显示内容。常见的数码管类型有共阴数码管和共阳数码管。

1、段选

普中A2开发板使用的是8位8段共阴极数码管,引脚高电平点亮。因此0-9的段码是

unsigned char code NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

因为51ROM空间大,RAM空间下,所以可以定义到ROM存放该显示数组,加code关键字,大家可以编译的时候观察存储空间的变化情况。

2、位选

位选信号就是选择8个数码管的哪个,根据74LS138芯片来进行位选。由P22、P23、P24来进行控制,这个地方的A2就有个问题,由于这3个引脚同时控制3个Led灯,而数码管的位选要不停地进行刷新,也就是扫描。凡是采用数码管的应用,这3个灯就常亮,没有办法控制。

2、数码管的动态显示

数码管的动态显示是利用人眼的视觉暂留和数码管的余晖效应实现的。我们看到的是数码管的同时显示,而实际上并非同时,只是CPU的运行速度比较快,数码管刷新的时间比较短,每个数码管显示大约1-2ms,循环进行。由于蓝桥杯基本上都是用数码管来显示数据,因此对于数码管的显示代码需要进行处理,不能用延时函数来做,可能就在延时的那一刻,需要扫描键盘了,但是却读不出按键值。我们先上数码管驱动代码Nixie.c和Nixie.h头文件

#include <REGX52.H>


unsigned char code NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

//数码管显示子函数
void Nixie(unsigned char Location,Number)
{
  P0=0x00;				//段码清0,消影
	switch(Location)		//位码输出
	{
		case 0:P2_4=1;P2_3=1;P2_2=1;break;
		case 1:P2_4=1;P2_3=1;P2_2=0;break;
		case 2:P2_4=1;P2_3=0;P2_2=1;break;
		case 3:P2_4=1;P2_3=0;P2_2=0;break;
		case 4:P2_4=0;P2_3=1;P2_2=1;break;
		case 5:P2_4=0;P2_3=1;P2_2=0;break;
		case 6:P2_4=0;P2_3=0;P2_2=1;break;
		case 7:P2_4=0;P2_3=0;P2_2=0;break;
	}
		P0=NixieTable[Number];	//段码输出
	 
}

#ifndef __NIXIE_H__
#define __NIXIE_H__

void Nixie(unsigned char Location,Number);

#endif

3、使用定时器刷新数码管

1、1ms定时

我们使用定时器T0来进行1ms定时,这里需要初始化T0定时器。同学们可以打开STC-ISP软件,找到定时器计算器。

将AUXR那一行去掉,因为我们的STC89C52RC没有这个寄存器,如果是其他的STC12或15系列则不用删除。最后在初始化函数后面不要忘记打开中断。

/* 定时器0中断初始化函数 */
void Timer0Init(void)		//1毫秒@12.000MHz
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;
	EA=1;
}

2、定时器中断服务函数

相关的知识默认同学们已经听过相关课程了,就不再赘述了,可以看B站单片机蓝桥杯视频大模板,我这边采用这个模版主要是为了以后做省赛题做铺垫。

定义相关变量在中断服务函数里面不断地扫描每个数码管,让其显示。

unsigned char Seg_Buf[8] = {10,10,10,10,10,10,10,10};//数码管显示数据存放数组
unsigned char Seg_Pos;//数码管扫描专用变量

/* 定时器0中断服务函数 */
void Timer0Server() interrupt 1
{  
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	if(++Seg_Pos == 8) Seg_Pos = 0;//数码管显示专用
	Nixie(Seg_Pos,Seg_Buf[Seg_Pos]);
}

4、信息处理显示函数

这里可以自己显示你想显示的数字或者字符,如果没有相关字符可以在段码显示数组自己定义,后面的文章也会有

/* 信息处理函数 */
void Seg_Proc()
{
	Seg_Buf[0]=5;
	Seg_Buf[1]=6;
	Seg_Buf[2]=7;
	Seg_Buf[3]=8;
	Seg_Buf[4]=5;
	Seg_Buf[5]=6;
	Seg_Buf[6]=7;
	Seg_Buf[7]=8;
}

5、结果展示

6、主函数的所有代码

#include <REGX52.H>
#include "Nixie.h"

unsigned char Seg_Buf[8] = {10,10,10,10,10,10,10,10};//数码管显示数据存放数组
unsigned char Seg_Pos;//数码管扫描专用变量


/* 信息处理函数 */
void Seg_Proc()
{
	Seg_Buf[0]=5;
	Seg_Buf[1]=6;
	Seg_Buf[2]=7;
	Seg_Buf[3]=8;
	Seg_Buf[4]=5;
	Seg_Buf[5]=6;
	Seg_Buf[6]=7;
	Seg_Buf[7]=8;
}


/* 定时器0中断初始化函数 */
void Timer0Init(void)		//1毫秒@12.000MHz
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;
	EA=1;
}

/* 定时器0中断服务函数 */
void Timer0Server() interrupt 1
{  
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	if(++Seg_Pos == 8) Seg_Pos = 0;//数码管显示专用
	Nixie(Seg_Pos,Seg_Buf[Seg_Pos]);
}

void main()
{
	Timer0Init();
	while(1)
	{  
		Seg_Proc();	
	}
	
}



8、硬件加载--前面的示例都比较简单,编译好的机器代码文件加载到单片机里面就可以看到效果了。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐