C51单片机使用3-数码管显示

本文详细介绍了数码管的工作原理和驱动方法,包括静态显示和动态显示。在静态显示中,通过控制位选和段选实现单个及多个数码管的数字显示,动态显示则利用快速切换数码管显示实现看似同时显示的效果。同时,提供了相应的代码实例和延时调整对显示效果的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、硬件介绍

1、原理

2、多位数码管驱动

二、数码管显示控制

1、静态显示

(1)单个数码管

(2)多个数码管显示

(3)显示数字使用编码方式

2、动态显示

(1)原理

(2)代码实现

(3)测试

工程下载链接


一、硬件介绍

1、原理

数码管有单位数码管、双位数码管和其它多位数码管。如下图所示

单个的数码管共10个引脚,显示不同的数字需要7个引脚,小数点占用1个引脚,公共端占用1个,厂家为了生产方便同意10个引脚,3和8引脚都是公共端。根据公共端接线不同分共阴和共阳。单个的数码管的原理如下

比如:

显示数字“8”,则需要点亮a、b、c、d、e、f、g引脚

显示数字“5”,则需要点亮a、c、d、f、g引脚

2、多位数码管驱动

当多位数码管应用于某一系统时,他们的“位选”是可独立控制的,而“段选“是连接在一起的,通过”位选“信号控制哪几个数码管亮。而在同一时刻,位选选通的所有数码管上显示的数字都是一样的(因为他们8段数码都连在一起的),这种显示方式叫静态显示

位和段分别用两个74HC573驱动和控制,P0同时使用上拉电阻。单片机可以控制锁存器的锁存端,进而控制锁存器的数据输出。当锁存使能低电平时11引脚)为高电平时,锁存器输出数据随输入数据变化而变化。当锁存器使能端(11引脚)为高电平时,输出数据为之前状态数据,输出数据不随输入变化。

 六位的数码管显示电气原理图

二、数码管显示控制

数码管采用共阴极方式,即程序中给数码管3和8公共引脚低电平,再给其它段码高电平则段码点亮。

1、静态显示

(1)单个数码管

任务:在左边第二个数码管上显示数字8

位选:

对于要启用的对应数码管,该位为低电平即0。不用的即1。从左往右依次为数码管1-数码管6。没有数码管7和数码管8,则这两个位都写1。

如,对于只启用第二个数码管,则六个数码管的值分别如下:

数码管1:1

数码管2:0

数码管3:1

数码管4:1

数码管5:1

数码管6:1

预留位7:1

预留位8:1

1111 1101即0xFD

段选:

需要点亮的段为1,不点亮的则是0

如,显示数字8,即

a=1

b=1

c=1

d=1

e=1

f=1

g=1

dp=0(小数点)

二进制表示就是0111 1111,16进制表示为0x7F

代码

#include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char


unsigned char m,n;
sbit dula=P2^6;					//段选锁存器-使能控制
sbit wela=P2^7;					//位选锁存器-使能控制


void Delay_ms(uint xms)
{
	uint i,j;	
	for(i=xms;i>0;i--)
		for(j=110;j>0;j--);
}

void main()
{
	wela=1;						//位选锁存器使能
	//P0=0xFE;					//1111 1110 :启用第一个数码管-左边第一个
	P0=0xFD;					//1111 1101 :启用第二个数码管-左边第二个
	wela=0;

	dula=1;						//段选锁存器使能
	P0=0X7F;					//0111 1111	:显示数字8				
	dula=0;
  	while(1)
  	{
	
   	}
}

实验结果

(2)多个数码管显示

显示6个数码管的话,即将位选的6个数码管都置为0,即1100 0000、16进制为0xC0。即可将六个全部都显示。

显示其它个数数码管同样原理即可。

(3)显示数字使用编码方式

任务:从0到F间隔0.5秒依次显示

数码管编码

根据该原理图,将0-F字符如下表格进行编码。

 共阴极数码管编码

注意:

①本原理图数码管为共阴极显示,共阳极数码管编码就不一样了

②如果需要点亮小数点,则需要对表格重新编码。

定义数组

