电子产品世界 » 论坛首页 » 高校社团 » 坤创E-Geek/天科大新电社 » 04. 单片机IO口的操作2-数码管篇


共8条 1/1 1 跳转至

04. 单片机IO口的操作2-数码管篇

工程师
2019-01-23 23:46:37    评分

在上一帖中,我们进行了LED点灯的练习,当然由于蓝桥板采用了通过74HC573、74HC02、74HC138这三个数字芯片作为LED灯的前置驱动电路的特殊电路结构,导致使用蓝桥板点亮LED灯的程序要稍微多了几行。同学们只需要搞明白,如何使用这些数字芯片级联控制就行了,耐心一点,在蓝桥板的资料包中,有这些芯片的说明文档。耐心点,根据代码,就很容易搞明白啦~

对于LED点灯来说,同学们会觉得很不屑,这么简单的操作,怎么可能出竞赛题呢?有这样的想法,你就错了。2018年第九届蓝桥杯省赛的试题,就是让你点灯,让你点出不同亮度的灯,让你变着法儿各种点灯,于是死伤无数。。。当然做这个题需要配合PWM脉宽调制的概念进行操作,对于历年试题的解答,在本系列贴的第二部分,会逐步为大家奉上。敬请期待哦~!

好了,言归正传,今天我们要进行数码管的操作,数码管是非常重要的一个部分,可以说历年考题必考数码管,因为它是蓝桥板上唯一一个能够进行显示的器件,当然,有同学问道今后可能不可能考到点阵和液晶,我可以告诉大家,可能性不大,今年一定还是数码管!那么既然数码管这么重要,接下来我就把相关的练习题和代码发出来,供大家参考学习。

题1、在数码管上显示字符8,每1秒移动一位

题2、在数码管上稳定显示字符12345678

题3、在数码管上稳定显示给定字符0000-1023或者000H-3FFH

下面依旧按照惯例分别奉上相关代码,并在文末给出所有代码压缩包的下载链接,欢迎大家下载查看。如有任何问题,请大家回帖告知,谢谢~!

-----------------------蓝桥板代码---------------------

蓝桥板题1代码:

/**********************************************
1、在数码管上显示字符8,每1秒移动一位
**********************************************/
#include<stc15f2k60s2.h>
#include"intrins.h"
#define  uchar  unsigned char
#define  uint   unsigned int 
uchar   code  smgwei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
void delayms(uint z);
void init();
void main()
{
 uchar i;
 init();
   
 while(1)
 {
//  for(i=0;i<8;i++)        //循环右移
//{
//P2=0xc0;
//P0=smgwei[i];
//P2=0xff;
//P0=0x80;;
//delayms(1000);
//      if(i==8)i=0; 
//}
 for(i=7;i>=0;i--)        //循环左移
 {
        P2=0xc0;
        P0=smgwei[i];
        P2=0xff;
        P0=0x80;;
        delayms(1000);
        if(i==0)i=8;
 }
}
}
void delayms(uint z)
{
    uint x,y;
    for(x=z;x>0;x--)
        for(y=845;y>0;y--);
}
void init()
{
   P2=0xa0; 
     P0=0x00;
     P2=0x80;
     P0=0xff;
     P2=0xc0;
     P0=0xff;
     P2=0xff;
     P0=0xff;
}

蓝桥板题2代码:

/*****************************************************
2、在数码管上稳定显示字符12345678
******************************************************/
#include<stc15f2k60s2.h>
#include"intrins.h"
#define  uchar  unsigned char
#define  uint   unsigned int 
uchar   code  smgtab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF,};
uchar  yi,er,san,si,wu,liu,qi,ba;
void  display1(uchar yi,uchar er);
void  display2(uchar san,uchar si);
void  display3(uchar wu,uchar liu );
void  display4(uchar qi,uchar ba);
void delayms(uint z);
void init();
void main()
{
     init();
       while(1)
     {
       yi=1;er=2;san=3;si=4;wu=5;liu=6;qi=7;ba=8;
       display1(yi,er);
         display2(san,si);
         display3(wu,liu);
         display4(qi,ba);
     }
}
void delayms(uint z)
{
    uint x,y;
    for(x=z;x>0;x--)
        for(y=845;y>0;y--);
}
void init()
{
      P2=0xa0; 
     P0=0x00;
     P2=0x80;
     P0=0xff;
     P2=0xc0;
     P0=0xff;
     P2=0xff;
     P0=0xff;
}
void  display1(uchar yi,uchar er)
{
      P2=0xc0;
     P0=0x01;
     P2=0xff;
     P0=smgtab[yi];
     delayms(1);
     P2=0xc0;
     P0=0x02;
     P2=0xff;
     P0=smgtab[er];
     delayms(1);
}
void  display2(uchar san,uchar si)
{
      P2=0xc0;
     P0=0x04;
     P2=0xff;
     P0=smgtab[san];
     delayms(1);
     P2=0xc0;
     P0=0x08;
     P2=0xff;
     P0=smgtab[si];
     delayms(1);
}
void  display3(uchar wu,uchar liu )
{
       P2=0xc0;
     P0=0x10;
       P2=0xff;
     P0=smgtab[wu];
     delayms(1);
     P2=0xc0;
     P0=0x20;
     P2=0xff;
     P0=smgtab[liu];
     delayms(1);
}
void  display4(uchar qi,uchar ba)
{
      P2=0xc0;
     P0=0x40;
     P2=0xff;
     P0=smgtab[qi];
     delayms(1);
     P2=0xc0;
     P0=0x80;
     P2=0xff;
     P0=smgtab[ba];
     delayms(1);
}

