弘毅 发表于 2011-8-6 08:23:36

arduino学习笔记13 - 4位数码管实验


这次我们进行的实验是使用arduino驱动一块共阳四位数码管。驱动数码管限流电阻肯定是必不可少的,限流电阻有两种接法,一种是在d1-d4阳极接,总共接4颗。这种接法好处是需求电阻比较少,但是会产生每一位上显示不同数字亮度会不一样,1最亮,8最暗。另外一种接法就是在其他8个引脚上接,这种接法亮度显示均匀,但是用电阻较多。本次实验使用8颗220Ω电阻(因为没有100Ω电阻,所以使用220Ω的代替,100欧姆亮度会比较高)。

下图为4位数码管



4位数码管总共有12个引脚,小数点朝下正放在面前时,左下角为1,其他管脚顺序为逆时针旋转。左上角为最大的12号管脚。



下图为数码管的说明手册



下面是硬件连接图





把下面的代码复制下载到控制板中,看看效果。
//设置阴极接口
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;
int f = 6;
int g = 7;
int p = 8;
//设置阳极接口
int d4 = 9;
int d3 = 10;
int d2 = 11;
int d1 = 12;
//设置变量
int del = 100;
int buttoncount = 0;
int loopcount = 0;

void setup()
{
pinMode(d1, OUTPUT);
pinMode(d2, OUTPUT);
pinMode(d3, OUTPUT);
pinMode(d4, OUTPUT);
pinMode(a, OUTPUT);
pinMode(b, OUTPUT);
pinMode(c, OUTPUT);
pinMode(d, OUTPUT);
pinMode(e, OUTPUT);
pinMode(f, OUTPUT);
pinMode(g, OUTPUT);
pinMode(p, OUTPUT);
digitalWrite(a, HIGH);
digitalWrite(b, HIGH);
digitalWrite(c, HIGH);
digitalWrite(d, HIGH);
digitalWrite(e, HIGH);
digitalWrite(f, HIGH);
digitalWrite(g, HIGH);
digitalWrite(p, HIGH);
}

void loop()
{
roulette(4);//轮转效果
delay(100);
zigzag(2);    //Z字型效果
delay(100);
circles(4);   //圈状效果
delay(100);
}

void pickDigit(int x)//定义pickDigit(x),其作用是开启dx端口
{
digitalWrite(d1, LOW);
digitalWrite(d2, LOW);
digitalWrite(d3, LOW);
digitalWrite(d4, LOW);

switch(x)
{
case 1:
    digitalWrite(d1, HIGH);
    break;
case 2:
    digitalWrite(d2, HIGH);
    break;
case 3:
    digitalWrite(d3, HIGH);
    break;
default:
    digitalWrite(d4, HIGH);
    break;
}
}

void clearLEDs()//清屏
{
digitalWrite(a, HIGH);
digitalWrite(b, HIGH);
digitalWrite(c, HIGH);
digitalWrite(d, HIGH);
digitalWrite(e, HIGH);
digitalWrite(f, HIGH);
digitalWrite(g, HIGH);
digitalWrite(p, HIGH);
}

void roulette(int x)//设置轮转效果
{
loopcount = 0;
while (loopcount < x)
{
    digitalWrite(a, LOW);
    pickDigit(1);
    delay(del);
    pickDigit(2);
    delay(del);
    pickDigit(3);
    delay(del);
    pickDigit(4);
    delay(del);
    digitalWrite(a, HIGH);
    digitalWrite(b, LOW);
    delay(del);
    digitalWrite(b, HIGH);
    digitalWrite(c, LOW);
    delay(del);
    digitalWrite(c, HIGH);
    digitalWrite(d, LOW);
    delay(del);
    pickDigit(3);
    delay(del);
    pickDigit(2);
    delay(del);
    pickDigit(1);
    delay(del);
    digitalWrite(d, HIGH);
    digitalWrite(e, LOW);
    delay(del);
    digitalWrite(e, HIGH);
    digitalWrite(f, LOW);
    delay(del);
    clearLEDs();
    loopcount++;
}
}

