51单片机数码管滚动显示学号_单片机数码管显示,看完这篇就够了

本文介绍了51单片机数码管的工作原理及显示技术,包括数码管内部电路、静态显示和动态显示。通过实例展示了如何利用单片机驱动数码管显示数字,并提供了共阴极和共阳极数码管的显示方法。此外,还分享了数码管滚动显示学号的编程技巧。

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

数码管简述

5cf6a467d857f55af2eb4ac0c6124048.png

这是一个数码管内部电路原理图,a~h每个数字代表一个发光二极管,v是公共端,可以接地或者电源,对应共阴极和共阳极接法。a~g段数码管用来显示数字,h显示小数点。为了便于封装,数码管的外部一共10个引脚,5和10连在一起接公共端,其余各对应一个发光二极管:

683b5025f7852016cfcf0eff44802ae1.png

例如,如果我们想显示数字“0”,那么就需要a~f这六个数码管亮;如果显示数字“1”,那么就需要b、c两个数码管点亮,以此类推。一般情况下,单片机的IO口和数码管的连接方式如下:

166b23c957328767013e7a7a7209d2d4.png

如果我们将数码管接到P1口上,显示数字“0”的话,那么P1口的八个引脚电平(共阴极数码管)应为:0011 1111转换成二进制就是P1=0x3f,如果是共阳极数码管,则P1=~0x3f,按位取反就可以。如果我们想让小数点显示出来,那么应该将P0.7置1(共阴极),对应引脚电平为1000 0000,二进制0x80,为了简便,我们直接参与按位或的方式,即:

P1=(0x3f|0x80) 共阴极 P1=~(0x3f|0x80) 共阳极

设计实例(数码管静态显示)

Proteus中的数码管有几种形式:内置编码器的数码管、七段数码管(共阴极、共阳极)、八段数码管(共阴极、共阳极),我们分别看一下:

  1. 带有编码器的数码管:

c6cf8208675e278ec0b38d262eaf74da.png

一共四个引脚,最右边是低位,最左边是高位,直接将对应数据的16进制输入即可,例如我们将上图数码管四个管脚由右边到左边依次接P1.0~P.3,如果我们想显示0的话,P1=0x00,显示1的话P1=0x01以此类推。这种数码管使用方便,但是没有使能端,一般只用作静态显示。

  1. 七段数码管(共阴极为例)

7367ab693f9e9e313bff5dc6203bb9b8.png

七段数码管一共七个数据端口,还有一个公共使能端,也叫做位选端。对于共阴极数码管,当公共端接低电平时候,数码管才可以正常工作。七个数据端口上为最低为、下边为高位,接单片机的IO口。例如,单片机的P1.0~P1.1依次接数码管的七个数据端,如果显示0,那么P1=0x3f,以此类推。

  1. 八段数码管(以共阳极为例)

489a20d72db424599d23ff536871eb3b.png

Proteus中八段数码管如图,有八个数据位(第七位同七段数码管,第八位为小数点),由一个位选端。如果想显示数字0,我们没有必要去推导每一位,直接按照共阴极按位取反,即P1=~0x3f,即为共阳极数码管显示数字0的方法。如果想显示小数点,直接按位或0x80,即P1=~(0x3f|0x80),此时显示的即为数字0加小数点。

小福利

共阴极七段数码管0~F的编码:

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

实例2 数码管动态显示

不知道大家看完上边的例子有没有想过,一个数码管需要单片机一个IO口的7~8个引脚,那么两个、三个呢,如果这么算,一个单片机只能驱动四个数码管,除此之外什么也干不了,那你可就小看单片机了,接下来就介绍一下51单片机数码管的动态显示。

首先看一下Proteus中的数码管:

7b12dc93b569b6f33dd4b0c0e04be345.png

四个数码管的段选端口是连接在一起的(A~G,DP端口是小数点的显示);1、2、3、4是位选信号。如果我们将段选信号输入到端口,那么所有的数码管显示的数字是一样的,这不是我们想要的效果,所以就需要用到位选信号1~4,每次只让一个位选信号使能,其他三个就禁止。可是这样你会觉得,每次只有一个数码管显示啊,对的,每个时刻确实只有一个数码管显示,但是下一时刻我们就切换要显示的数字,然后换一个数码管显示,这样的效果就是看到四个数码管轮流显示,每次显示的数字不一样,还不是我们想要的效果。那如果我们将每个数码管切换的时间间隔缩小呢,比如,10ms,这个间隔肉眼是无法分辨出来的,这就是数码管动态显示的原理!我们直接上干活:

