51单片机静态数码管和动态数码管原理及实验

数码管实验
  • 数码管
    多位数码管,即是两个或两个以上单个数码管并列集中在一起形成一体的数码管。当多位一体时,它们内部的公共端是独立的,而负责显示什么数字的段线全部是连接在一起的,独立的公共端可以控制多位一体中的哪一位数码管点亮,而连接在一起的段线可以控制这个能点亮数码管亮什么数字,通常我们把公共端叫做“位选线”,连接在一起的段线叫做“段选线”有了这两个线后,通过单片机及外部驱动电路就可以控制任意的数码管显示。一般一位数码管有10个引脚,二位数码管也是10个引脚,四位数码管是12个引脚。
    为了更方便区分段选和位选,请看下原理图:
    在这里插入图片描述
    如图为两个4位一体的数码管,可以看到与8个com相连的是两个数码管的位选,位选与引脚相连,所以位选控制那个灯亮。段选可以看到a,b,g并联到一起。因为是并联,所以点亮的数码管显示的数字相同。
  • 共阴极数码管和共阳极数码管
    在这里插入图片描述

图a数码管管脚图,图b是共阳极数码管,图c是共阴极数码管。
由图b可知共阳极数码管阳极连接在一起,接高电平,阴极对应的各段分别控制。比如要想显示1,则阴极对应的bc段低电平,其它接高电平,即可显示。
由图C可知,共阴极数码管将各个二极管的阴极连接在一起(阴极为低电平),而阳极控制各段,比如要显示1,则bc为高电平,其它各段低电平即可显示。

共阳极和共阴极数码管对照表
共阳极数码管对照表(位选位高电平,各段选低电平控制数字显示)

uchar code table[]={
	0xc0,//0
	0xf9,//1
	0xa4,//2
	0xb0,//3
	0x99,//4
	0x92,//5
	0x82,//6
	0xf8,//7
	0x80,//8
	0x90,//9
	0x88,//A
	0x83,//B
	0xc6,//C
	0xa1,//D
	0x86,//E
	0x8e, //F
	0x8c, //P
	0xc1,//U
	0x91,//Y
	0x7c,//L
	0x00,//全亮
	0xff  //熄灭
};

共阴极数码管对照表(位选为低电平,段选为高电平)

uchar code leddata[]={
	0x3F,  //"0"
    0x06,  //"1"
    0x5B,  //"2"
    0x4F,  //"3"
    0x66,  //"4"
    0x6D,  //"5"
    0x7D,  //"6"
    0x07,  //"7"
    0x7F,  //"8"
    0x6F,  //"9"
    0x77,  //"A"
    0x7C,  //"B"
    0x39,  //"C"
    0x5E,  //"D"
    0x79,  //"E"
    0x71,  //"F"
    0x76,  //"H"
    0x38,  //"L"
    0x37,  //"n"
    0x3E,  //"u"
    0x73,  //"P"
    0x5C,  //"o"
    0x40,  //"-"
    0x00  //熄灭
	};

  • 数码管显示原理
    1.静态显示
    多位数码管依然可以静态显示,但是显示时要么只显示一位数码管,否则一体的多位同时显示必须时显示相同内容。当多位数码管应用于某一系统时,它们的“位选”是可独立控制的,而“段选”是连接在一起的,我们可以通过位选信号控制哪几个数码管亮,而在同一时刻,位选选通的所有数码管上显示的数字始终都是一样的,因为它们的段选是连接在一起的,所以送入所有数码管的段选的信号都是相同的,那么他们显示的数字必定一样。(换言之,你可以通过位选控制那个数码管亮,但是亮的同时显示的数字必定相同)
    2.动态显示
    位选控制亮不亮,而段选控制显示数字,那怎样显示不同的数字呢?这就利用了人体肉眼观察的能力。
    举个例子,假设段选1控制第一位数码管数字显示1,那么在显示第二个数码管是段选控制数码管显示2,而位选控制灯第二位数码管亮,第一位数码管灭。但是给人的感受是第一位数码管并没有灭(实际已经灭了),因为时间太短人体肉眼无法识别。这样就会发现数码管动态显示是向左或向右一位一位点亮。
  • 静态数码管工作原理
    静态数码管原理图:
    在这里插入图片描述
    因为共阳极数码管,所以位选接的是高电平,要想正常显示通过控制低电平来控制段选即可。
  • 静态数码管代码实现:
#include <reg52.h>
#include <intrins.h>
typedef unsigned char u8; //重定义全局字符型变量
typedef unsigned int u16; //重定义全局整型变量
u8 code table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
/*利用数组引用数码表(注次数码表为阴极数码表,因为是共阳极数码管,本应使用刚阳极数码管,
为了方便直接将共阴极数码表取反来使用)。code是将数组从ram调到ROM节省空间*/

/*延时函数*/
void dealy(u16 i)
{
while(i--);
}

