【雕爷学编程】Arduino动手做(47)---七段LED数码管模块
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和模块,依照实践(动手试试)出真知的理念,以学习和交流为目的,这里准备逐一做做实验,不管能否成功,都会记录下来---小小的进步或是搞不掂的问题,希望能够抛砖引玉。
【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
实验四十七:七段LED数码管模块Seven Segment Display
七段数码管为常用显示数字的电子元件。因为借由七个发光二极管以不同组合来显示数字,所以称为七段数码管,而七划旁的点为它的“第八划”。一般的七段数码管拥有八个发光二极管用以显示十进制0至9的数字,也可以显示英文字母,包括十六进制和二十进制中的英文A至F(b,d,i为小写,其他为大写)。现时大部份的七段数码管会以斜体显示。
控制原理
七段数码管分为共阳极及共阴极,共阳极的七段数码管的正极(或阳极)为八个发光二极管的共有正极,其他接点为独立发光二极管的负极(或阴极),使用者只需把正极接电,不同的负极接地就能控制七段数码管显示不同的数字。共阴极的七段数码管与共阳极的只是接驳方法相反而已。七段数码管已可以特定的集成电路控制,只要向集成电路输入4-bit的二进制数字讯号就能控制七段数码管显示;市面上更有 8421-BCD 代码直接转为七划管控制电平的 IC,方便配合单片机使用。
驱动方式
直流驱动------是指每个数码管的每一个段码都由一个单片机的I/O端口进行驱动,或者使用如BCD码二-十进制译码器译码进行驱动。优点是编程简单,显示亮度高,缺点是占用I/O端口多。
动态显示驱动------是将所有数码管通过分时轮流控制各个数码管的的COM端,就使各个数码管轮流受控显示。将所有数码管的8个显示笔划"a,b,c,d,e,f,g,dp"的同名端连在一起,另外为每个数码管的公共极COM增加位选通控制电路,位选通由各自独立的I/O线控制,当单片机输出字形码时,所有数码管都接收到相同的字形码,但究竟是那个数码管会显示出字形,取决于单片机对位选通COM端电路的控制,所以我们只要将需要显示的数码管的选通控制打开,该位就显示出字形,没有选通的数码管就不会亮。
LED数码管简易测试方法
一个质量保证的LED数码管,其外观应该是做工精细、发光颜色均匀、无局部变色及无漏光等。对于不清楚性能好坏、产品型号及管脚排列的数码管,可采用下面介绍的简便方法进行检测。
1.干电池检测法。
如图所示,取两节普通1.5V干电池串联(3V)起来,并串联一个100Ω、1/8W的限流电阻器,以防止过电流烧坏被测LED数码管。将3V干电池的负极引线(两根引线均可接上小号鳄鱼夹)接在被测数码管的公共阴极上,正极引线依次移动接触各笔段电极(a~h脚)。当正极引线接触到某一笔段电极时,对应笔段就发光显示。用这种方法可以快速测出数码管是否有断笔(某一笔段不能显示)或连笔(某些笔段连在一起),并且可相对比较出不同的笔段发光强弱是否一致。若检测共阳极数码管,只需将电池的正、负极引线对调一下,方法同上。
如果将图中被测数码管的各笔段电极(a~h脚)全部短接起来,再接通测试用干电池,则可使被测数码管实现全笔段发光。对于质量保证的数码管,其发光颜色应该均匀,并且无笔段残缺及局部变色等。
如果不清楚被测数码管的结构类型(是共阳极还是共阴极)和引脚排序,可从被测数码管的左边第1脚开始,逆时针方向依次逐脚测试各引脚,使各笔段分别发光,即可测绘出该数码管的引脚排列和内部接线。测试时注意,只要某一笔段发光,就说明被测的两个引脚中有一个是公共脚,假定某一脚是公共脚不动,变动另一测试脚,如果另一个笔段发光,说明假定正确。这样根据公共脚所接电源的极性,可判断出被测数码管是共阳极还是共阴极。显然,公共脚如果接电池正极,则被测数码管为共阳极;公共脚如果接电池负极,则被测数码管应为共阴极。接下来测试剩余各引脚,即可很快确定出所对应的笔段来。
2.万用表检测法。
这里以MF50型指针式万用表为例,说明具体检测方法:首先,按照图所示,将指针式万用表拨至“R×10k”电阻挡。由于LED数码管内部的发光二极管正向导通电压一般≥1.8V,所以万用表的电阻档应置于内部电池电压是15V(或9V)的“R×10k”挡,而不应置于内部电池电压是1.5V的 “R×100”或“R×1k”挡,否则无法正常测量发光二极管的正、反向电阻。然后,进行检测。在测图5(b)所示的共阴极数码管时,万用表红表笔(注意:红表笔接表内电池负极、黑表笔接表内电池正极)应接数码管的“-”公共端,黑表笔则分别去接各笔段电极(a~h脚);对于共阳极的数码管,黑表笔应接数码管的“+”公共端,红表笔则分别去接a~h脚。正常情况下,万用表的指针应该偏转(一般示数在100kΩ以内),说明对应笔段的发光二极管导通,同时对应笔段会发光。若测到某个管脚时,万用表指针不偏转,所对应的笔段也不发光,则说明被测笔段的发光二极管已经开路损坏。与干电池检测法一样,采用万用表检测法也可对不清楚结构类型和引脚排序的数码管进行快速检测。
LED数码管使用常识
1.LED数码管一般要通过专门的译码驱动电路,才能正常显示字符。由于LED数码管的品种和类型繁多,所以在实际使用时应注意根据电路的不同选择不同类型的管子。例如,共阴极的LED数码管,只能接入输出为高电平的译码驱动电路;共阳极的LED数码管,只能接入输出为低电平的译码驱动电路。动态扫描显示电路的输出端,只能接多位动态LED数码管。
2.各厂家或同一厂家生产的不同型号的LED数码管,即使封装尺寸完全相同,其性能和引脚排列有可能大相径庭。反过来,功能和引脚排列相同的LED数码管,外形尺寸往往有大有小。所以选用或代换LED数码管时,只能以它的型号为根据。表3给出了国产BS×××系列LED数码管与国内外其他同类产品的直接代换型号,可供参考。
3.LED数码管属于电流控制型器件,它的发光亮度与工作电流成正比。实际使用时,每段笔划的工作电流取5~15mA(指普通小型管),这样既可保证亮度适中,延长使用寿命,又不会损坏数码管。如果在大电流下长期使用,容易使数码管亮度衰退,降低使用寿命,过大的电流(指超过内部发光二极管所允许的极限值)还会烧毁数码管。为了防止过大电流烧坏数码管,在电路中使用时一定要注意给它串联上合适的限流电阻器。
4.使用LED数码管时必须注意区分普通亮度数码管和高亮度数码管。通常情况下,用高亮度数码管可以代换现有设备上的普通亮度数码管,但反过来不能用普通亮度数码管代换高亮度数码管。这是因为普通亮度数码管的发光强度IV≥0.15mcd(毫坎),而高亮度数码管的发光强度IV≥5mcd,两者相差悬殊,并且普通亮度数码管每个笔段的工作电流≥5mA,而高亮度数码管在大约1mA的工作电流下即可发光。
5.在挑选国产BS×××系列LED数码管时,应注意产品型号标注的末位编号,以便与译码驱动电路等相匹配。通常产品末位数字是偶数的,为共阳极数码管,如BS206、BS244等;若产品末位数字是奇数,则为共阴极数码管,如BS205、BS325等。但也有个别产品例外,应注意区分。型号后缀字母 “R”,表示发红光;后缀字母“G”,表示发绿光;后缀字母“OR”,表示发橙光。
6.小型LED数码管为一次性产品,即使其中一个笔段的发光二极管在使用中损坏,也只能更换新管。曾见某图书介绍修复数码管内部损坏发光二极管的方法,笔者亲自动手实践,发现根本行不通,只会是徒劳的。因为采用环氧树脂灌封的全密封产品,外壳根本无法打开,强行用刀切割,随着面板的四分五裂,里面的电路和光导材料早已被破坏得面目全非了。
7.LED数码管除了常用的“8”字形数码管以外,较常见的还有图6所示的“±1”数字管、“N”形管和“米”字管等。其中,“±1”数字管能够显示 “+1”和“-1”,以及小数点“.”。“N”形管除了具有“8”字形数码管的功能外,还能够显示字母“N”等。“米”字管功能最全,除显示数学运算符号 “+”、“-”、“×”、“÷”之外,还可显示A~Z共26个英文字母,常用作单位符号显示。
8. LED数码管的显示面在出厂时贴有保护膜,在使用时可以撕下来。不要用尖硬物去碰触显示面,以免造成划痕等物理损伤,影响显示效果。焊接小型LED数码管宜用20W左右的小功率电烙铁,焊接时间一般不要超过3s,以免烫坏器件本身或线路板。
一位盆友送我的8个数码管
实验 接线
在该电路中,七段数码管的引脚连接到Arduino引脚2-9,如下表所示。公共引脚(引脚3和引脚8)连接到VCC,dp没有连接,因为此实验未使用dp。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | /* 【Arduino】168种传感器模块系列实验(47) 实验四十七:七段LED数码管模块 之一 在这个实验中,我们将只需逐段点亮和熄灭关闭LED,来熟悉七段数码管的工作原理 使用共阳数码管 */ void setup() { pinMode(2,OUTPUT); pinMode(3,OUTPUT); pinMode(4,OUTPUT); pinMode(5,OUTPUT); pinMode(6,OUTPUT); pinMode(7,OUTPUT); pinMode(8,OUTPUT); } void loop() { for ( int i=2;i<9;i++) { digitalWrite(i,HIGH); delay(600); } for ( int i=2;i<9;i++) { digitalWrite(i,LOW); delay(600); } delay(1000); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | /* 【Arduino】168种传感器模块系列实验(47) 实验四十七:七段LED数码管模块 之二 */ #include <reg52.h> #define LONG 50000 #define SHORT 10000 //先定义字形码,table数组中装下了自形0到9 unsigned int table[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90}; //延时函数 void delay( int i) { while (i--) { } } void main() { int i = 0; while (1) { for (i = 0; i < 10; i++) { P0 = table; delay(LONG); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | /* 【Arduino】168种传感器模块系列实验(47) 实验四十七:七段LED数码管模块 之三 */ int pinDigitron = 2; //管脚D2连接到数码管的A脚,D3连B... D9连h void setup() { for ( int x=0; x<8; x++) pinMode(pinDigitron+x, OUTPUT); //设置各脚为输出状态 } //在数码管中显示数字的函数 void displayDigit(unsigned char digit) { //定义一个数组表:不同数字的abcdefgh各段的取值 unsigned char abcdefgh[][8] = { {1,1,1,1,1,1,0,0}, //0 {0,1,1,0,0,0,0,0}, //1 {1,1,0,1,1,0,1,0}, //2 {1,1,1,1,0,0,1,0}, //3 {0,1,1,0,0,1,1,0}, //4 {1,0,1,1,0,1,1,0}, //5 {1,0,1,1,1,1,1,0}, //6 {1,1,1,0,0,0,0,0}, //7 {1,1,1,1,1,1,1,0}, //8 {1,1,1,1,0,1,1,0}, //9 {1,1,1,0,1,1,1,0}, //A {0,0,1,1,1,1,1,0}, //b {1,0,0,1,1,1,0,0}, //C {0,1,1,1,1,0,1,0}, //d {1,0,0,1,1,1,1,0}, //E {1,0,0,0,1,1,1,0}, //F }; if ( digit >= 16 ) return ; for (unsigned char x=0; x<8; x++) digitalWrite( pinDigitron + x, abcdefgh[digit][x] ); } void loop() { //在数码管中显示0-9,A-F各个数字 for ( int x=0; x<16; x++) { displayDigit(x); //调用displayDigit()子函数,显示数字 delay(1000); //等待1000毫秒 } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | /* 【Arduino】66种传感器模块系列实验(47) 实验四十七:七段LED数码管模块 之四 */ const int a = 7; //a连接到数字引脚7 const int b = 6; // b连接到数字引脚6 const int c = 5; //c 连接到数字引脚5 const int d = 11; //d连接到数字引脚11 const int e = 10; //e 连接到数字引脚 10 const int f = 8; //f 连接到数字引脚 8 const int g = 9; //g 连接到数字引脚 9 const int dp = 4; //dp 连接到数字引脚 4 void setup() { //从4到11循环,并将它们全部初始化为 输出 for ( int thisPin = 4; thisPin <= 11; thisPin++) { pinMode(thisPin, OUTPUT); } digitalWrite(dp, LOW); //从4到11循环,并将它们全部输出 } /*********以下为数码管 1-f 的显示函数*********/ void digital_1( void ) //显示 1 函数 { digitalWrite(c, HIGH); //数码管c段为高电平 digitalWrite(b, HIGH); //数码管b段为高电平 for ( int j = 7; j <= 11; j++) //数码管其余段为低电平 digitalWrite(j, LOW); } void digital_2( void ) { digitalWrite(b, HIGH); digitalWrite(a, HIGH); for ( int j = 9; j <= 11; j++) digitalWrite(j, HIGH); digitalWrite(c, LOW); digitalWrite(f, LOW); } void digital_3( void ) { unsigned char j; digitalWrite(g, HIGH); digitalWrite(d, HIGH); for (j = 5; j <= 7; j++) digitalWrite(j, HIGH); digitalWrite(f, LOW); digitalWrite(e, LOW); } void digital_4( void ) { digitalWrite(c, HIGH); digitalWrite(b, HIGH); digitalWrite(f, HIGH); digitalWrite(g, HIGH); digitalWrite(a, LOW); digitalWrite(e, LOW); digitalWrite(d, LOW); } void digital_5( void ) { unsigned char j; for (j = 7; j <= 9; j++) digitalWrite(j, HIGH); digitalWrite(c, HIGH); digitalWrite(d, HIGH); digitalWrite(b, LOW); digitalWrite(e, LOW); } void digital_6( void ) { unsigned char j; for (j = 7; j <= 11; j++) digitalWrite(j, HIGH); digitalWrite(c, HIGH); digitalWrite(b, LOW); } void digital_7( void ) { unsigned char j; for (j = 5; j <= 7; j++) digitalWrite(j, HIGH); for (j = 8; j <= 11; j++) digitalWrite(j, LOW); } void digital_8( void ) { unsigned char j; for (j = 5; j <= 11; j++) digitalWrite(j, HIGH); } void digital_9( void ) { unsigned char j; for (j = 5; j <= 9; j++) digitalWrite(j, HIGH); digitalWrite(d, LOW); digitalWrite(e, LOW); } void digital_A( void ) { unsigned char j; for (j = 5; j <= 10; j++) digitalWrite(j, HIGH); digitalWrite(d, LOW); } void digital_b( void ) { unsigned char j; for (j = 7; j <= 11; j++) digitalWrite(j, HIGH); digitalWrite(a, LOW); digitalWrite(b, LOW); } void digital_C( void ) { digitalWrite(a, HIGH); digitalWrite(b, LOW); digitalWrite(c, LOW); digitalWrite(d, HIGH); digitalWrite(e, HIGH); digitalWrite(f, HIGH); digitalWrite(g, LOW); } void digital_d( void ) { unsigned char j; digitalWrite(a, LOW); digitalWrite(f, LOW); digitalWrite(b, HIGH); digitalWrite(c, HIGH); digitalWrite(j, HIGH); for (j = 9; j <= 11; j++) digitalWrite(j, HIGH); } void digital_E( void ) { unsigned char j; digitalWrite(b, LOW); digitalWrite(c, LOW); for (j = 7; j <= 11; j++) digitalWrite(j, HIGH); } void digital_F( void ) { unsigned char j; digitalWrite(b, LOW); digitalWrite(c, LOW); digitalWrite(d, LOW); for (j = 7; j <= 10; j++) digitalWrite(j, HIGH); } void loop() { digital_1(); //显示1 delay(1000); //延时1秒 digital_2(); //显示2 delay(1000); digital_3(); //显示3 delay(1000); digital_4(); //显示4 delay(1000); digital_5(); //显示5 delay(1000); digital_6(); //显示6 delay(1000); digital_7(); //显示7 delay(1000); digital_8(); //显示8 delay(1000); digital_9(); //显示9 delay(1000); digital_A(); //显示a delay(1000); digital_b(); //显示b delay(1000); digital_C(); //显示c delay(1000); digital_d(); //显示d delay(1000); digital_E(); //显示e delay(1000); digital_F(); //显示f delay(1000); } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性