数码管动态显示Proteus仿真电路图:

fb5c718f564d13d59d2c539041ae1d99.png

然后是代码,有详细注释哦~

#include <reg51.h>
unsigned char num,num2=0;//num用于计数,刷新数码管,num2用于选择要显示的数字
unsigned char code display[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//数码
unsigned char com[]={0x01,0x02,0x04,0x08};//位选地址

void main()
{
	TMOD=0x01;//设置定时器0工作方式1
	TH0 = (65536-917)/256;		//1ms延时初值计算
	TL0 = (65536-917)%256;;		
	EA=1;//开总中断
	ET0=1;//定时器0中断
	TR0=1;//开始计时
	while(1){
		if(num==10){  //定时器中断10次,也就是10ms
			num=0;  //清零
			P1=~com[num2];//送入位选信号
		  P2=0xff;//消影
		  P2=display[num2];//送入段选信号
			num2++; //num2=0~3,四个数码管轮流显示。
			if(num2>=4)
			num2=0;
		}
	}
}

void Timer0() interrupt 1  //定时器中断
{
  TH0 = (65536-917)/256;	//重新赋值
TL0 = (65536-917)%256;;	
num++;//
}

然后就是一个使用点的例子,实现59s的计时,电路图和上边是一样的,直接上代码:

#include <reg51.h>
unsigned char code display[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned char com[]={0x01,0x02,0x04,0x08};

unsigned char num,num2=0,time[4];
unsigned int num3;

void main()
{
	TMOD=0x01;
	TH0 = (65536-917)/256;		
	TL0 = (65536-917)%256;;		
	EA=1;
	ET0=1;
	TR0=1;
	time[0]=0;
	time[1]=0;
	time[2]=0;
	time[3]=0;
	while(1){
		if(num==10){		
			num=0;
			P1=~com[num2];
		  P2=0xff;
		  P2=display[time[num2]];
			num2++;
			if(num2>=4)
			num2=0;	
		}
 
			if(num3==1000)//计数1000次,计时1s
			{
				time[3]++;//更新第四位
				if(time[3]>=10)
				{
					time[3]=0;
					time[2]++;//更新第三位
					if(time[2]>=6)
						time[2]=0;
				}
				num3=0;
			}
	}
}

void Timer0() interrupt 1
{
  TH0 = (65536-917)/256;		
	TL0 = (65536-917)%256;;	
	num++;
	num3++;
}

主要程序和上边是一样的,多了一部分计时1s的程序。

<think>好的,我现在需要帮助用户了解如何在51单片机实现数码管滚动显示学号。首先,我得回忆一下数码管的工作原理51单片机的相关知识。数码管通常分为阴极极,用户可能需要动态扫描来实现多个数码管的控制。而滚动显示的话,可能需要用到移或者定时器中断来控制显示的内容。 接下来,用户的需求是显示学号,通常是多数字,比如8。普通的静态显示只能固定显示,而滚动的话需要让数字依次移动,比如从右向左滚动。这时候可能需要用到缓冲区来存储当前显示的数据,然后定时更新缓冲区的内容,实现滚动的效果。 然后,我需要考虑硬件连接。51单片机的I/O口可能连接数码管选。选控制显示数字选控制哪个数码管亮。动态扫描的时候,需要快速切换选,利用人眼的视觉暂留效应,看起来所有数码管都在同时显示。 接下来是软件部分。主程序可能需要初始化定时器,设置中断服务函数来定时刷新数码管显示。同时,需要一个数组来存储学号的各个数字,比如学号20231234,拆分为2,0,2,3,1,2,3,4。然后,通过改变显示的起始置,每次中断时移动起始点,从而实现滚动效果。 可能需要注意的问题包括:定时器中断的时间间隔,太慢会导致闪烁,太快可能影响其他操作;数码管的消影处理,防止切换时的残影;滚动速度的控制,可能需要调整移动的步长时间间隔。 另外,代码部分需要用到数码管的编码表,即0-9对应的码,比如阴或的编码。比如,假设使用数码管,0的编码可能是0x3F,1是0x06,依此类推。在代码中,需要将学号的每一数字转换为对应的码,并按照当前显示置送到选口,同时选通对应的选。 滚动实现的关键在于如何更新显示的数据。比如,可以维护一个显示缓冲区,存储当前正在显示的几数字。每次中断时,将缓冲区的数据左移或右移一,并补充新的数字进来,或者循环。例如,学号8数码管显示4,那么缓冲区可以初始化为前4,然后每次左移一,后面的数字跟进,当滚动到末尾时,可能需要循环或者复。 可能还需要考虑边界情况,比如学号滚动完一遍后如何处理,是否循环滚动或者停止。此外,按键控制滚动开始或暂停,但用户可能暂时不需要这个,专注于基本功能。 总结步骤大概是:1. 确定硬件连接方式;2. 编写数码管显示函数,包括选的控制;3. 使用定时器中断定时刷新显示;4. 维护显示缓冲区,实现滚动逻辑;5. 处理消影延时问题。 现在,我需要把这些思路整理成用户容易理解的步骤,包括代码示例解释。同时要注意用户可能对动态扫描中断不熟悉,需要适当解释原理。代码部分要确保语法正确,并且符合51单片机的编程规范,比如使用Keil C的语法,端口定义等。</think>要实现51单片机数码管滚动显示学号,需结合动态扫描定时器中断技术。以下是具体步骤及代码示例: --- ### **一、硬件设计** 1. **数码管类型**:假设使用阴极4数码管。 2. **连接方式**: - **选(a-g, dp)**:连接单片机P0口。 - **选(4个)**:连接P2口的低4(P2.0-P2.3)。 3. **限流电阻**:选线路串联220Ω电阻。 --- ### **二、软件设计** #### **1. 定义编码表学号数组** ```c // 阴极数码管0-9编码(a-g对应P0.0-P0.6) unsigned char code segmentCode[] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F }; // 学号:20231234 → 拆分为[2,0,2,3,1,2,3,4] unsigned char studentID[] = {2,0,2,3,1,2,3,4}; ``` #### **2. 动态显示函数** ```c unsigned char displayBuffer[4]; // 显示缓冲区(存储当前显示的4数字) unsigned char position = 0; // 当前显示起始置(用于滚动) void display() { static unsigned char digit = 0; // 当前扫描的(0-3) P2 |= 0x0F; // 关闭所有选(消影) // 发送码 P0 = segmentCode[displayBuffer[digit]]; // 设置选 P2 = ~(0x01 << digit); digit = (digit + 1) % 4; // 循环扫描4 } ``` #### **3. 定时器中断初始化** ```c void timer_init() { TMOD = 0x01; // 定时器0,模式1 TH0 = 0xFC; // 1ms定时(假设晶振11.0592MHz) TL0 = 0x67; ET0 = 1; // 允许定时器0中断 EA = 1; // 开总中断 TR0 = 1; // 启动定时器 } void timer0_isr() interrupt 1 { TH0 = 0xFC; // 重装初值 TL0 = 0x67; display(); // 调用显示函数 } ``` #### **4. 滚动逻辑实现** ```c void updateBuffer() { static unsigned int counter = 0; if (++counter >= 200) { // 约200ms移动一次(调整counter值可改变速度) counter = 0; position = (position + 1) % 8; // 循环滚动学号数组 // 更新显示缓冲区 for (int i=0; i<4; i++) { displayBuffer[i] = studentID[(position + i) % 8]; } } } void main() { timer_init(); while(1) { updateBuffer(); // 持续更新缓冲区 } } ``` --- ### **三、关键点说明** 1. **动态扫描**:通过定时器中断每1ms刷新一数码管,4轮流显示。 2. **滚动原理**:每200ms更新一次`displayBuffer`,起始置`position`递增,实现学号左移效果。 3. **循环处理**:使用取模运算`%8`使学号循环滚动(如学号8显示4)。 --- ### **四、优化建议** - **消影处理**:在切换选前关闭所有数码管,避免残影。 - **速度调整**:修改`counter`阈值或定时器初值可调节滚动速度。 - **扩展功能**:添加按键控制滚动启停或方向。 通过以上代码,学号将在4数码管实现平滑的循环滚动显示
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值