【项目8-任务10-小组13】利用四位数码管实现动态扫描显示

学习任务
1、四位数码管的电路结构与显示原理
(什么是位选、什么是段选、共阴与共阳的区别、显示4位数字,需要多少条口线?显示n位数字呢?)
2、Arduino直接连接四位数码管实现四位阿拉伯数字显示
(Friting绘制电路图(注意每个段都要加470欧姆限流电阻),程序原理说明,包含完整注释的源代码)

首先主要是介绍要完成四位数码管的动态扫描显示所需要了解并掌握的四位数码管的电路结构与显示原理。

一、位选与段选

图1.jpg

以一位的7段数码管为例,如图1所示,一位的数码管加上小数点一共是8个需要控制的发光管,分别是a、b、c、d、e、f、g、dp,由8个引脚分别控制他们的亮灭,也就是说一个引脚控制一个发光管,那么这就是段选。发光的二极管是有两端的,那么这8个发光的二极管有一个公共端,这样就可以控制一位数码管整体,这就是位选。


图2.jpg

由一位数码管延伸到四位数码管时,如图2所示,每一个发光管都有相应的引脚控制,每一位的数码管都有自己的公共端,通过公共端来控制哪一位的数码管亮或者是灭,这就是位选。

二、共阴与共阳的区别

一位的数码管相当于是由8个发光二极管拼成的,二极管有两个极,也就是阴极和阳极。


图3.jpg
图4.jpg
  • 共阴数码管(如图4),也就是把所有组成这一位数码管的二极管的阴极都接在一起,想要点亮数码管中的某一段,就将com段(所有段的共同的阴极)接地,也就是低电平,然后把相应的阳极(a、b、c…….)接高电平,这样这一段就会被点亮。
    图5.jpg
  • 共阳数码管(如图5),也就是把所有组成这一位数码管的二极管的阳极都接在一起,想要点亮数码管中的某一段,就将com段(所有段的共同的阳极)接高电平,然后把相应的阴极(a、b、c…….)接地或者是低电平,这样这一段就会被点亮。
    当然,如果拿到一个数码管不知道是共阳还是共阴,可以用万用表的蜂鸣档测试一下或者高低电平接一下即可知道。

三、显示N位数字的口线数量规律

那么要想使四位数码管显示4位数字,需要多少条口线?显示n位数字呢?能总结出一个规律么?

图6.jpg

  • 以两位的共阴数码管为例(如图6),先观察段选,每一位数码管的相同的段并联在一起,最后由一个引脚控制,那么每一位有8个二极管,也就是需要并联8次,最后需要8个口线。对于位选,因为一共是两位数码管,所以需要两个公共端去控制每一位数码管。这样就是(8+2)条口线。


    图7.jpg
  • 延伸到四位数码管(如图7),同理,对于段选,仍然是每一位数码管的相同的段并联在一起,最后由一个引脚控制,那么每一位有8个二极管,也就是需要并联8次,最后需要8个引脚。对于位选,因为一共是四位数码管,所以需要四个公共端去控制每一位数码管。这样就是(8+4)条口线。
    可以看到,N位数码管,对于段选,不管是多少位的数码管,由于每一位相同的段都是并联,都是需要8个口线去控制段;对于位选,有几位数码管,就需要几个公共端去控制。所以N位数码管显示N位数字需要(8+N)条口线。

接下来介绍一下我们所使用的四位数码管主要会有哪些类型,并且他们之间有什么不同。

一、12个引脚的四位数码管

类型一

图1.jpg
图2.jpg

如图1,2所示,这种四位数码管是最常见的也是最简单的,每一位数码管中相同的段彼此并联,由8个引脚控制段选,其余4个引脚分别控制四个位选。

类型二

图3.jpg
图4.jpg

如图3,4所示,这种四位数码管在第二三位中间多了两点,这是属于时钟数码管,可以用它来显示时间。以共阴为例,这种的不同之处在于,它将增加的时钟点的阳极与其他四位的小数点(dp段)的阳极相并联,然后阴极也就是公共端,与第二位的数码管的公共端共享。也就是说可以看成是将这两个时钟点加入到了第二位的数码管中,成为它的一部分,这样使得四位数码管的引脚数量仍然不发生改变。

二、14个引脚的四位数码管

图5.png
图6.jpg
图7.jpg