void zigzag(int x)//设置Z字形效果
{
loopcount = 0;
while(loopcount < x)
{
    digitalWrite(a, LOW);
    pickDigit(1);
    delay(del);
    pickDigit(2);
    delay(del);
    pickDigit(3);
    delay(del);
    pickDigit(4);
    delay(del);
    digitalWrite(a, HIGH);
    digitalWrite(b, LOW);
    delay(del);
    digitalWrite(b, HIGH);
    digitalWrite(g, LOW);
    delay(del);
    pickDigit(3);
    delay(del);
    pickDigit(2);
    delay(del);
    pickDigit(1);
    delay(del);
    digitalWrite(g, HIGH);
    digitalWrite(e, LOW);
    delay(del);
    digitalWrite(e, HIGH);
    digitalWrite(d, LOW);
    delay(del);
    pickDigit(2);
    delay(del);
    pickDigit(3);
    delay(del);
    pickDigit(4);
    delay(del);
    digitalWrite(d, HIGH);
    digitalWrite(c, LOW);
    delay(del);
    digitalWrite(c, HIGH);
    digitalWrite(g, LOW);
    delay(del);
    pickDigit(3);
    delay(del);
    pickDigit(2);
    delay(del);
    pickDigit(1);
    delay(del);
    digitalWrite(g, HIGH);
    digitalWrite(f, LOW);
    delay(del);
    clearLEDs();
    loopcount++;
}
}

void circles(int x)//设置圈状效果
{
loopcount = 0;
while (loopcount < x)
{
    digitalWrite(a, LOW);
    digitalWrite(b, LOW);
    digitalWrite(f, LOW);
    digitalWrite(g, LOW);
    pickDigit(1);
    delay(250);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(c, LOW);
    digitalWrite(d, LOW);
    digitalWrite(e, LOW);
    pickDigit(2);
    delay(250);
    digitalWrite(a, LOW);
    digitalWrite(b, LOW);
    digitalWrite(f, LOW);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(e, HIGH);
    pickDigit(3);
    delay(250);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(c, LOW);
    digitalWrite(d, LOW);
    digitalWrite(e, LOW);
    pickDigit(4);
    delay(250);
    clearLEDs();
    loopcount++;
}
}
上面代码效果如下,为3种花样组成。

http://player.youku.com/player.php/sid/XMjkyMDU4OTc2/v.swf

再把下面代码复制下载到控制板中,看看效果。
//设置阴极接口
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;
int f = 6;
int g = 7;
int p = 8;
//设置阳极接口
int d4 = 9;
int d3 = 10;
int d2 = 11;
int d1 = 12;
//设置变量
long n = 0;
int x = 100;
int del = 55;//此处数值对时钟进行微调

void setup()
{
pinMode(d1, OUTPUT);
pinMode(d2, OUTPUT);
pinMode(d3, OUTPUT);
pinMode(d4, OUTPUT);
pinMode(a, OUTPUT);
pinMode(b, OUTPUT);
pinMode(c, OUTPUT);
pinMode(d, OUTPUT);
pinMode(e, OUTPUT);
pinMode(f, OUTPUT);
pinMode(g, OUTPUT);
pinMode(p, OUTPUT);
}

void loop()
{
clearLEDs();
pickDigit(1);
pickNumber((n/x/1000)%10);
delayMicroseconds(del);

clearLEDs();
pickDigit(2);
pickNumber((n/x/100)%10);
delayMicroseconds(del);

clearLEDs();
pickDigit(3);
dispDec(3);
pickNumber((n/x/10)%10);
delayMicroseconds(del);

clearLEDs();
pickDigit(4);
pickNumber(n/x%10);
delayMicroseconds(del);

n++;

if (digitalRead(13) == HIGH)
{
    n = 0;
}
}

