C51入门之数码管

  • 如何静态点亮一个数码管

 •共阳数码管,阳极共用在一起,接VCC,阴极独立分别接IO控制脚

由于是共阳极性,所以数码管是低电平驱动点亮段画

 

点亮 0~9数码对应的段码,做成一个表格存入一个数组中。

code unsigned char disp_code[] = {0xC0,0xF9,0xA4,0xB0,0x99,  0x92,0x82,0xF8,0x80,0x90}; //0~9段码表

  如果要显示0,将P0口送0xc0也就是表中数组索引为0对应的值,则:

P0 = disp_code[0];   // 取出0对应的段码值给P0

现在来新建一个工程lesson3,实现点亮数码管,代码如下:

#include <reg52.h>
code unsigned char disp_code[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
void main(void)
{
  P0 = disp_code[0];   //点亮数字0
  for(;;)
  {
  }
}
  • 如何显示0~9的数字

  1.  让数码管每隔1秒显示数字,循环显示0~9
  2. 先实现1秒延时函数
  3. 使用硬延时空等待来实现达到延时的目的

   注意:实现产品软件开发中,不建议使用 硬延时,使用硬延时会降低产品的实时性

实现方法:

 1. 写一个函数,带一个形参,延时值由其传入函数

 2.函数体内由2for循环组成

 3.由分号语句实现空等待操作


#include <reg52.h>
code unsigned char disp_code[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};

void delayMills(unsigned int ms)
{
      unsigned int i,j;              //局部变量定义
      for(i=ms; i>0; i--)          //第一层for
          for(j=121; j>0; j--);        //第二层for
			//分号语句,空操作			
}

void main(void) 
{	
    unsigned char num = 0;
    for(;;) 
    {
	P0 = disp_code[num]; //通过num取出数组值
	if(++num > 9) num = 0;
	   delayMills(1000);	
    }
}
  • 如何显示8个数码管 

 

动态扫码原理

  1. 先锁存位,也就是要点亮的数码管
  2. 再锁存段码,在要点亮的数码管送入要显示的数值
  3. 延时一段时间,再继续锁存点亮下一位数码管,注意,扫描间隙延时,时间太长会闪烁,太短会造成重影
  4. 周而复始地扫码,利用人眼的惰性,这样看起来所有的数码管好像都同时点亮了

 

8个数码管为共阴,公共端接低电平,因此点亮段画需要高电平驱动 

 

  1. 点亮0~9数码对应的段码,做成一个表格存入一个数组中。

        code unsigned char disp_code[] = {0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f};//0~9段码表 

  2. 使用74HC573来锁存数据,先锁存数码管位,选择点亮哪个数码管,选择第1个数据码,数码管阴极要拉到低电平,

      那么P0.00,其余为1,则 P0 = 0xfe; 

  3. 再将P2.2脚拉高,将P0口的数据经过74HC573送到数码管的阴极,然后将P2.2脚拉低锁存数据 

  4.再锁存数码管段画,将要显示的段画值送入P0,将P2.3脚拉高,将P0口的数据经过74HC573送到数码管的段画引脚,

     然后将P2.3脚拉低锁存数据 

   5.延时一段时间,此时间太快会造成重影,太慢会造成闪烁 

新建一个工程lesson3_2,来实现数码管扫码功能

#include<reg52.h> //包含头文件
#define DataPort P0 //定义数据端口 sbit LATCH1=P2^2;//定义锁存使能端口 段锁存
sbit LATCH2=P2^3;//定义锁存使能端口    位锁存
unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//段码表  
unsigned char code dofly_WeiMa[]={ 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位码表
/*------------------------------------------------
 延时函数,含有输入参数 unsigned int t,无返回值
 unsigned int 是定义无符号整形变量,其值的范围是
 0~65535
------------------------------------------------*/
void Delay(unsigned int t)
{
  while(--t);
}

void main(void)
{
   unsigned char i=0;
   while(1)     
   {
       DataPort=dofly_WeiMa[i]; //取位码 
       LATCH2=1;     //位锁存
       LATCH2=0;
       DataPort=dofly_DuanMa[i]; //取显示数据,段码
       LATCH1=1;     //段锁存
       LATCH1=0;
       Delay(200); //扫描间隙,太长会闪烁,太短会造成重影
       if(++i==8) 
         i=0;  //检测8位扫描完全结束?
   }
}

数码管动态扫描消隐处理

  1. 在显示数据前,先将数码管断画关断显示,然后再显示正常的数值,消隐的目的是防止有交替重影出现

将上述例子代码,在显示数据前加入以下代码进行消隐处理

DataPort=0;   //清空数据,防止有交替重影      
LATCH1=1;     //段锁存   
LATCH1=0;
  • 让数字动态显示计数 

将上述例子修改一下,将位码表改成如下

                unsigned char code dofly_WeiMa[]={ 0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//位码表

增加一个无符号整型计数值 count ,约 1 秒加 1
count 值拆分放入要显示的数组中,定义一个数组长度为 8 ,因为有 8 个数码管,开 8 buffer 的数组就够用,即:

              unsigned char disp_buffer[8];

拆分数字      

              disp_buffer[0] = count%10;  //个位 

              disp_buffer[1] = count/10%10;  //十位

              disp_buffer[2] = count/100%10;  //百位

               disp_buffer[3] = count/1000%10;  //千位

                disp_buffer[4] = count/10000%10;  //万位

                disp_buffer[5] = count/100000%10;  //十万位

显示时取断码改成

   DataPort=dofly_DuanMa[disp_buffer[i]];

   LATCH1=1;     //段锁存

   LATCH1=0;

#include<reg52.h> //包含头文件
#define DataPort P0 //定义数据端口 
sbit LATCH1=P2^2;//定义锁存使能端口 段锁存
sbit LATCH2=P2^3;//定义锁存使能端口    位锁存
unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//段码表
  
unsigned char code dofly_WeiMa[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; //位码表

unsigned int count;
unsigned char disp_buffer[8];

void digitNum(void)
{
  disp_buffer[0] = count%10;  //个位
  disp_buffer[1] = count/10%10;  //十位
  disp_buffer[2] = count/100%10;  //百位
  disp_buffer[3] = count/1000%10;  //千位
  disp_buffer[4] = count/10000%10;  //万位
  disp_buffer[5] = count/100000%10;  //十万位
	
}

void incSecond(void)
{
   static unsigned int j=216;
   if(--j==0)
   {
      j=216;
	
      count++;
	
   }
}

/*------------------------------------------------
 延时函数,含有输入参数 unsigned int t,无返回值
 unsigned int 是定义无符号整形变量,其值的范围是
 0~65535
------------------------------------------------*/
void Delay(unsigned int t)
{
 while(--t);
}



void main(void)
{
	
	unsigned char  i = 0;
	
	for(;;)
	{
		digitNum();
		DataPort = 0;
		LATCH1 = 1;
		LATCH1 = 0;
		
		DataPort = dofly_WeiMa[i];
		LATCH2 = 1;
		LATCH2 = 0;
		
		 DataPort = dofly_DuanMa[disp_buffer[i]];
		if(i==5)
	  	DataPort |= 0x80;  // 1000 0000
		LATCH1 = 1;
		LATCH1 = 0;
		if(++i==8)
			i = 0;
		Delay(200);
		incSecond();
		
		
	}
}

 

 

 

 

 

 

 

 

 

 


      

 


 

 

 

 

 

 

 

 


 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

      

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

风雨依依

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

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

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

打赏作者

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

抵扣说明:

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

余额充值