如图5,6,7,所示,以共阴极为例,这是我们所使用的四位数码管,也同样是属于时钟数码管,它之所以会增加两个引脚是因为它将两个时钟点单独拿出来,阳极并联使用一个引脚,再使用一个公共端,这个就可以看成是两个时钟点的一个位选。

在之前的四位数码管的显示原理学习的基础上,介绍的是利用Arduino直接连接四位数码管从而实现四位阿拉伯数字显示。以四位共阴数码管为例,显示数字1234。

一、实验器材

  • Nano开发板
  • 配套USB数据线
  • 一个四位数码管
  • 8个470Ω的电阻
  • 若干导线

二、电路连接图

电路连接图.jpg

分析:四位数码管一共有8个引脚控制段选,所以需要每一个引脚串联一个电阻保证电流的正常流通,使得二极管正常显示。根据数码管的引脚图可对应段选和位选的引脚号,从而通过导线将引脚与nano板相连接,与电脑连接之后,在arduino中编写代码即可控制四位数码管。

三、编写代码

#define SEG_B 3  //Arduino Pin3--->SegLed Pin7
#define SEG_C 4  //Arduino Pin4--->SegLed Pin4
#define SEG_D 5  //Arduino Pin5--->SegLed Pin2
#define SEG_E 6  //Arduino Pin6--->SegLed Pin1
#define SEG_F 7  //Arduino Pin7--->SegLed Pin10
#define SEG_G 8  //Arduino Pin8--->SegLed Pin5    
#define SEG_H 9  //Arduino Pin9--->SegLed Pin3

#define COM1 13  //Arduino Pin10--->SegLed Pin12
#define COM2 12  //Arduino Pin11--->SegLed Pin9
#define COM3 11  //Arduino Pin12--->SegLed Pin8
#define COM4 10  //Arduino Pin13--->SegLed Pin6
unsigned char table[10][8] =                
{
        {0,        0,        1,        1,        1,        1,        1,        1},        //0
        {0,        0,        0,        0,        0,        1,        1,        0},        //1
        {0,        1,        0,        1,        1,        0,        1,        1},        //2
        {0,        1,        0,        0,        1,        1,        1,        1},        //3
        {0,        1,        1,        0,        0,        1,        1,        0},        //4
        {0,        1,        1,        0,        1,        1,        0,        1},        //5
        {0,        1,        1,        1,        1,        1,        0,        1},        //6
        {0,        0,        0,        0,        0,        1,        1,        1},        //7
        {0,        1,        1,        1,        1,        1,        1,        1},        //8
        {0,        1,        1,        0,        1,        1,        1,        1}        //9
};
void setup()
{
        pinMode(SEG_A,OUTPUT);                //设置为输出引脚
        pinMode(SEG_B,OUTPUT);
        pinMode(SEG_C,OUTPUT);
        pinMode(SEG_D,OUTPUT);
        pinMode(SEG_E,OUTPUT);
        pinMode(SEG_F,OUTPUT);
        pinMode(SEG_G,OUTPUT);
        pinMode(SEG_H,OUTPUT);
       
        pinMode(COM1,OUTPUT);
        pinMode(COM2,OUTPUT);
        pinMode(COM3,OUTPUT);
        pinMode(COM4,OUTPUT);
}
void loop()
{
        Display(1,1);                        //第1位显示1
        Delay(10);
        Display(2,2);                        //第2位显示2
        Delay(10);
        Display(3,3);                        //第3位显示3
        Delay(10);
        Display(4,4);                        //第4位显示4
        Delay(10);
}
void Display(unsigned char com, unsigned char num)
{
        digitalWrite(SEG_A,LOW);              
        digitalWrite(SEG_B,LOW);
        digitalWrite(SEG_C,LOW);
        digitalWrite(SEG_D,LOW);
        digitalWrite(SEG_E,LOW);
        digitalWrite(SEG_F,LOW);
        digitalWrite(SEG_G,LOW);
        digitalWrite(SEG_H,LOW);

        switch(com)                                                //选通位选
        {
                case 1:
                        digitalWrite(COM1,LOW);                //选择位1
                        digitalWrite(COM2,HIGH);
                       digitalWrite(COM3,HIGH);
                        digitalWrite(COM4,HIGH);
                        break;
                case 2:
                        digitalWrite(COM1,HIGH);
                        digitalWrite(COM2,LOW);                //选择位2
                        digitalWrite(COM3,HIGH);
                        digitalWrite(COM4,HIGH);
                        break;
                case 3:
                        digitalWrite(COM1,HIGH);
                        digitalWrite(COM2,HIGH);
                        digitalWrite(COM3,LOW);                //选择位3
                        digitalWrite(COM4,HIGH);
                        break;
                case 4:
                        digitalWrite(COM1,HIGH);
                        digitalWrite(COM2,HIGH);
                        digitalWrite(COM3,HIGH);
                        digitalWrite(COM4,LOW);                //选择位4
                        break;
                default:break;
        }
        digitalWrite(SEG_A,table[num][7]);                        //a查询码值表
        digitalWrite(SEG_B,table[num][6]);
        digitalWrite(SEG_C,table[num][5]);
        digitalWrite(SEG_D,table[num][4]);
        digitalWrite(SEG_E,table[num][3]);
        digitalWrite(SEG_F,table[num][2]);
        digitalWrite(SEG_G,table[num][1]);
        digitalWrite(SEG_H,table[num][0]);
}

