4.自制单片机之四----数码管电路的制做与驱动_边学边秀单片机_百度空间

数码管的使用方法与发光二极管没什么区别,只是把七或八只发光二极管组合在一个模件上组成了个8字和小数点,用以显示数字。为了减少管脚,把各个发光管的其中同一个极接在一起作为共用点,因此就产生了共阳极和共阴极数码之说。共阳管就是把各个发光管的正极接在一起,而共阴管就刚好相反。见下图:

先不接上图的R2和74HC244,将数码管一个段直接接地。调节R1,测得S9012基极电流为0.21mA时集电极也就是数码管上已有40mA,说明放大倍数足够了。这时接上R2和74HC244,调节R2使数码管电流控制在15mA,这样当8个段一起点亮时三极管上得通过120mA的电流。而基极上需要0.63mA,为了减小三极管的负荷应使三极管过饱和,,调节R1使基极电流为2mA,此时测得集电极和漏极之间的电压约0.1V。好!此时R1为2K。R2为240欧姆。确定。
然后就是写程序。先写个查询方式的吧!
//六位管码管在以0.3秒的间隔在闪烁,这是采用查询方式的,比较占CUP资源
/********************************************************************
定义管脚:P2_0-------上横 a               P3_0-------个位
                  P2_1-----右上竖 b               P3_1-------十位
                  P2_2-----右下竖 c               P3_2-------百位
                  P2_3-----      下横 d             P3_3-------千位
                  P2_4-----左下竖 e               P3_4-------万位
                  P2_5-----左上竖 f                P3_5-------十万位
                  P2_6-----中间横 g
                  P2_7-----小数点 H
*********************************************************************/
# include <AT89X51.h>
typedef unsigned char uchar;
uchar code bit_num[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//位码值表:0,1,2,3,4,5
uchar code meg_val[]={0x03,0x9f,0x25,0x0d,0x99,0x49};//段码值表:0,1,2,3,4,5
uchar code hello[]={0x03,0xe3,0xe3,0x61,0x91,0xff};      //HELLO
uchar code beybey[]={0x89,0x61,0xc1,0x89,0x61,0xc1};//beybey
uchar code ab6789[]={0xc1,0x11,0x09,0x01,0x1f,0x41};//ab6789
void delay(int n);
void main(void)
{
       uchar i,m;
       P2=0xff;      //先将段码关闭
       P3=0xff;      //将位码关闭
       delay(20);//等待一会
       while(1)
        {
          for (m=30;m>0;m--)      //显示30次约0.3秒
{
        for(i=0;i<=5;i++)
               {
                P2=0xff;
                P3=bit_num[i];      //输出位码到P3口
                P2=ab6789[i];      //输出段码到P2口
                delay(5);
        }
      }
          P2=0xff;         //关闭段码
          P3=0xff;         //关闭位码
          delay(1000);      //等待0.3秒
         }
}
void delay(int n)      //子程序
{
       int j;
       uchar k;
       for(j=0;j<n;j++)
        {
          for(k=255;k>0;k--);
        }
}
======================================
当我插把程序写入片子,插上电运行时,是乱码。你猜怎么回事?
原来那个P2口方向是反的,您注意过没有,在AT89S51管脚排列上,P0--P1和P3都是上方为PX_0。而唯独P2口管脚排列是下方为P2_0。方向则好是反的。既然反了,我就把段码表重写一下。再试,一切正常。
在这里我说一下段码的排列,好多人问数码管段码是如何排列的,我也在网上查了,好像没有什么标准的排法,随自己的接法而定,这也是导致为什么在网上下载的一些数码管程序在自己的板子上不能正常显示的原因。就普遍而言我最上面的那张图示的标法最多,在上面程序里原打算也是P2_0对应段码a(也就是上面的横)。一直到P2_7对应段为h(就是小数点)。结果哪知道P2口刚好是反的。这样一来也就是倒过来了,P2_0对应段h(小数点了)。例如我原先定义的数码管显示“2”段码为10100100B的,一接反了就不再是“2”了。而要想再显示“2”那就把段码的高低位倒过来。改为00100101B就OK了。
//这是采用中断方式的,也是带闪烁的。
/********************************************************************
定义管脚:P2_0------小数点        P3_0------个位  
                  P2_1------中横            P3_1------十位
                  P2_2------左上竖        P3_2------百位
                  P2_3------左下竖        P3_3------千位
                  P2_4------下横           P3_4------万位
                  P2_5------右下竖        P3_5------十万位
                  P2_6------右上竖
                  P2_7------上横
*********************************************************************/
# include <AT89X51.h>
typedef unsigned char uchar;
uchar code bit_num[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//位码:0,1,2,3,4,5
uchar code meg_val[]={0x49,0x99,0x0d,0x25,0x9f,0x03};//段码:0,1,2,3,4,5
uchar i,aa; //定义全局变量
bit fg;        //定义一个亮起和熄灭标志
void timer0(void) interrupt 1 using 1      //中断程序
{
      if (fg)        //当fg为1时点亮6位数码管
       {      P2=0xff;
         if (i>=6)
           {
             i=0;
            }
         else
           {
             P3=bit_num[i];      //输出位码到P3口
             P2=meg_val[i];      //输出段码到P2口
             i++;
            }
       }
      else                 //当fg为0时熄灭数码管
        {
           if(aa==0)
         {
           P3=0xff;
           P2=0xff;
                }
         }
       aa++;
       if (aa>=254) //当aa值累加至254时fg标志翻转。
         {
           fg=~fg;
           aa=0;
}
       TH0=0xf8; //重装定时器初值,2ms,值为65536-2000
       TL0=0x30;
}

void main(void)
{
       P2=0xff;      //先将段码关闭
       P3=0xff;      //将位码关闭
       TMOD=0x01;//设置T0为模式1
       TH0=0xf8; //装入计数初值高位
       TL0=0x30; //装入计数初值低位
       EA=1;      //总充许
       ET0=1; //T0充许
       fg=1;       //将亮、灭标志设置为亮
       TR0=1;      //启动中断
       while(1);
}

36 2009-04-22 18:46 |
版主回复的好快哈!支持一下!
程序我仔细看过了,通过两个for循环让数码管由低到高依次点亮,再让这个过程执行30次,不知道正确不!
上面的那个程序我还有点不懂,比如
uchar code ab6789[]={0xc1,0x11,0x09,0x01,0x1f,0x41};//ab6789
语句我就对不上号,数组中的十六进制数是怎样对应的啊?当i=0的时候,按理说是个位数码管亮,但数字怎么会是0呢?按你的段码定义,应该是0x3F才对啊?不知讲清楚没有哈!敬请指教!
37 2009-04-23 19:17 |
回复learning keyin:
  上面的程序里定义的几个数组:
uchar code meg_val[]={0x03,0x9f,0x25,0x0d,0x99,0x49};//段码值表:0,1,2,3,4,5
uchar code hello[]={0x03,0xe3,0xe3,0x61,0x91,0xff};      //HELLO
uchar code beybey[]={0x89,0x61,0xc1,0x89,0x61,0xc1};//beybey
uchar code ab6789[]={0xc1,0x11,0x09,0x01,0x1f,0x41};//ab6789
都是段码表。只有uchar code bit_num[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//位码值表:0,1,2,3,4,5
是位码表。
你说当i=0时,位码是bit_num[i]=0xFE,就是个位上是0呀!就是个位上为低电平。其它位都是高电平。

郑重声明:资讯 【4.自制单片机之四----数码管电路的制做与驱动_边学边秀单片机_百度空间】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——