void pickDigit(int x)//定义pickDigit(x),其作用是开启dx端口
{
digitalWrite(d1, LOW);
digitalWrite(d2, LOW);
digitalWrite(d3, LOW);
digitalWrite(d4, LOW);

switch(x)
{
case 1:
    digitalWrite(d1, HIGH);
    break;
case 2:
    digitalWrite(d2, HIGH);
    break;
case 3:
    digitalWrite(d3, HIGH);
    break;
default:
    digitalWrite(d4, HIGH);
    break;
}
}

void pickNumber(int x)   //定义pickNumber(x),其作用是显示数字x
{
switch(x)
{
default:
    zero();
    break;
case 1:
    one();
    break;
case 2:
    two();
    break;
case 3:
    three();
    break;
case 4:
    four();
    break;
case 5:
    five();
    break;
case 6:
    six();
    break;
case 7:
    seven();
    break;
case 8:
    eight();
    break;
case 9:
    nine();
    break;
}
}

void dispDec(int x)//设定开启小数点
{
digitalWrite(p, LOW);
}

void clearLEDs()//清屏
{
digitalWrite(a, HIGH);
digitalWrite(b, HIGH);
digitalWrite(c, HIGH);
digitalWrite(d, HIGH);
digitalWrite(e, HIGH);
digitalWrite(f, HIGH);
digitalWrite(g, HIGH);
digitalWrite(p, HIGH);
}

void zero()//定义数字0时阴极那些管脚开关
{
digitalWrite(a, LOW);
digitalWrite(b, LOW);
digitalWrite(c, LOW);
digitalWrite(d, LOW);
digitalWrite(e, LOW);
digitalWrite(f, LOW);
digitalWrite(g, HIGH);
}

void one()//定义数字1时阴极那些管脚开关
{
digitalWrite(a, HIGH);
digitalWrite(b, LOW);
digitalWrite(c, LOW);
digitalWrite(d, HIGH);
digitalWrite(e, HIGH);
digitalWrite(f, HIGH);
digitalWrite(g, HIGH);
}

void two()//定义数字2时阴极那些管脚开关
{
digitalWrite(a, LOW);
digitalWrite(b, LOW);
digitalWrite(c, HIGH);
digitalWrite(d, LOW);
digitalWrite(e, LOW);
digitalWrite(f, HIGH);
digitalWrite(g, LOW);
}

void three()//定义数字3时阴极那些管脚开关
{
digitalWrite(a, LOW);
digitalWrite(b, LOW);
digitalWrite(c, LOW);
digitalWrite(d, LOW);
digitalWrite(e, HIGH);
digitalWrite(f, HIGH);
digitalWrite(g, LOW);
}

void four()//定义数字4时阴极那些管脚开关
{
digitalWrite(a, HIGH);
digitalWrite(b, LOW);
digitalWrite(c, LOW);
digitalWrite(d, HIGH);
digitalWrite(e, HIGH);
digitalWrite(f, LOW);
digitalWrite(g, LOW);
}

void five()//定义数字5时阴极那些管脚开关
{
digitalWrite(a, LOW);
digitalWrite(b, HIGH);
digitalWrite(c, LOW);
digitalWrite(d, LOW);
digitalWrite(e, HIGH);
digitalWrite(f, LOW);
digitalWrite(g, LOW);
}

void six()//定义数字6时阴极那些管脚开关
{
digitalWrite(a, LOW);
digitalWrite(b, HIGH);
digitalWrite(c, LOW);
digitalWrite(d, LOW);
digitalWrite(e, LOW);
digitalWrite(f, LOW);
digitalWrite(g, LOW);
}

void seven()//定义数字7时阴极那些管脚开关
{
digitalWrite(a, LOW);
digitalWrite(b, LOW);
digitalWrite(c, LOW);
digitalWrite(d, HIGH);
digitalWrite(e, HIGH);
digitalWrite(f, HIGH);
digitalWrite(g, HIGH);
}

void eight()//定义数字8时阴极那些管脚开关
{
digitalWrite(a, LOW);
digitalWrite(b, LOW);
digitalWrite(c, LOW);
digitalWrite(d, LOW);
digitalWrite(e, LOW);
digitalWrite(f, LOW);
digitalWrite(g, LOW);
}