蓝桥板题3代码:

/*****************************************************
3、在数码管上稳定显示给定字符0000-1023或者000H-3FFH
******************************************************/
#include<stc15f2k60s2.h>
#include"intrins.h"
#define  uchar  unsigned char
#define  uint   unsigned int 
uchar   code  smgtab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF, 0x8E,0x89,0XFF,};
uchar  yi,er,san,si,wu,liu,qi,ba;
void  display1(uchar yi,uchar er);
void  display2(uchar san,uchar si);
void  display3(uchar wu,uchar liu );
void  display4(uchar qi,uchar ba);
void delayms(uint z);
void init();
void main()
{
   init();
   while(1)
   {
    // yi=0;er=0;san=0;si=0;wu=1;liu=0;qi=2;ba=3;
      yi=0;er=0;san=0;si=12;wu=3;liu=11;qi=11;ba=12;
      display1(yi,er);
      display2(san,si);
      display3(wu,liu);
      display4(qi,ba);
   }
}
void delayms(uint z)
{
    uint x,y;
    for(x=z;x>0;x--)
        for(y=845;y>0;y--);
}
void init()
{
       P2=0xa0; 
     P0=0x00;
     P2=0x80;
     P0=0xff;
     P2=0xc0;
     P0=0xff;
     P2=0xff;
     P0=0xff;
}
void  display1(uchar yi,uchar er)
{
       P2=0xc0;
     P0=0x01;
     P2=0xff;
     P0=smgtab[yi];
     delayms(1);
     P2=0xc0;
     P0=0x02;
     P2=0xff;
     P0=smgtab[er];
     delayms(1);
}
void  display2(uchar san,uchar si)
{
       P2=0xc0;
     P0=0x04;
     P2=0xff;
     P0=smgtab[san];
     delayms(1);
     P2=0xc0;
     P0=0x08;
     P2=0xff;
     P0=smgtab[si];
     delayms(1);
}
void  display3(uchar wu,uchar liu )
{
       P2=0xc0;
     P0=0x10;
       P2=0xff;
     P0=smgtab[wu];
     delayms(1);
     P2=0xc0;
     P0=0x20;
     P2=0xff;
     P0=smgtab[liu];
     delayms(1);
}
void  display4(uchar qi,uchar ba)
{
       P2=0xc0;
     P0=0x40;
     P2=0xff;
     P0=smgtab[qi];
     delayms(1);
     P2=0xc0;
     P0=0x80;
     P2=0xff;
     P0=smgtab[ba];
     delayms(1);
}


-----------------------小红板代码----------------------

小红板题1代码:

/*************************************************************
1、在数码管上显示字符8,每1秒移动一位
*************************************************************/
#include"reg52.h"
#define  uchar unsigned char
#define  uint  unsigned int 
sbitP_HC595_SER   = P2^7;//pin 14SERdata input
sbitP_HC595_RCLK  = P2^5;//pin 12RCLkstore (latch) clock
sbitP_HC595_SRCLK = P2^6;//pin 11SRCLKShift data clock
//uchar  code smgtab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00};//共阴数码管段值
uchar  code  smgwei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uchar yi,er,san,si,wu,liu,qi,ba;
void SMG_Init();
void Send_595(unsigned char dat);
void delayms(uint z);
void main()
{
    uchar i;
    SMG_Init();
    while(1)
   {
        //for(i=0;i<8;i++)     //循环右移
        //{
        //Send_595(smgwei[i]); 
        //    Send_595(0x7f);
        //    P_HC595_RCLK = 0;
        //    P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
        //        delayms(1000);
        //}
   
      for(i=7;i>=0;i--)     //循环左移
      {
            Send_595(smgwei[i]); 
            Send_595(0x7f);
            P_HC595_RCLK = 0;
            P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
            delayms(1000);
            if(i==0)i=8;
      }
    }
}
void delayms(uint z)
{
    uint x,y;
    for(x=z;x>0;x--)
        for(y=110;y>0;y--);
}
void SMG_Init()
{
    Send_595(0x00);  //同时选择8个数码管
    Send_595(0x00); //让8个数码管同时显示消隐字符
    P_HC595_RCLK = 0;
    P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
}
void Send_595(unsigned char dat)//发送一个字节
{
    unsigned chari;
    for(i=0; i<8; i++)
    {
        if(dat & 0x80)    //判断dat的最高位是否为1
        P_HC595_SER = 1;  //最高位如果为1,则令P2.7 = 1
        else
        P_HC595_SER = 0;  //最高位如果为0,则令P2.7 = 0
        P_HC595_SRCLK = 0;
        P_HC595_SRCLK = 1;
        P_HC595_SRCLK = 0;  //使用P2.6制造一个上升沿将这一位数据送到74HC595的QA输出端
        dat = dat << 1;     //将dat左移一位,取次高位
    }
}

