加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

LY-51S(STC89C52R):8个共阴极数码管-程序(1)

(2012-09-12 16:17:33)
标签:

51单片机

it

分类: LY-51S单片机学习笔记
    8位数码管的程序浪费了我一些时间,但是多思考不会有什么坏处,所以这部分我写的程序相对较多点儿,有些虽然看起来很相似,但为了加深理解我还是一个个的写出来,就连通用的函数头,显示函数和延时函数我也都一一写出来了。这些程序都是我亲手测试过的,不排出在调整排版时导致错误可能。
    8个数码管为共阴极接法,与单片机P0口连接,段锁存位接P2^2,位锁存位接P2^3。

18个共阴极数码管流水灯式的分别显示09

#include

sbit LATCH1=P2^2;     //声明段锁存口

sbit LATCH2=P2^3;     //声明位锁存口

#define uint unsigned int

#define uchar unsigned char

#define MAXDM 10      //宏定义一个段码最大个数

#define MAXWM 8       //宏定义位码最大个数

unsigned char code DM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //09的段码值

unsigned char code WM[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};           //18数码管的位码值

void delay(uint );    //声明自定义函数

void main(void)

{

    uchar i,j;        

    while(1)                    //while()主循环体,当双重for()循环结束后可直接从这里开始,不必再从main()函数开始

         {

             for(i=0;i位码循环主体

             {

                      P0=WM[i];

                       LATCH2=1;            //打开位码锁存端

                       LATCH2=0;            //关闭位码锁存端

                       for(j=0;j嵌套在位码循环主体中的段码循环显示09

                      {

                               P0=DM[j];         

                                LATCH1=1;         //打开段码锁存端

                                LATCH1=0;

                                delay(500);       //关闭段码锁存端

                       }

             }

    }

} 

void delay(uint time)              //自定义延迟函数的定义

{

    unsigned int i,j;

    for(i=time;i>0;i--)

           for(j=110;j>0;j--)                  

}

2:用函数_crol_()实现8个共阴极数码管流水显示数字8 

注意:1、在LY-51S单片机中,数码管的电源是独立的,所以在实时应将J50用跳帽短接,以便连接到电源;

      2、单片机上的P2.2接数码管的段锁存器的锁存控制端,P2.3接数码管的位锁存器的锁存控制端,即分别和板子上的J2BJ2A相连接.

#include

#include

#define uint unsigned int

#define uchar unsigned char

sbit LATCH1=P2^2;    //声明段锁存口(J2B口相连)

sbit LATCH2=P2^3;    //声明位锁存口(J2A口相连)

void delay(uint time); 

void main(void)

{

   unsigned char ch=0xfe;

    while(1)

   {

        LATCH2=1;   //打开为锁存

        P0=ch;      //选择第一个数码管显示(由于数码管为共阴极,所以位选低电平时选通)

        LATCH2=0;

        LATCH1=1;   //打开段锁存

        P0=0x7f;    //第一个数码管显示8

        LATCH1=0;

        delay(1000);      //延时越1s

        ch=_crol_(ch,1);  //段码循环左移,即让第其他数码管按顺序显示数字8

    }

}

void delay(uint time)     //自定义函数定义

{

    unsigned int i,j;

    for(i=time;i>0;i--)

           for(j=110;j>0;j--)                      

}

3:8位数码管动态扫描(现象上为固定显示1-8)

注意:每个数码管都需要8位二进制数才能控制,所以8个数码管原理上应该属于并联连接方式,即同一时刻如果选定位码,那么所选定的数码管上显示的数字都是段码所标识的那一个.要想每个数码管显示的数字看起来不一样则必须用到动态扫描.(数码管的连接方式不同LED,因为LEDP1每个口连接一个LED,所以可以单独的进行赋值,

P1^0=1,但是在8位数码管中不能单独对某个口赋值,因为控制一个数码管上的LED便需要8个二进制数据).

#include

sbit LATCH1=P2^2;     //声明段锁存口

sbit LATCH2=P2^3;     //声明位锁存口

#define MAX 8         //段码或位码最大个数

unsigned char code DM[]={0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f}; //18的段码值

unsigned char code WM[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //18数码管的位码值

void delay(unsigned int time);  //自定义延时函数

void main(void)

{

    while(1)

    {

        unsigned char i;

        for(i=0;i

        {

             LATCH2=1;      //锁存位码,即选择了数码管

             P0=WM[i];

             LATCH2=0;

            

             LATCH1=1;      //锁存段码,即对已选择的数码管显示数字

             P0=DM[i];

             LATCH1=0;

                             delay(100);    //动态扫描,时间长会闪烁,时间短会重影

          }

       }

}

void delay(unsigned int time)

{

    while(time--);

} 

4:数码管动态循环显示0-9 

注意:以动态扫描的方式让数码管上显示出静态数字,让后通过while()循环,让这个静态扫描的过程循环50(只有这样才能让静态数据停留一段时间后变为下一组数据.起初我是在for()后加了一个delay(N),让时间延长,但这样并不会让静态数据全部显示,只会让最后一个数码管的数据停留delay(N)的时间),只有让整个动态扫描过程循环,其结果才能显示在数码管上(这里指的是while()循环,main()循环).因此,程序中的ct记录的是while()循环的次数. 

#include

sbit LATCH1=P2^2;     //声明段锁存口

sbit LATCH2=P2^3;     //声明位锁存口

#define MAXDM 10      //段码最大个数

#define MAXWM 8       //位码最大个数

unsigned char code DM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //09的段码值

unsigned char code WM[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};           //18数码管的位码值

void delay(unsigned int time);  //自定义延时函数

void main(void)

{

    unsigned char i,j,num=0,ct=0;

    while(1)

    {

        for(i=0,j=num;i

        {

             LATCH2=1;      //锁存位码,即选择了数码管

             P0=WM[i];

             LATCH2=0;

            

             LATCH1=1;      //锁存段码,即对已选择的数码管显示选定的数字

             P0=DM[j++];

             LATCH1=0;

             delay(3);     //动态扫描,时间长会闪烁,时间短会重影

             if(j==MAXDM)  //循环过程中若数码管显示为9则接着从0开始

                   j=0;

                           //如果直接在for()后加延时,那只会显示最后一个数码管的数字

         ct++;      //定义一个记数量ct,整个while()循环一次ct增加1

         if(ct==50)  //while()循环达到50次时,ct0,重新开始记数

          {

                 ct=0;

                 num++;         //num1,下一次开始时,数码管显示的数字加1

                 if(num==MAXDM)//如果数码管显示为9,则下次让其又从1开始

                       num=0;

            }

      }        

}

void delay(unsigned int time)

{

    unsigned int i,j;

    for(i=time;i>0;i--)

           for(j=110;j>0;j--)                       

}

5:3个数码管交替显示1-9 

#include

sbit LATCH1=P2^2;     //声明段锁存口

sbit LATCH2=P2^3;     //声明位锁存口

#define MAXDM 9       //段码最大个数

#define SMNUM 3       //交替显示数字的数码管的个数

unsigned char code DM[]={0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //19的段码值

unsigned char code WM[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};      //18数码管的位码值

unsigned char temp[MAXDM];

void delay(unsigned int time);

void main(void)

{

    unsigned int i;

    while(1)

    {

             for(i=0;i1开始为了避免循环一次后下一次0%39%3在同一个数码管上显示

             {

                       LATCH2=1;

                       P0=WM[i%SMNUM];   //让位码索引重复0-2

                        LATCH2=0;

                        LATCH1=1;         //让段码重复1-9

                        P0=DM[i];       

                        LATCH1=0;

                       delay(500);       //延时,便于观察现象

              }

       

} 

void delay(unsigned int time)

{

     unsigned int i,j;

     for(i=time;i>0;i--)

           for(j=110;j>0;j--)                      

}

6:8个数码管中的一个循环累加9

#include

sbit LATCH1=P2^2;     //声明段锁存口

sbit LATCH2=P2^3;     //声明位锁存口

#define MAXDM 10      //段码最大个数

unsigned char code DM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //09的段码值

void delay(unsigned int time);

void main(void)

{

    unsigned char i;

    LATCH2=1;                  //锁存第一个数码管

    P0=0xfe;

    LATCH2=0;    

    while(1)

    {

          for(i=0;i第一个数码管循环显示0-9

          {

                 LATCH1=1;  

                 P0=DM[i];

                 LATCH1=0;

                 delay(500);       //每个数字之间的间隔时间

           }

     }

}

void delay(unsigned int time)

{

    unsigned int i,j;

    for(i=time;i>0;i--)

           for(j=110;j>0;j--)                      

} 

看了别人关于显示函数的写法后修改如下: 

#include

sbit LATCH1=P2^2;     //声明段锁存口

sbit LATCH2=P2^3;     //声明位锁存口

#define MAXDM 10      //段码最大个数

#define MAXWM 8       //位码最大个数

#define uint unsigned int   //宏定义

#define uchar unsigned char //宏定义

uchar code DM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //09的段码值

uchar code WM[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};           //18数码管的位码值

void delay(uint );            //自定义延时函数声明

void display(uchar ,uchar );  //自定义显示函数声明,第一个参数为要开始数码管位,若为0则第一个数码管显示;第二个为累加的数字位数

uchar temp[MAXDM];            //临时数组声明

void main(void)

{

         uint num=0,ct=0;

         while(1)

         {

             ct++;

             if(ct==100)        //让显示在数码管上的数字固定一段时间

             {

                    ct=0;         

                    num++;         //固定时间到后,将显示下一个数字

                    if(num==10)    //因为是9的累加,所以不能超过10

                         num=0;

              }

              temp[0]=DM[num];//将要显示的数字和段码索引巧妙联系在一起

              display(0,1);

         }

} 

void display(uchar site,uchar digit)

{

    uchar dex;

    for(dex=0;dex

    {

           LATCH1=1;          //清除数字变化对未点亮数码管产生交替重影

           P0=0;

           LATCH1=0;

           LATCH2=1;          //锁存要显示的位码

           P0=WM[dex+site];

           LATCH2=0;

           LATCH1=1;          //锁存要显示的段码

           P0=temp[dex];

           LATCH1=0;

           delay(3);          //延时一小段时间,太长数字会闪烁,太短会重影

     }

} 

void delay(uint time)

{

    uint i,j;

    for(i=time;i>0;i--)

           for(j=110;j>0;j--)

                       ;

}

7:99累加前的牺牲品

现象,显示0-99,但是只有各位进一时十位才会显示一下

#include

sbit LATCH1=P2^2;     //声明段锁存口

sbit LATCH2=P2^3;     //声明位锁存口

#define MAXDM 10      //段码最大个数

#define MAXWM 8       //位码最大个数

#define uint unsigned int   //宏定义

#define uchar unsigned char //宏定义

uchar code DM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //09的段码值

uchar code WM[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};           //18数码管的位码值

void delay(unsigned int time);  //自定义延时函数声明

void main(void)

{

    unsigned int i,j,ct=0;

    while(1)

    {

          for(i=0;i

          {

                 LATCH2=1;

                 P0=0x7f;

                 LATCH2=0;

                 LATCH1=1;

                 P0=DM[i];

                 LATCH1=0;

                 delay(1000); 

                 if(i==MAXDM-1)

                 {

                      j++;

                      LATCH2=1;

                      P0=0xbf;

                      LATCH2=0;

 

                      LATCH1=1;

                      P0=DM[j];

                      LATCH1=0;

                      delay(500);

                 }

          }

          ct++;

          if(ct==50)

          {

                  ct=0;

                  j++;

                  if(j==MAXDM)

                       j=0;

           }

    }

}

void delay(unsigned int time)

{

    unsigned int i,j;

    for(i=time;i>0;i--)

          for(j=110;j>0;j--)                     

}

8:数码管99累加

原理:利用动态扫描,让十位的段码索引在个位的十次循环中一直维持为一个数,如个位从0-9变化过程中其段码索引也从0-9,但是这个过程中十位的段码索引却只为一个数,最开始为0,逐渐递增,个位从0-9循环一次,十位的索引增加一.注意:起初我在显示函数中没有添加清除数据的语句,导致其他未显示数字的数码管出现交替重影现象.所以记得在这种交替式变化的程序中每次锁存位码前将(段码)数据清空

#include

sbit LATCH1=P2^2;     //声明段锁存口

sbit LATCH2=P2^3;     //声明位锁存口

#define MAXDM 10      //段码最大个数

#define MAXWM 8       //位码最大个数

#define uint unsigned int   //宏定义

#define uchar unsigned char //宏定义

uchar code DM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //09的段码值

uchar code WM[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};           //18数码管的位码值

void delay(uint );            //自定义延时函数声明

void display(uchar ,uchar );  //自定义显示函数声明,第一个参数为要开始数码管位,若为0则第一个数码管显示;第二个为累加的数字位数

uchar temp[MAXDM];            //临时数组声明

void main(void)

{

    uint num=0,ct=0;

    while(1)

    {

         ct++;

         if(ct==50)          //让显示在数码管上的数字固定一段时间

         {

               ct=0;

               num++;

               if(num==100)    //99的累加,所以数字不能超过100

               num=0;

          }

         temp[0]=DM[num/10]; //将要显示的数字和段码索引巧妙结合在一起,十位

         temp[1]=DM[num]; //个位

         display(0,2);      

         }

} 

void display(uchar site,uchar digit)

{

    uchar dex;

    for(dex=0;dex

    {

          LATCH1=1;          //清除数字变化对未点亮数码管产生交替重影

          P0=0;

          LATCH1=0;

          LATCH2=1;          //锁存选定位码

          P0=WM[dex+site];

          LATCH2=0;

          LATCH1=1;          //锁存选定段码

          P0=temp[dex];

          LATCH1=0;

          delay(3);

     }

}

void delay(uint time)

{

    uint i,j;

    for(i=time;i>0;i--)

          for(j=110;j>0;j--)                      

}

9:数码管999累加

注意:在将需显示的数字和其段码巧妙结合时要要注意,一定要让段码在0-9之间循环,不可超出,否则会出现乱码

#include

sbit LATCH1=P2^2;     //声明段锁存口

sbit LATCH2=P2^3;     //声明位锁存口

#define MAXDM 10      //段码最大个数

#define MAXWM 8       //位码最大个数

#define uint unsigned int   //宏定义

#define uchar unsigned char //宏定义

uchar code DM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //09的段码值

uchar code WM[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};           //18数码管的位码值

void delay(uint );            //自定义延时函数声明

void display(uchar ,uchar );  //自定义显示函数声明

uchar temp[MAXDM];            //临时数组声明

void main(void)

{

    uint num=0,ct=0;

    while(1)

    {

          ct++;

          if(ct==10)             //让显示在数码管上的数字固定一段时间

          {

                ct=0;         

                num++;           //固定时间到后,将显示下一个数字

                if(num==1000)    //因为是999的累加,所以不能超过1000

                     num=0;

          }

          temp[0]=DM[num/100];   //将要显示的数字和段码索引巧妙联系在一起

          temp[1]=DM[(num0)/10];

          temp[2]=DM[(num0)];

          display(0,3);

    }

}

void display(uchar site,uchar digit)

{

    uchar dex;

    for(dex=0;dex

    {

          LATCH1=1;          //清除数字变化对未点亮数码管产生交替重影

          P0=0;

          LATCH1=0; 

          LATCH2=1;          //锁存要显示的位码

          P0=WM[dex+site];

          LATCH2=0;

          LATCH1=1;          //锁存要显示的段码

          P0=temp[dex];

          LATCH1=0;

          delay(3);          //延时一小段时间,太长数字会闪烁,太短会重影

    }

} 

void delay(uint time)

{

    uint i,j;

    for(i=time;i>0;i--)

          for(j=110;j>0;j--)                     

}

10:数码管9累减

原理:同累加,用动态扫描原理 

#include

sbit LATCH1=P2^2;     //声明段锁存口

sbit LATCH2=P2^3;     //声明位锁存口

#define MAXDM 10      //段码最大个数

#define MAXWM 8       //位码最大个数

#define uint unsigned int   //宏定义

#define uchar unsigned char //宏定义

uchar code DM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //09的段码值

uchar code WM[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};           //18数码管的位码值

void delay(uint );            //自定义延时函数声明

void display(uchar ,uchar );  //自定义显示函数声明

uchar temp[MAXDM];            //临时数组声明

void main(void)

{

    uint num=9,ct=0;         //num这里应为需要开始减的数

    while(1)

    {

         ct++;

         if(ct==100)            //让显示在数码管上的数字固定一段时间

         {

              ct=0;

              if(num>0)         //为了可用更大的数,前面对num的声明用了unsigned int所以不能                                          if(num<0)判断

                   num--;       

               else             

                    num=9;

          }

        temp[0]=DM[num];   //将要显示的数字和段码索引巧妙联系在一起

        display(0,1);

    }

} 

void display(uchar site,uchar digit)

{

    uchar dex;

     for(dex=0;dex

         {

              LATCH1=1;          //清除数字变化对未点亮数码管产生交替重影

              P0=0;

              LATCH1=0; 

              LATCH2=1;          //锁存要显示的位码

              P0=WM[dex+site];

              LATCH2=0;

              LATCH1=1;          //锁存要显示的段码

              P0=temp[dex];

              LATCH1=0;

              delay(3);          //延时一小段时间,太长数字会闪烁,太短会重影

         }

}

void delay(uint time)

 

{

    uint i,j;

    for(i=time;i>0;i--)

          for(j=110;j>0;j--)                     

}

11:数码管9999累减 

#include

sbit LATCH1=P2^2;     //声明段锁存口

sbit LATCH2=P2^3;     //声明位锁存口

#define MAXDM 10      //段码最大个数

#define MAXWM 8       //位码最大个数

#define uint unsigned int   //宏定义

#define uchar unsigned char //宏定义

uchar code DM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //09的段码值

uchar code WM[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};           //18数码管的位码值

void delay(uint );            //自定义延时函数声明

void display(uchar ,uchar );  //自定义显示函数声明

uchar temp[MAXDM];            //临时数组声明

void main(void)

{

    uint num=9999,ct=0;         //num这里应为需要开始减的数

    while(1)

    {

         ct++;

         if(ct==10)            //让显示在数码管上的数字固定一段时间

         {

               ct=0;

                if(num>0)         //为了可用更大的数,前面对num的声明用了unsigned int所以不能                                          if(num<0)判断

                      num--;       

                else             

                      num=9999;

          }

          temp[0]=DM[num/1000];   //将要显示的数字和段码索引巧妙联系在一起

          temp[1]=DM[(num00)/100];

          temp[2]=DM[((num00)0)/10];

          temp[3]=DM[((num00)0)];

          display(0,4);

     }

}

 

 

void display(uchar site,uchar digit)

{

    uchar dex;

     for(dex=0;dex

         {

              LATCH1=1;          //清除数字变化对未点亮数码管产生交替重影

              P0=0;

              LATCH1=0; 

              LATCH2=1;          //锁存要显示的位码

              P0=WM[dex+site];

              LATCH2=0;

              LATCH1=1;          //锁存要显示的段码

              P0=temp[dex];

              LATCH1=0;

              delay(3);          //延时一小段时间,太长数字会闪烁,太短会重影

         }

}

void delay(uint time)

 

{

    uint i,j;

    for(i=time;i>0;i--)

          for(j=110;j>0;j--)                     

}

12:数码管65535累减

unsigned int范围为2^16=65535,

#include

sbit LATCH1=P2^2;     //声明段锁存口

sbit LATCH2=P2^3;     //声明位锁存口

#define MAXDM 10      //段码最大个数

#define MAXWM 8       //位码最大个数

#define uint unsigned int   //宏定义

#define uchar unsigned char //宏定义

uchar code DM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //09的段码值

uchar code WM[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};           //18数码管的位码值

void delay(uint );            //自定义延时函数声明

void display(uchar ,uchar );  //自定义显示函数声明

uchar temp[MAXDM];            //临时数组声明

void main(void)

{

    uint num=65535,ct=0;      //num这里应为需要开始减的数

    while(1)

    {

          ct++;

          if(ct==10)            //让显示在数码管上的数字固定一段时间

          {

               ct=0;

               if(num>0)         //为了可用更大的数,前面对num的声明用了unsigned int所以不能                                          if(num<0)判断

                    num--;       

               else             

                    num=65535;

           }

           temp[0]=DM[num/10000];   //将要显示的数字和段码索引巧妙联系在一起

           temp[1]=DM[(num000)/1000];

           temp[2]=DM[((num000)00)/100];

           temp[3]=DM[(((num000)00)0)/10];

           temp[3]=DM[(((num000)00)0)];

           display(0,5);

     }

}

 

void display(uchar site,uchar digit)

{

    uchar dex;

     for(dex=0;dex

         {

              LATCH1=1;          //清除数字变化对未点亮数码管产生交替重影

              P0=0;

              LATCH1=0; 

              LATCH2=1;          //锁存要显示的位码

              P0=WM[dex+site];

              LATCH2=0;

              LATCH1=1;          //锁存要显示的段码

              P0=temp[dex];

              LATCH1=0;

              delay(3);          //延时一小段时间,太长数字会闪烁,太短会重影

         }

}

void delay(uint time)

 

{

    uint i,j;

    for(i=time;i>0;i--)

          for(j=110;j>0;j--)                     

}


0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有