uchar code table[]=
{
	//0-9   A-F,共阴极数码管显示编码
	0x3f,0x06,0x5b,0x4f,
	0x66,0x6d,0x7d,0x07,
	0x7f,0x6f,0x77,0x7c,
	0x39,0x5e,0x79,0x71
};

代码

 #include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char


sbit dula=P2^6;					//段选锁存器-使能控制
sbit wela=P2^7;					//位选锁存器-使能控制
uchar num;

uchar code table[]=
{
	//0-9   A-F,共阴极数码管显示编码
	0x3f,0x06,0x5b,0x4f,
	0x66,0x6d,0x7d,0x07,
	0x7f,0x6f,0x77,0x7c,
	0x39,0x5e,0x79,0x71
};


void Delay_ms(uint xms)
{
	uint i,j;	
	for(i=xms;i>0;i--)
		for(j=110;j>0;j--);
}

void main()
{
	wela=1;						//位选锁存器使能
	//P0=0xFE;					//1111 1110 :启用第一个数码管-左边第一个
	//P0=0xFD;					//1111 1101 :启用第二个数码管-左边第二个
	P0=0xC0;					//1100 0000
	wela=0;

	
	P0=0X7F;					//0111 1111	:显示数字8				

  	while(1)
  	{
		for(num=0;num<16;num++)
		{
			dula=1;						//段选锁存器使能
			P0=table[num];
			dula=0;						//段选锁存器去使能
			Delay_ms(500);				//500毫秒延时
		}
	
   	}
}

2、动态显示

(1)原理

数码管动态显示又叫数码管的动态扫描显示。通俗的说就是先在第一个数码管显示一个数字然后关闭再在在很短的时间延迟后在第二个数码管上显示数字再关闭,再延迟一段时间再在第三个数码管上显示数字,依次类推。

这个延迟时间要设置的非常小,测试的时候从500毫秒到10毫秒内,现象为轮流点亮6个数码管数码管到数码管一起变得闪烁显示数字。最后设置1毫秒延时,因为视觉暂留效应,人的眼睛是看不出来的,所以看起来像是静态显示的一样。

(2)代码实现

#include <reg51.h>
#include <intrins.h>
 
#define uint unsigned int
#define uchar unsigned char
 
 
sbit dula=P2^6;					//段选锁存器-使能控制
sbit wela=P2^7;					//位选锁存器-使能控制
uchar num;
uchar index;
 
uchar code table[]=
{
	//0-9   A-F,共阴极数码管显示编码
	0x3f,0x06,0x5b,0x4f,
	0x66,0x6d,0x7d,0x07,
	0x7f,0x6f,0x77,0x7c,
	0x39,0x5e,0x79,0x71
};
 
 
void Delay_ms(uint xms)
{
	uint i,j;	
	for(i=xms;i>0;i--)
		for(j=110;j>0;j--);
}
 
void main()
{

	uint delayTime=1;			//延时时间-毫秒
	while(1)
	{
		//第一个数码管显示
		num=1;
		dula=1;
		P0=table[num];
		dula=0;
		P0=0xFF;				//消影功能-将所有数码管段都置高电平,都熄灭,就不会有亮点带到下一位数码管上了

		wela=1;
		P0=0xfe;
		wela=0;
		Delay_ms(delayTime);			

		//第二个数码管显示
		num=2;
		dula=1;
		P0=table[num];
		dula=0;
		P0=0xFF;

		wela=1;
		P0=0xfd;					//1111 1101
		wela=0;
		Delay_ms(delayTime);

		//第三个数码管显示
		num=3;
		dula=1;
		P0=table[num];
		dula=0;
		P0=0xFF;

		wela=1;
		P0=0xfb;					//1111 1011
		wela=0;
		Delay_ms(delayTime);

		//第四个数码管显示
		num=4;
		dula=1;
		P0=table[num];
		dula=0;
		P0=0xFF;

		wela=1;
		P0=0xf7;					//1111 0111
		wela=0;
		Delay_ms(delayTime);

		//第五个数码管显示
		num=5;
		dula=1;
		P0=table[num];
		dula=0;
		P0=0xFF;

		wela=1;
		P0=0xef;					//1110 1111
		wela=0;
		Delay_ms(delayTime);

		//第六个数码管显示
		num=6;
		dula=1;
		P0=table[num];
		dula=0;
		P0=0xFF;

		wela=1;
		P0=0xdf;					//1101 1111
		wela=0;
		Delay_ms(delayTime);
	}



}