小红板题2代码:

/******************************************
2、在数码管上稳定显示字符12345678
*******************************************/
/*#include"reg52.h"
#define  uchar unsigned char
#define  uint  unsigned int 
sbitP_HC595_SER   = P2^7;//pin 14SERdata input
sbitP_HC595_RCLK  = P2^5;//pin 12RCLkstore (latch) clock
sbitP_HC595_SRCLK = P2^6;//pin 11SRCLKShift data clock
uchar  code smgtab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00};//共阴数码管段值
uchar yi,er,san,si,wu,liu,qi,ba;
void  display1(uchar yi,uchar er);
void  display2(uchar san,uchar si);
void  display3(uchar wu,uchar liu);
void  display4(uchar qi,uchar ba);
void SMG_Init();
void Send_595(unsigned char dat);
void delayms(uint z);
void main()
{
    SMG_Init();
    while(1)
    {
        yi=1;er=2;san=3;si=4;wu=5;liu=6;qi=7;ba=8;
        display1(yi,er);
        display2(san,si);
        display3(wu,liu);
        display4(qi,ba);
    }
}
void delayms(uint z)
{
    uint x,y;
    for(x=z;x>0;x--)
        for(y=110;y>0;y--);
}
void SMG_Init()
{
    Send_595(0x00);  //同时选择8个数码管
    Send_595(0x00); //让8个数码管同时显示消隐字符
    P_HC595_RCLK = 0;
    P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
}
void Send_595(unsigned char dat)//发送一个字节
{
    unsigned char i;
    for(i=0; i<8; i++)
    {
        if(dat & 0x80)    //判断dat的最高位是否为1
        P_HC595_SER = 1;  //最高位如果为1,则令P2.7 = 1
        else
        P_HC595_SER = 0;  //最高位如果为0,则令P2.7 = 0
        P_HC595_SRCLK = 0;
        P_HC595_SRCLK = 1;
        P_HC595_SRCLK = 0;  //使用P2.6制造一个上升沿将这一位数据送到74HC595的QA输出端
        dat = dat << 1;     //将dat左移一位,取次高位
    }
}
void  display1(uchar yi,uchar er)
{
    Send_595(0xfe);        //位选
    Send_595(smgtab[yi]); //段选
    P_HC595_RCLK = 0;
    P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
    delayms(1);
    Send_595(0xfd); 
    Send_595(smgtab[er]);
    P_HC595_RCLK = 0;
    P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
    delayms(1);
}
void  display2(uchar san,uchar si)
{
    Send_595(0xfb); 
    Send_595(smgtab[san]);
    P_HC595_RCLK = 0;
    P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
    delayms(1);
    Send_595(0xf7); 
    Send_595(smgtab[si]);
    P_HC595_RCLK = 0;
    P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
    delayms(1);
}
void  display3(uchar wu,uchar liu)
{
    Send_595(0xef); 
    Send_595(smgtab[wu]);
    P_HC595_RCLK = 0;
    P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
    delayms(1);
    Send_595(0xdf); 
    Send_595(smgtab[liu]);
    P_HC595_RCLK = 0;
    P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
    delayms(1);
}
void  display4(uchar qi,uchar ba)
{
    Send_595(0xbf); 
    Send_595(smgtab[qi]);
    P_HC595_RCLK = 0;
    P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
    delayms(1);
    Send_595(0x7f); 
    Send_595(smgtab[ba]);
    P_HC595_RCLK = 0;
    P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
    delayms(1);
}

小红板题3代码:

/*************************************************
3、在数码管上稳定显示给定字符0000-1023或者000H-3FFH
**************************************************/
#include"reg52.h"
#define  uchar unsigned char
#define  uint  unsigned int 
sbitP_HC595_SER   = P2^7;//pin 14SERdata input
sbitP_HC595_RCLK  = P2^5;//pin 12RCLkstore (latch) clock
sbitP_HC595_SRCLK = P2^6;//pin 11SRCLKShift data clock
uchar  code smgtab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x76,0x00};
uchar yi,er,san,si,wu,liu,qi,ba;
void  display1(uchar yi,uchar er);
void  display2(uchar san,uchar si);
void  display3(uchar wu,uchar liu);
void  display4(uchar qi,uchar ba);
void SMG_Init();
void Send_595(unsigned char dat);
void delayms(uint z);
void main()
{
     SMG_Init();
   while(1)
     {
        // yi=0;er=0;san=0;si=0;wu=1;liu=0;qi=2;ba=3;    字符0000-1023  
        yi=0;er=0;san=0;si=0;wu=3;liu=15;qi=15;ba=16;
        display1(yi,er);
        display2(san,si);
        display3(wu,liu);
        display4(qi,ba);
     }
}
void delayms(uint z)
{
    uint x,y;
    for(x=z;x>0;x--)
        for(y=110;y>0;y--);
}
void SMG_Init()
{
    Send_595(0x00);  //同时选择8个数码管
    Send_595(0x00); //让8个数码管同时显示消隐字符
    P_HC595_RCLK = 0;
    P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
}
void Send_595(unsigned char dat)//发送一个字节
{
    unsigned char i;
    for(i=0; i<8; i++)
    {
        if(dat & 0x80)    //判断dat的最高位是否为1
        P_HC595_SER = 1;  //最高位如果为1,则令P2.7 = 1
        else
        P_HC595_SER = 0;  //最高位如果为0,则令P2.7 = 0
        P_HC595_SRCLK = 0;
        P_HC595_SRCLK = 1;
        P_HC595_SRCLK = 0;  //使用P2.6制造一个上升沿将这一位数据送到74HC595的QA输出端
        dat = dat << 1;     //将dat左移一位,取次高位
    }
}
void  display1(uchar yi,uchar er)
{
    Send_595(0xfe); 
    Send_595(smgtab[yi]);
    P_HC595_RCLK = 0;
    P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
    delayms(1);
    Send_595(0xfd); 
    Send_595(smgtab[er]);
    P_HC595_RCLK = 0;
    P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
    delayms(1);
}
void  display2(uchar san,uchar si)
{
  Send_595(0xfb); 
Send_595(smgtab[san]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
    delayms(1);
  Send_595(0xf7); 
Send_595(smgtab[si]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
    delayms(1);
}
void  display3(uchar wu,uchar liu)
{
   Send_595(0xef); 
    Send_595(smgtab[wu]);
    P_HC595_RCLK = 0;
    P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
   delayms(1);
   Send_595(0xdf); 
    Send_595(smgtab[liu]);
    P_HC595_RCLK = 0;
    P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
   delayms(1);
}
void  display4(uchar qi,uchar ba)
{
  Send_595(0xbf); 
   Send_595(smgtab[qi]);
   P_HC595_RCLK = 0;
   P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
  delayms(1);
  Send_595(0x7f); 
   Send_595(smgtab[ba]);
   P_HC595_RCLK = 0;
   P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
   delayms(1);
}


----------------所有代码打包下载链接------------------

04. 单片机IO口的操作2-数码管篇_全部代码打包.zip


同学们,可以接着往下进行 05. 单片机I/O口的操作3-机械按键篇 的题目练习哦~~对代码有任何问题,欢迎回帖指出来哦~积极参与的小可耐们,可是有U盘拿的哦~!!

学习,就像攀登珠峰,一步一步都要走扎实,才能顺利登顶!Come on!!




管理员
2019-01-24 08:37:17    评分
2楼

谢谢楼主分享


专家
2019-01-24 11:21:31    评分
3楼

提个建议,还是少用display1这样的命名,来一个实际意义的单词呗。

displayAlpha;

displayBravo;


菜鸟
2019-01-24 13:47:59    评分
4楼

感谢楼主的分享,楼主辛苦了,如果蓝桥板的代码能多加一点注释就好了


菜鸟
2019-01-24 20:32:55    评分
5楼

果然,数码管是单片机学习过程中的重中之重!


菜鸟
2019-01-25 23:14:58    评分
6楼

为什么要把数字显示分成两个数字两个数字显示?这种思路有什么优点?


菜鸟
2019-01-27 18:57:12    评分
7楼

帖子值得永久收藏,力挺楼主


专家
2019-02-15 08:47:11    评分
8楼

帖子值得永久收藏,挺楼主


共8条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]