实验2 基于51单片机的数码管显示系统设计

该实验旨在让学生掌握单片机接口显示技术,通过设计一个使用AT89C51单片机控制8只数码管滚动显示0-7的系统。实验涉及硬件电路设计,包括数码管的工作原理、单片机控制数码管的原理及电平转换,以及在Proteus和KeiluVision中的软件仿真。程序代码包括C语言和汇编语言实现。
摘要由CSDN通过智能技术生成

目录

一、实验项目

二、实验目的

三、实验器材

四、实验原理(含硬件电路图)

五、实验步骤

六、程序代码:

1.C语言代码

2.汇编语言代码


一、实验项目:数码管显示系统设计

二、实验目的

        本系统设计的目的是使学生掌握单片机的接口显示技术。深刻理解单片机片内主要硬件的功能和运行原理,掌握单片机软硬件系统开发的技巧。具体要求用单片机控制并排放着的8只数码管,使得数码管滚动显示数字0-7。要求在Proteus中设计出仿真硬件电路,在keiluvision中分别设计出汇编语言和C语言的源程序,然后用Proteus来进行整体系统仿真运行。

三、实验器材

        电脑,Keil uVision编译器Proteus电路仿真软件。

        实验模拟的各器件:AT89C51单片机、 CAP电容、 CAP-ELEC锁存器 CRYSTAL震荡器、 NPN三极管、RX8 、 RES电阻。

四、实验原理(含硬件电路图)

        1、数码管的显示原理:数码管一般由若干个发光二极管(LED)组成,每个LED有两个引脚,分别为阳极和阴极。共阳数码管的所有LED的阳极都相连,每个数字的LED的阴极都相连,共阴数码管则相反。

        2、为了让数码管显示数字,需要控制对应数字的LED点亮。以共阳数码管为例,当对应数字的LED的阳极接地,阴极接受正电压时,LED将会点亮。因此,为了让数码管显示数字,需要分别控制对应数字的LED的阳极接地,而阳极则需要接受正电压。

        3、单片机控制数码管的原理:单片机需要通过IO口控制数码管的显示。在控制数码管时,需要使用单片机的IO口输出高低电平,从而控制数码管的显示。单片机需要通过特定的端口来控制数码管的显示,这些端口通常被称为IO口,可以输出高电平或低电平。通过控制IO口输出高低电平,可以控制数码管的显示。

        4、为了让单片机控制数码管的显示,需要对数码管的控制线进行电平转换。由于数码管是共阳或共阴的,所以需要使用NPN三极管进行电平转换。在共阳数码管中,数码管的阳极接单片机的IO口,而数码管的阴极通过NPN三极管接地。在共阴数码管中,则相反。此外,为了防止NPN三极管被过流损坏,需要在三极管的基极与单片机的IO口之间加上限流电阻。

硬件电路图:

五、实验步骤

        1、在Proteus中设计出仿真硬件电路,将AT89C51单片机进行放置,同时将数码管的八根引脚线连接到总线P1上,NPN三极管应该通过引脚线,起到放大电压的作用,位选控制线连接到P0口上。

        2、在keil  uvision中分别编写汇编语言和C语言的源程序,用于控制单片机输出高低电平,从而实现数码管的滚动显示数字0-7。

        3、将编写好的程序下载到AT89C51单片机中,然后将单片机和仿真硬件电路连接起来,同时,将keil  uvision中编写好的文件烧录到单片机中,进行仿真实验的显示。

        4、在Proteus中进行整体系统仿真运行,观察数码管是否能够正确地滚动显示数字0-7,进行循环调试,达到实验的要求。

六、程序代码

1.C语言代码:

#include<reg51.h>    //包含51单片机的头文件,用于定义AT89C51单片机的寄存器和端口                         
#include<intrins.h>   //在这里引入头文件,主要是因为下面使用了_crol_循环左移的内部函数                                           
#define uchar unsigned char	 //定义两个无符号的字符型和整数型常量
#define uint unsigned int	 //uchar代表unsigned char,uint代表unsigned int
uchar code light[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};    //数码管的字符码0~7数字       
void delay(uint time)  //延时函数,循环嵌套t为延迟的时间,循环嵌套循环执行i的值,实现延迟                           
{
    uchar i;
    while(time--)
    for(i=0;i<200;i++);  			  
}
void main()
{
    uchar i,j=0x80;		//0x80用于将数码管进行初始化,80=1000 0000 ,第一个1对应高电平
    while(1)				//死循环
    {
         for(i=0;i<8;i++)
        {    
            j=_crol_(j,1);   //将二进制代码循环左移                               
            P0=light[i];     //将当前位数码管的字符码dis_code[i]赋值给P0口,控制数码管显示                              
            P2=j;            //将移位后的位置j赋值给P2口,控制数码管位置                                   
            delay(200);      //调用延时函数delay,延时一段时间,达到动态显示的效果                                
        }
    }
}

2.汇编语言代码:

ORG 	0000H	           ; 定义程序起始地址为0000H
		LJMP	MAIN	    ; 长转移指令,无条件跳转到主程序
DELAY:	MOV	R3,	#200	   ; 定义延迟函数DELAY,将计数器R3和R4的初始值设为200
D1:		MOV	R4,	#200	   
D2:		DJNZ 	R4, D2	   ; R4自减,当R4不为0时跳转到D2,用于延迟等待
		DJNZ 	R3, D1	   ; R3自减,当R3不为0时跳转到D1,用于延迟等待
		RET			       ; 延迟函数结束并返回,此处延时时间为(2*200+2+1)*200+2,大约为84ms
MAIN:	MOV	R0,	#01H	   ; 主程序开始,设置数码管首次显示的初始位置
		MOV	R1,	#00H	   ;设置数码管首次显示的数字
		MOV	R2,	#08H	   ;设置一次循环中的显示次数为8次
T2:		MOV	A,	R1		   ; 将R1的值移动到累加器A中
		MOV	DPTR,	#TAB    ; 将表TAB的地址加载到数据指针寄存器DPTR中
		MOVC	A,	@A+DPTR	  ;以DPTR为基址,A为偏移量来获取对应的数字编码
		MOV	P0,	A		     ; 将累加器A中的数据写入P0口输出
		MOV	P2,	R0			  ; 将寄存器R0中的数据写入P2口输出
		LCALL	DELAY	     ; 延迟一段时间
		INC	R1				 ; 将寄存器R1中的值自增1 ,为下一次显示下一个数做准备
		LCALL	DELAY		 ;多次引用了DELAY函数, 延迟一段时间
		MOV	A,	R0	; 将寄存器R0中的值移动到累加器A中,(无法对R0中数据直接操作)
		RL	A				 ; 将累加器A中的值循环左移一位,使得显示位置向右移动一位
		MOV	R0,	A			; 将累加器A中的值移动到寄存器R0中
		LCALL	DELAY	   ; 延迟一段时间
		DJNZ	R2,	T2	   ; R2自减,当R2不为0时跳转到L2,重复执行指定的代码块
TAB:	DB	0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8	  ; 定义一个包含8个字节的表,用于控制七段数码管的显示 ,此处为共阳极管,上述对应的数字为0到7
		END							 ; 程序结束

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Jerry独爱电子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值