(3)测试

分别设置delayTime不同的值,依次编译生成HEX文件下载。

500毫秒运行效果:

uint delayTime=500;

100毫秒运行效果:

uint delayTime=100;

20毫秒运行效果:

uint delayTime=20;

5毫秒运行效果:

uint delayTime=5;

1毫秒运行效果:

uint delayTime=1;


工程下载链接



https://download.csdn.net/download/panjinliang066333/86504920

### 使用C51单片机驱动数码管显示温度传感器数据 #### 系统概述 为了实现一个能够实时监测并显示环境温度的系统,可以选择使用C51单片机作为核心控制器,并配备合适的温度传感器和显示器组件。在此案例中,选用的是DS18B20数字温度传感器以及静态数码管用于数据显示[^1]。 #### 主要组成部分说明 - **温度传感模块**:采用DS18B20传感器负责收集周围空气中的实际温湿度情况;该器件具备较高的测量精度(可达±0.5°C),并且可以直接输出数字化后的结果给MCU处理。 - **微控制器单元(MCU)**:这里指的就是STC系列或其他兼容型号的8位AT89S52/51型单片计算机芯片,它承担着接收来自前端感知元件的信息、执行必要的算法运算并将最终得到的数据映射成适合视觉呈现的形式等功能角色。 - **显示终端设备**:由多个七段LED构成的一组或多组阳极或阴极连接方式组成的多位数显装置——即所谓的“数码管”,用来直观反映当前所处位置下的具体数值变化趋势。 #### 关键技术要点解析 ##### 初始化设置 在程序启动初期阶段,应当先完成对于各个外设资源的基础配置工作,比如初始化I/O端口状态、定义全局变量存储空间大小等操作: ```c #include <reg52.h> // 定义公使用的参数 unsigned char code smgduan[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; // 数字对应7段码表 bit flag; float temperature; void delay(unsigned int z) { unsigned int x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void init(void){ TMOD = 0X01; // 设置定时器模式 TH0=(65536-5000)/256; // 初值计算 TL0=(65536-5000)%256; } ``` ##### 获取温度读数 借助于专门编写的子例程从指定地址获取最新的温度采样点记录下来供后续分析调用: ```c sbit DQ=P3^7; void start_convert(){ uchar i; DQ=0; delay(5); // 延迟大于等于750ns DQ=1; while(DQ==0); // 等待低电平结束 while(DQ==1); // 等待存在脉冲到来 } uchar read_bit(){ uchar bit_value; DQ=0; DQ=1; nops(); nops(); bit_value=DQ; while(!DQ); return(bit_value); } char ds18b20_read_temp(){ uchar temp_l,temp_h,i,j,t; float tem; start_convert(); DQ=0; for(i=0;i<8;i++){ DQ=1; DQ=0; t=read_bit(); if(t==1) j|=0x01<<i; } DQ=1; temp_l=j; for(i=0;i<8;i++){ DQ=1; DQ=0; t=read_bit(); if(t==1) j|=0x01<<i; } DQ=1; temp_h=j; tem=((temp_h&0x0F)<<8)+temp_l; tem*=0.0625; if(temp_h & 0xf0) tem=-tem; return (int)(tem*10); } ``` ##### 更新显示屏内容 每当有新的有效数据到达时,则需及时刷新屏幕上的图像以保持界面同步更新的效果: ```c void display(int num){ P0=smgduan[num%10]; P2=0xfe; delay(5); P0=smgduan[(num/10)%10]; P2=0xfd; delay(5); P0=smgduan[(num/100)%10]; P2=0xfb; delay(5); P0=smgduan[num/1000]; P2=0xf7; delay(5); } void main(){ EA=1; ET0=1; TR0=1; init(); while(1){ temperature = ds18b20_read_temp()/10.0f; display((int)temperature); } } ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Big_潘大师

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

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

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

打赏作者

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

抵扣说明:

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

余额充值