void nine()//定义数字9时阴极那些管脚开关
{
digitalWrite(a, LOW);
digitalWrite(b, LOW);
digitalWrite(c, LOW);
digitalWrite(d, LOW);
digitalWrite(e, HIGH);
digitalWrite(f, LOW);
digitalWrite(g, LOW);
}
下面的代码与上面的效果一样,但是使用了数组方法进行简写,大家对比一下看看哪里不易一样。//设置阴极接口
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;
int f = 6;
int g = 7;
int p = 8;
//设置阳极接口
int d4 = 9;
int d3 = 10;
int d2 = 11;
int d1 = 12;
//设置变量
long n = 0;
int x = 100;
int del = 55;//此处数值对时钟进行微调

byte segs = { a, b, c, d, e, f, g };

byte seven_seg_digits = { { 0,0,0,0,0,0,1 },// = 0
                                 { 1,0,0,1,1,1,1 },// = 1
                                 { 0,0,1,0,0,1,0 },// = 2
                                 { 0,0,0,0,1,1,0 },// = 3
                                 { 1,0,0,1,1,0,0 },// = 4
                                 { 0,1,0,0,1,0,0 },// = 5
                                 { 0,1,0,0,0,0,0 },// = 6
                                 { 0,0,0,1,1,1,1 },// = 7
                                 { 0,0,0,0,0,0,0 },// = 8
                                 { 0,0,0,0,1,0,0 }   // = 9
                           };

void setup()
{
pinMode(d1, OUTPUT);
pinMode(d2, OUTPUT);
pinMode(d3, OUTPUT);
pinMode(d4, OUTPUT);
pinMode(a, OUTPUT);
pinMode(b, OUTPUT);
pinMode(c, OUTPUT);
pinMode(d, OUTPUT);
pinMode(e, OUTPUT);
pinMode(f, OUTPUT);
pinMode(g, OUTPUT);
pinMode(p, OUTPUT);
}

void loop()
{
clearLEDs();
pickDigit(1);
lightSegments((n/x/1000)%10);
delayMicroseconds(del);

clearLEDs();
pickDigit(2);
lightSegments((n/x/100)%10);
delayMicroseconds(del);

clearLEDs();
pickDigit(3);
dispDec(3);
lightSegments((n/x/10)%10);
delayMicroseconds(del);

clearLEDs();
pickDigit(4);
lightSegments(n/x%10);
delayMicroseconds(del);

n++;

if (digitalRead(13) == HIGH)
{
    n = 0;
}
}

void pickDigit(int x)//定义pickDigit(x),其作用是开启dx端口
{
digitalWrite(d1, LOW);
digitalWrite(d2, LOW);
digitalWrite(d3, LOW);
digitalWrite(d4, LOW);

switch(x)
{
case 1:
    digitalWrite(d1, HIGH);
    break;
case 2:
    digitalWrite(d2, HIGH);
    break;
case 3:
    digitalWrite(d3, HIGH);
    break;
default:
    digitalWrite(d4, HIGH);
    break;
}
}

void dispDec(int x)//设定开启小数点
{
digitalWrite(p, LOW);
}

void clearLEDs()//清屏
{
digitalWrite(a, HIGH);
digitalWrite(b, HIGH);
digitalWrite(c, HIGH);
digitalWrite(d, HIGH);
digitalWrite(e, HIGH);
digitalWrite(f, HIGH);
digitalWrite(g, HIGH);
digitalWrite(p, HIGH);
}


// 点亮对应数字的数码管
void lightSegments(int x) {
for (int i = 0; i < 7; i++) {
    digitalWrite(segs, seven_seg_digits);
}
}
此代码为简易的秒表,效果如下,精准度不是很高,需要大家微调参数。

http://player.youku.com/player.php/sid/XMjkyMDU4OTgw/v.swf

悠然小调 发表于 2011-8-6 09:59:04

关注中:lol:lol

悠然小调 发表于 2011-8-8 16:45:41

本帖最后由 悠然小调 于 2011-8-8 21:11 编辑

n/x/1000)%10这没看懂,开始时n=0