void main()
{ int i=0;
  for(i=0;i<9;i++){
  P0=~table[i];//取反是因为使用的是阴极数码表,而取反得阳极数码表
  dealy(50000);
  }	
  //p0=~table[0];  该写法是固定显示数字不变的写法,~table[0]显示的就为0
	 
}
  • 动态数码管工作原理
    在这里插入图片描述在这里插入图片描述
    如图,位选的控制通过连接J16的管脚连接138译码器,利用138译码器控制位选。段选不是有单片机IO直接驱动,而是通过连接74HC25芯片连接管脚,利用芯片来实现段选。
    因为是共阴极数码管,所以位选应接低电平,段选接高电平时,数码管正常显示。

译码器工作原理
在这里插入图片描述在这里插入图片描述在这里插入图片描述
可以有真值表观察,当使能控制都为低电平的情况下,A0A1A2输入不同电平控制输出。
例,A0A1A2为000(二进制为0)对应Y0就输出低电平,为001(二进制为1)输出Y1就位高电平。所以就相当于二进制十进制,十进制对应输出。

74HC25看自己的原理图即可,不再阐述。

  • 动态数码管代码实现
#include <reg52.h>
#include <intrins.h>
typedef unsigned char u8; //重定义全局字符型变量
typedef unsigned int u16; //重定义全局整型变量

u8 code table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
/*利用数组引用数码表(该数码管是共阴极数码管,所以使用共阴极数码表)。code是将数组从ram调到ROM节省空间*/

sbit LSA=P2^2;    //ABC分别连接单片机的P2^2,P2^3,P2^4管脚
sbit LSB=P2^3;
sbit LSC=P2^4;

/*延时函数*/
void dealy(u16 i)
{
while(i--);
}

/*动态显示函数
*参数说明
*ABC分别为138译码器的输入端,通过控制输入端来控制输出端的高低电平,从而实现对位选的控制
且A为二进制中的低位,C为高位*/
void Display()
{  u16 i=0;
for(i=0;i<8;i++)
{
 switch(i)
 {
 case 0:LSA=0;LSB=0;LSC=0;break; //利用138译码器来控制位选,当ABC都等于0时,y0为低电平,其余为高电平
 case 1:LSA=1;LSB=0;LSC=0;break; //Y1输出低电平
 case 2:LSA=0;LSB=1;LSC=0;break; //Y2输出低电平
 case 3:LSA=1;LSB=1;LSC=0;break; //Y3输出低电平
 case 4:LSA=0;LSB=0;LSC=1;break; //Y4输出低电平
 case 5:LSA=1;LSB=0;LSC=1;break; //Y5输出低电平
 case 6:LSA=0;LSB=1;LSC=1;break; //Y6输出低电平
 case 7:LSA=1;LSB=1;LSC=1;break; //Y7输出低电平
 }
 P0=table[i];  //第i个为低电平决定位选则跳出switch循环,P0提供段选(原理图可以看出)
 dealy(100);  // 短暂的延时,达到肉眼看不到的速度,以达到同时显示效果
 P0=0x00;     //清零,作用为了下一个显示不会产生重影
}
}

void main()
{ 
  while(1)
  {
  Display();
  }	 
}
  • 10
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面为您提供一个51单片机静态数码管计算器的实例代码: ``` #include<reg52.h> #define uchar unsigned char sbit dula=P2^6; sbit wela=P2^7; uchar code table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数码管显示0~9,A~F uchar num1,num2,result;//记录输入的数值和结果 uchar flag=0;//标志位,用于选择运算符 void delay(uchar z)//延时函数 { uchar x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void display(uchar num)//数码管显示函数 { P0 = table[num]; } void keyscan()//按键扫描函数 { uchar keyvalue = P1; keyvalue &= 0x0f; if(keyvalue != 0x0f) { delay(10); keyvalue = P1; keyvalue &= 0x0f; if(keyvalue != 0x0f) { switch(keyvalue) { case 0x0e: num1=1; display(num1); break;//1键 case 0x0d: num1=2; display(num1); break;//2键 case 0x0b: num1=3; display(num1); break;//3键 case 0x07: num1=4; display(num1); break;//4键 case 0x0e: num1=5; display(num1); break;//5键 case 0x0d: num1=6; display(num1); break;//6键 case 0x0b: num1=7; display(num1); break;//7键 case 0x07: num1=8; display(num1); break;//8键 case 0x0e: num1=9; display(num1); break;//9键 case 0x0d: num1=0; display(num1); break;//0键 case 0x0b: flag=1; break;//加法键 case 0x07: flag=2; break;//减法键 case 0x0e: flag=3; break;//乘法键 case 0x0d: flag=4; break;//除法键 case 0x0b: flag=5; break;//等于键 case 0x07: num1=0; num2=0; result=0; display(num1); break;//清零键 } } } } void main() { while(1) { keyscan(); if(flag != 0) { keyscan(); num2 = num1; num1 = 0; display(num1); switch(flag) { case 1: result = num1 + num2; break;//加法运算 case 2: result = num1 - num2; break;//减法运算 case 3: result = num1 * num2; break;//乘法运算 case 4: result = num1 / num2; break;//除法运算 } display(result); flag = 0; } } } ``` 这是一个简单的静态数码管计算器,通过按键输入数字和运算符,然后在数码管上显示结果。代码中使用了延时函数、数码管显示函数和按键扫描函数等。需要注意的是,这个程序中只能进行加减乘除四则运算,如果需要扩展其他运算,可以自行添加代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值