四、代码分析

  1. 首先,定义数码管a段是接引脚2,b段是接引脚3……以此类推定义完段选,之后再定义位选,1位数码管的公共端接13……同样以此类推。
#define SEG_A 2  //Arduino Pin2--->SegLed Pin11
#define SEG_B 3  //Arduino Pin3--->SegLed Pin7
#define SEG_C 4  //Arduino Pin4--->SegLed Pin4
#define SEG_D 5  //Arduino Pin5--->SegLed Pin2
#define SEG_E 6  //Arduino Pin6--->SegLed Pin1
#define SEG_F 7  //Arduino Pin7--->SegLed Pin10
#define SEG_G 8  //Arduino Pin8--->SegLed Pin5    
#define SEG_H 9  //Arduino Pin9--->SegLed Pin3

#define COM1 13  //Arduino Pin10--->SegLed Pin12
#define COM2 12  //Arduino Pin11--->SegLed Pin9
#define COM3 11  //Arduino Pin12--->SegLed Pin8
#define COM4 10  //Arduino Pin13--->SegLed Pin6
  1. 定义一个可以查询的码值表,因为使用的是共阴四位数码管,用0表示低电平,用1表示高电平,从而将0~9这10个数字显示时,数码管的阳极的一端的高低电平的状态表示出来。例如,当想要显示数字1时,那么a段与b段的阳极是高电平,那么a段与b段的二极管将会点亮,其余的是熄灭状态,那么就会显示数字1。
unsigned char table[10][8] =                
{
        {0,        0,        1,        1,        1,        1,        1,        1},        //0
        {0,        0,        0,        0,        0,        1,        1,        0},        //1
        {0,        1,        0,        1,        1,        0,        1,        1},        //2
        {0,        1,        0,        0,        1,        1,        1,        1},        //3
        {0,        1,        1,        0,        0,        1,        1,        0},        //4
        {0,        1,        1,        0,        1,        1,        0,        1},        //5
        {0,        1,        1,        1,        1,        1,        0,        1},        //6
        {0,        0,        0,        0,        0,        1,        1,        1},        //7
        {0,        1,        1,        1,        1,        1,        1,        1},        //8
        {0,        1,        1,        0,        1,        1,        1,        1}        //9
};
  1. 利用setup函数定义所连接的引脚为输出引脚
void setup()
{
        pinMode(SEG_A,OUTPUT);                //设置为输出引脚
        pinMode(SEG_B,OUTPUT);
        pinMode(SEG_C,OUTPUT);
      pinMode(SEG_D,OUTPUT);
        pinMode(SEG_E,OUTPUT);
        pinMode(SEG_F,OUTPUT);
        pinMode(SEG_G,OUTPUT);
        pinMode(SEG_H,OUTPUT);
        pinMode(COM1,OUTPUT);
        pinMode(COM2,OUTPUT);
        pinMode(COM3,OUTPUT);
        pinMode(COM4,OUTPUT);
}

4.用loop函数来定义第一位显示1,第二位显示2,第三位显示3,第四位显示4,每一个显示后面都加了一个delay,用来表示显示延时10秒钟。又因为loop函数是一个死循环体,那么它会一直循环执行函数里面的内容。