悠然小调 发表于 2011-8-8 21:16:47

把最后一个程序缩一下,不知道是否正确。//设置变量
long n = 0;
int x = 100;
int del = 55;//此处数值对时钟进行微调
Byte pin={12,11,10,9}                     //设置阳极接口:d1接12; d2接11; d3接10; d4接9
byte segs = { 1, 2, 3, 4, 5 ,6, 7 };    //设置阴极接口:a接 1; b接 2; c 接 3; d 接 4; e接 5; f接 6; g接 7; p 接 8;

byte seven_seg_digits = {   { 0,0,0,0,0,0,1 },// = 0
                           { 1,0,0,1,1,1,1 },// = 1
                           { 0,0,1,0,0,1,0 },// = 2
                           { 0,0,0,0,1,1,0 },// = 3
                           { 1,0,0,1,1,0,0 },// = 4
                           { 0,1,0,0,1,0,0 },// = 5
                           { 0,1,0,0,0,0,0 },// = 6
                           { 0,0,0,1,1,1,1 },// = 7
                           { 0,0,0,0,0,0,0 },// = 8
                           { 0,0,0,0,1,0,0 }   // = 9
                           };

void setup()
{for(int i=1,i<12,i++)
{pinMode(i, OUTPUT); }
}

void loop()
{
   int shu;
   for (int k=0,k<3,k++)
    {
      clearLEDs();
      digitalWrite(pin,HIGH);
      shu=n/k%10;
      for (int i = 0; i < 7; i++)
   {
       digitalWrite(segs, seven_seg_digits );
            if (k==2)
         { digitalWrite(p, LOW); }
       }
   delayMicroseconds(del);
}
         n++;
    if (digitalRead(13) == HIGH)
{n = 0;}
}

void clearLEDs()//清屏
{
   for (int j=1,j<12,j++)
    {
      digitalWrite( j, HIGH);
   }
}

━__Neo_ˇ 发表于 2011-8-9 09:36:11

:D 嘿嘿嘿嘿

渤海渔翁 发表于 2011-8-18 18:03:40

我的数码管没有说明书,几个脚还没分清:dizzy:

悠然小调 发表于 2011-8-21 07:48:49

用万用表量量

プ汏坏疍 发表于 2011-12-14 14:11:29

呵呵,用arduino这样玩数码管,真的很神!赞一下!

幻生幻灭 发表于 2012-5-10 13:38:59

弘毅,你太耐亲了!你都可以出书了!

xzmoji 发表于 2012-7-3 07:56:56

跟2楼一样,我也没看懂(n/x/1000)%10

xzmoji 发表于 2012-7-3 08:57:56

我终于知道了,数码管在同一时刻4位只能显示同一数字,即1111、2222……,如果要显示1324,就要
①先关第2~4位,第1位显示“1”,延时。
①先关第1、3、4位,第2位显示“3”,延时。
①先关第1、2、4位,第3位显示“2”,延时。
①先关第1~3位,第4位显示“4”,延时。
调节延时的时间,让人眼分辨不出它在闪烁。
我的理解对吗?斑竹

bigtreelbq 发表于 2012-7-6 14:03:17

用analogwrite不就可以去掉电阻吗

骷髅 发表于 2012-9-9 10:20:53

悠然小调 发表于 2011-8-8 16:45 static/image/common/back.gif
n/x/1000)%10这没看懂,开始时n=0

求解,这句的意思看懂没有呢

hk386 发表于 2012-10-8 17:40:11

斑竹啊,数字脚一般的0 1不是不用做输出的吗,这次怎么用了

弘毅 发表于 2012-10-8 17:50:06

hk386 发表于 2012-10-8 17:40 static/image/common/back.gif
斑竹啊,数字脚一般的0 1不是不用做输出的吗,这次怎么用了

额。。。当年不知道模拟口可以当数字口用。。。端口不够用,所以就都用了。其实。。可以用A0,A1等。。。
页: [1] 2 3 4
查看完整版本: arduino学习笔记13 - 4位数码管实验