小白自学c51笔记之数码管2

零基础小白自学到了动态数码管了👏
1.动态数码管原理:
先上个原理图:
在这里插入图片描述
数码管其实就是多个led组成的(小数点也是一个),如上图,一个8加上小数点就是一个数码管,一共八个led,上图是八个数码管。
数码管按接法不同可分为共阴极和共阳极数码管。字面意思,共阴极就一个数码管的八段led阴极连一起,共阳极就一个数码管的八段led阳极阳极连一起。
声明一下,我的数码管是共阴极的。
下面是两张静态数码管(我觉得动态数码管就是把下面两张图片里GND和VCC去掉而接到其他管口上):
共阴:
在这里插入图片描述
共阳:
右上角是5v,即VCC高压,图为静态数码管
右上角是5v,即VCC高电压
只要控制a~g,dp的电压就可以控制led亮暗。
而动态数码管不同,如第一张图有八个数码管,如果都像静态数码管一样则需8×8=64个管口控制,所以动态数码管利用动态扫描原理来达到不同数码管亮不同数字(或字母:A,b,C,d,E,F)的目的。
动态扫描,看字面意思,扫描,是一个数码管一个数码管亮的且每次只亮一个,但因为人眼有视觉暂留,所以只要通过适当延时使亮的那段时间足够短以至于下一个数码管亮时上个数码管在我们眼中还是亮的就可以达到我们的目的——它们一起亮。
这样我们就可以用八个管口控制哪个数码管亮,用八个管口控制该数码管亮哪几段led,总共用了16个大大减少所需管口数。再加上38译码器,3通道输入,8通道输出,只需3+8=11个管口便可控制八个数码管。
这里有两个概念,段选和位选。
位选:“位”,顾名思义,选择哪个位置的数码管亮。
段选:“段”,选择已被选中的数码管哪几“段”led亮。
看开头给出的原理图,可知P0八个口控制段选(具体哪个口控制哪段led从图中很容易就可以看出来),先通过D74HC245是为了增加驱动,单片机电流不够数码管会很暗(有人说共阴极的电流才会不够,共阳极就可以直接驱动,我不太懂,待查)。要想知道位选由单片机哪个口控制还有一张图:在这里插入图片描述
由之前已知的此芯片功能,我们可以通过控制P2^2,P2^3,P2^4口输入值来控制Y0(上横线)~Y7(上横线)哪个输出低电压,输出低电压的那个口连接的数码管就算被选中了。
想让该数码管发光,接下来段选那边肯定要输高电压了,由此确定P0口的值。

2.动态数码管编程:

#include<reg52.h>
sbit  LSA=P2^2;
sbit  LSB=P2^3;
sbit  LSC=P2^4;
unsigned int code smgduan[16]={	0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};  //共阴极数码管表,分别对应让数码管显示0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F;这是c语言中数组定义和初始化

void delay(unsigned int i)						   //自定义函数delay
{	
    while(i--);
}
void bigdisplay()								    //自定义函数bigdisplay
{	
 	unsigned int i;
	for(i=0;i<8;i++)							    //c语言中for语句
	{
	 switch(i)									    //c语言中switch语句	,此处为了处理亮第几个数码管问题——位选
	  {
	   case 0:LSA=0,LSB=0,LSC=0;break;			    //i的值与哪个case后相同就执行哪条语句,再由真值表知38译码器输出状态,最后知亮第几个数码管 (编程时思维方向与此相反)
	   case 1:LSA=1,LSB=0,LSC=0;break;
	   case 2:LSA=0,LSB=1,LSC=0;break;
	   case 3:LSA=1,LSB=1,LSC=0;break;
	   case 4:LSA=0,LSB=0,LSC=1;break;
	   case 5:LSA=1,LSB=0,LSC=1;break;
	   case 6:LSA=0,LSB=1,LSC=1;break;
	   case 7:LSA=1,LSB=1,LSC=1;break;
	  }
	  P0=smgduan[i];							    //给P0赋值,值为上面smgduan数组中第i个数,注意:从0开始算;c语言中数组用法;若将这一条语句中i换成i+8最终效果图在下面。
	  delay(100);								    //调用函数delay来延时,延时不能太短也不能太久
	  P0=0x00;									    //P0全归零,不然亮第二个数码管时会有干扰,产生重影
	 }
}

void main()										    //主函数
{
 	while(1)								    	// 1一直符合循环条件,一直循环{}内语句
	{
	 bigdisplay();									//调用上面编好的函数bigdisplay,如果不自定义函数bigdisplay,也可直接在主函数main中写程序
	}
}

效果:
1.原来的代码:
在这里插入图片描述
2.将上面代码中指定的i换掉之后:记得从右往左看😂


小白心情记——终于记完了,原来这就是爆肝的感觉,😭我流下了幸福的泪水。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值