您当前的位置: 首页 > 

仙剑情缘

暂无认证

  • 8浏览

    0关注

    333博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

C51入门之数码管

仙剑情缘 发布时间:2019-11-11 07:22:30 ,浏览量:8

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

 •共阳数码管,阳极共用在一起,接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 
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.函数体内由2级for循环组成

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


#include 
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.0为0,其余为1,则 P0 = 0xfe; 

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

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

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

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

新建一个工程lesson3_2,来实现数码管扫码功能
#include //包含头文件
#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 //包含头文件
#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();
		
		
	}
}

 

 

 

 

 

 

 

 

 

 

      

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

      

 

 

 

 

 

 

 

 

 

 

 

 

 

 

关注
打赏
1658017818
查看更多评论
立即登录/注册

微信扫码登录

0.0391s