蓝桥杯数码管

数码管基础知识

蓝桥杯板上由4位数码管构成的8位数码管,数码管内部其实是一小段LED构成的,每位数码管由8个LED构成,所以控制每一小段LED的点亮和熄灭就可以显示不同的数字或英文。

蓝桥杯板载的数码管是共阳极的数码管,每一位数码管的阳极都接在一起引出来,所以一个有8个阳极,称为位选(com),所有数码管的阴极都接在一起引出来一共8位,称为段选,所以共16个引脚 。位选就是控制哪一位数码管选通,段选就是哪一段LED选通。要想点亮数码管就需要把对应的位选置为高电平,相应的段选置为低电平。

控制流程

上面说了数码管其实就是由很多个LED构成,那么点亮数码管的流程也和点亮LED一样,先给P0送段选数据,然后选通Y7C段选锁存器,关锁存器,再给P0送位选数据,开Y6C位选锁存器,关锁存器

上面说了数码管其实就是由很多个LED构成,那么点亮数码管的流程也和点亮LED一样,先给P0送段选数据,然后选通Y7C段选锁存器,关锁存器,再给P0送位选数据,开Y6C位选锁存器,关锁存器。

P27

P26

P25

译码器输出

或门输出

1

0

1

Y5=0

WR=0

(IO模式)

Y5C=1

1

0

0

Y4=0

Y4C=1

(LED)

1

1

0

Y6=0

Y6C=1

(数码管)

1

1

1

Y7=0

Y7C=1

(数码管)

聪明的童鞋就看出来了,这样子共阳极或者共阴极接的数码管在同一时刻,只能送一次段选数据,那么这样子就不能实现每一个数码管显示不同的数字或字母,但是可以利用人的视觉残留来模拟动态显示的效果,天下武功唯快不破,只要数码管上的数据变得够快,人就看不出来,就可以达到看起来每个数码管显示的东西不一样的效果了。单个数码管显示时间推荐为1ms-2ms,并且放在中断里面操作,显示效果比较好。

我们想显示不同的数字或者字母,每一次都要去推段选信号,感觉很麻烦,但是其实蓝桥杯比赛一般是会提供段选数据对照表的(只提供数字0-9),但是也有特殊情况,所以这里有一个小妙招,就是强大的STC-ISP。

在范例程序里面里面就有,并且字母对应的段选数据也有,这样子就可以愉快的复制黏贴啦~~~~当然一些特殊的符号之类的还是需要自己推的。

但是但是但是,这个里面的是共阴极数码管,蓝桥杯板载的共阳极的数码管,所以在使用这个数组的时候捏,需要进行取反(~)操作。

程序控制

//数码管动态显示
//8个数码管依次显示数字0-8

#include <STC15F2K60S2.H>
typedef unsigned char u8;
typedef unsigned int u16;

/*************  本地常量声明    **************/
u8 code t_display[]={                       //标准字库
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};      //位码

void device_ctrl(u8 P2data,u8 P0data)
{
    P0=P0data;
    P2=P2data;
    P2=0;
}
void system_init()
{
    device_ctrl(0xa0,0);   //关闭蜂鸣器,继电器
    device_ctrl(0x80,0xff);  //关闭LED

}

 void Timer2Init(void)        //1毫秒@12.000MHz
{
    AUXR &= 0xFB;        //定时器时钟12T模式
    T2L = 0x18;        //设置定时初始值
    T2H = 0xFC;        //设置定时初始值
    AUXR |= 0x10;        //定时器2开始计时
    IE2 |= 0x04;                    //开定时器2中断
    EA = 1;
}



void smg_display()
{
    static u8 i=0;       //定义i为静态变量是为了防止每次执行完毕后将i清0
    device_ctrl(0xe0,0xff);    //将所有段选置为高电平,防止在com口开启时送入前一次的段选数据,其实有没有这一步操作区别也不大
    device_ctrl(0xe0,~t_display[i]);   //送段选信号,记住从STC-ISP中复制来的数据一定要进行取反
    device_ctrl(0xc0,T_COM[i]);     //送位选信号
    i++;
    if(i==8)             //当8个数码管数据全部送完,将i清0
        i=0;
}

 void main()
 {
    system_init();
    Timer2Init();
    while(1)
    {
        
    }
 }

void t2int() interrupt 12  
{
    smg_display();
}
//数码管显示HELLO


#include <STC15F2K60S2.H>
typedef unsigned char u8;
typedef unsigned int u16;

/*************  本地常量声明    **************/
u8 code t_display[]={                       //标准字库
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};      //位码

void device_ctrl(u8 P2data,u8 P0data)
{
    P0=P0data;
    P2=P2data;
    P2=0;
}
void system_init()
{
    device_ctrl(0xa0,0);   //关闭蜂鸣器,继电器
    device_ctrl(0x80,0xff);  //关闭LED

}

u8 smg_buf[8];
void smg_process()                             //利用重新定义8位数组,给数字赋值,再把数组的值给8个数码管
                                            //可以不用去修改数码管显示函数,不想显示的时候就直接给数组对应的位赋0就可以了
{
    smg_buf[0]=t_display[18];
    smg_buf[1]=t_display[14];
    smg_buf[2]=t_display[21];
    smg_buf[3]=t_display[21];
    smg_buf[4]=t_display[0];
    smg_buf[5]=0x00;                        //蓝桥杯板载是共阳极数码管,但是我们拷贝来的对照数据是共阴极的
    smg_buf[6]=0x00;                        //并且在显示函数里面就是进行了取反操作,所以相应的0xff取反0x00才是熄灭数码管
    smg_buf[7]=0x00;
}
 
 void Timer2Init(void)        //1毫秒@12.000MHz
{
    AUXR &= 0xFB;        //定时器时钟12T模式
    T2L = 0x18;        //设置定时初始值
    T2H = 0xFC;        //设置定时初始值
    AUXR |= 0x10;        //定时器2开始计时
    IE2 |= 0x04;                    //开定时器2中断
    EA = 1;
}



void smg_display()
{
    static u8 i=0;       //定义i为静态变量是为了防止每次执行完毕后将i清0
    device_ctrl(0xe0,0xff);    //将所有段选置为高电平,防止在com口开启时送入前一次的段选数据,其实有没有这一步操作区别也不大
    device_ctrl(0xe0,~smg_buf[i]);   //送段选信号,记住从STC-ISP中复制来的数据一定要进行取反
    device_ctrl(0xc0,T_COM[i]);     //送位选信号
    i++;
    if(i==8)             //当8个数码管数据全部送完,将i清0
        i=0;
}

 void main()
 {
    system_init();
    Timer2Init();
    smg_process();
    while(1)
    {
        
    }
 }
 
 
void t2int() interrupt 12  
{
    smg_display();
}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值