void loop()
{
        Display(1,1);                        //第1位显示1
        Delay(10);
        Display(2,2);                        //第2位显示2
        Delay(10);
        Display(3,3);                        //第3位显示3
        Delay(10);
        Display(4,4);                        //第4位显示4
        Delay(10);
}
  1. 定义display这个函数,首先利用digitalWrite函数将共阴数码管的8个段的阳极设置为低电平,作用是为了将所有的二极管熄灭,起到置零的作用。
    之后利用switch函数来定义位选,因为是以显示1234为例,那么当只让第一位亮起数字1时,就将第一位的公共端(com端)设置为低电平,其余设置为高电平;当只让第二位亮起数字2时,就将第二位的公共端(com端)设置为低电平……
    最后,定义完位选后,用digitalWrite来定义段选,利用之前定义好的码值表,当显示数字1时,查询码值表找到相应的每一个段(a、b、c……)分别是高电平还是低电平,然后将这个信号发送到每一个段的对应的引脚上来控制二极管的亮灭状态。
void Display(unsigned char com, unsigned char num)
{
        digitalWrite(SEG_A,LOW);              
        digitalWrite(SEG_B,LOW);
        digitalWrite(SEG_C,LOW);
        digitalWrite(SEG_D,LOW);
        digitalWrite(SEG_E,LOW);
        digitalWrite(SEG_F,LOW);
        digitalWrite(SEG_G,LOW);
        digitalWrite(SEG_H,LOW);

        switch(com)                                                //选通位选
        {
                case 1:
                        digitalWrite(COM1,LOW);                //选择位1
                        digitalWrite(COM2,HIGH);
                       digitalWrite(COM3,HIGH);
                        digitalWrite(COM4,HIGH);
                        break;
                case 2:
                        digitalWrite(COM1,HIGH);
                        digitalWrite(COM2,LOW);                //选择位2
                        digitalWrite(COM3,HIGH);
                        digitalWrite(COM4,HIGH);
                        break;
                case 3:
                        digitalWrite(COM1,HIGH);
                        digitalWrite(COM2,HIGH);
                        digitalWrite(COM3,LOW);                //选择位3
                        digitalWrite(COM4,HIGH);
                        break;
                case 4:
                        digitalWrite(COM1,HIGH);
                        digitalWrite(COM2,HIGH);
                   digitalWrite(COM3,HIGH);
                        digitalWrite(COM4,LOW);                //选择位4
                        break;
                default:break;
        }
        digitalWrite(SEG_A,table[num][7]);                        //a查询码值表
        digitalWrite(SEG_B,table[num][6]);
        digitalWrite(SEG_C,table[num][5]);
        digitalWrite(SEG_D,table[num][4]);
        digitalWrite(SEG_E,table[num][3]);
        digitalWrite(SEG_F,table[num][2]);
        digitalWrite(SEG_G,table[num][1]);
        digitalWrite(SEG_H,table[num][0]);
}         

五、实验现象

实物连接图.jpg

实物连接图2.jpg

输入代码之后,观察四位数码管,先第一位10秒显示数字1,第二位10秒显示数字2,第三位10秒显示数字3,第一位10秒显示数字4,之后一次再循环点亮数字1,2,3,4……

六、实验总结

为什么不是直接显示数字1234的静态显示,而是数字循环出现?

  • 首先,根据四位数码管的引脚图可以知道,每一位相同的段是并联在一起然后连到一个相同的引脚,信号会发送到每一个段的引脚上来控制段的点亮还是熄灭。假如是同时显示四位数字的话,那么引脚一次只能传递高电平和低电平的其中一种,会使每一位相同的段具有相同的电平,但是显示不同的数字,段的状态是不同的,这就产生了矛盾。所以四位数码管在显示的时候,是先将第一位的数码管的所有段的信号通过引脚传送之后,在传送第二位需要的信号,一直到第四位。
  • 其次,要注意代码中使用loop函数来定义第一位显示1,第二位显示2,第三位显示3,第四位显示4,每一个显示后面都加了一个delay,用来表示显示延时10秒钟。又因为loop函数是一个死循环体,那么它会一直循环执行函数里面的内容。假如将delay去掉,实验的现象是看上去数字1234是同时显示的,其实仍是1234在循环显示,只是速度太快,产生视觉暂留效应给我们的眼睛产生了错觉。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,290评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,107评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,872评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,415评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,453评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,784评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,927评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,691评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,137评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,472评论 2 326
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,622评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,289评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,887评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,741评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,316评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,490评论 2 348

推荐阅读更多精彩内容