学习Arduino:四位数码管的使用心得

本程序的功能:调整电位计,使得Arduino获取的电位计的数值实时的显示在四位数码管上。

当然,可以将电位计换做任意模拟输入器件均可,有的也只需相应的在读取数据和给val赋值上做些稍许改变。你可以将电位计换成火焰传感器、距离传感器、温度传感器、光敏电阻等等来让数码管显示数字。

比如用 LM35 传感器来读取温度的时候,让val的值为最终换算出来的温度即可,甚至可以让个位显示一个C或F表示是摄氏度还是华氏温度。只需要稍微修改一下本代码即可。

首先说说什么是共阴极和共阳极。共阴极是指数码管中所有控制数字显示的针脚分别接到阳极上,输出电平是高(HIGH)时亮,是低(LOW)时灭。共阳极与之相反,输出电平是高(HIGH)时灭,是低(LOW)时却亮。

我用的 5461AS 型四位数码管,它是共阴极数码管(对应的5461BS型为共阳极型)。即按照上面的说法,所有控制数字的针脚是高(HIGH) 时就亮。

不同款式的数码管阵脚也许不同,因此本文的接线方法不一定适用于任何四位数码管,您在使用之前应该知道所用数码管的针脚分布。5461AS 型四位数码管的电路原理图如下:

5461AS 电路图

从图中可以看到 12、9、8、6 针脚控制着千位、百位、十位、个位(这里分别编号1、2、3、4位,后文要用到)的数码管的亮与灭。剩下的针脚用数字注明了。虽然从电路图上看针脚排列很无规律,但是物理元件上的针脚分布却很简单,见下图。将数码管正面朝向自己,正放(小数点显示在右下方),那么针脚的分布将如下图所示(左下角为1,逆时针方向旋转一周则转到针脚12。即左下角为1,右下角为6,右上角为7,左上角为12)。如果你不想记住,可以用记号笔在数码管的侧面写上针脚,方便以后使用。

V90VO

四位数码管是怎么同时显示数字的呢?答案其实很简单,它仍旧是一个数码管一个数码管的显示,只是变换太快,人眼看起来好像是同时在亮。本程序是从千位到个位先后进行显示的,每个数码管的显示时间设置为5000微秒,即5毫秒。程序中设置为微秒是为了更方便的微调,您也可以选择自己的合适的延迟时间。

根据针脚的分布,我们现在接线。

我们首先接数码管。

经过测试,数字针脚0,1不应该被使用。因为如果要做串口通信的话,这里的信号会影响数字的显示,使得这里的针脚一直有高低电平的交替,灯管会被交替点亮,看起来也比别的灯管稍微暗一点,而且一直都是这样的亮度。因此我们舍弃这两个针脚。

这里设定数字针脚2至8分别接上四位数码管的a至g,9接上小数点dp。DIG1至DIG4分别接到数字针脚13、12、11和10上。为什么是不按顺序接呢?因为Arduino的数字针脚是从右到左,而数码管的DIG针脚确实从左到右排的。当然也可以接为同一方向,无非就是自己把DIG1当DIG4换着用就好。不过这样下去个人觉得比较容易引起混淆,我就按照刚才的接法继续。

在2至9的八个线之间我们应该串联上100到220欧姆的电阻,既可以使得数码管的亮度比较合适,又可以保护数码管。

数码管接好之后,我们接电位计。

电位计的接法很简单。由于其实质上是电阻,因此不分正负极,正负极随便接就好。我们把5V电源接到电位计的右端,GND接到电位计的左端,将模拟针脚A0接到电位计的中间,这样Arduino就可以将电位计的数值通过模拟针脚Ao读取进来,交给数码管去显示。

接完线后的实物图如下:

lsjy1-1

接下来就是程序部分。

完整的程序如下:

[cc lang=”java”]

/* 四位数码管的可控显示
** 注意,使用的5461AS是共阴极的,如果您是共阳极的需要注意某些部分的HIGH与LOW的替换
** 作者:TAHO
** 版本:1.0
** 时间:2013.07.12
** 博客:http://blog.tahoroom.com
*/

//设置阳极接口
//D1口用来做串口数据传输(TX)
int a = 2;//D0,D1口在本程序中用来数据传出传入,不能当作数字针脚使用。
int b = 3;
int c = 4;
int d = 5;
int e = 6;
int f = 7;
int g = 8;
int p = 9;//小数点
//设置阴极接口(控制1、2、3、4数码管的亮与灭)
int d1 = 13;//千位
int d2 = 12;//百位
int d3 = 11;//十位
int d4 = 10;//个位
//设置变量
int del = 5000; //此数值可用于对时钟进行微调
int changepin = A0;//从A0口输入电位计数据
int val=0;//接收从A0口获得的电位计数值
int val4=0; //千位上的数字,即DIG1上的数字,对应针脚为d1,Arduino上的针脚为13
int val3=0; //百位上的数字,即DIG2上的数字,对应针脚为d2,Arduino上的针脚为12
int val2=0; //十位上的数字,即DIG3上的数字,对应针脚为d3,Arduino上的针脚为11
int val1=0; //个位上的数字,即DIG4上的数字,对应针脚为d4,Arduino上的针脚为10

void setup()
{
Serial.begin(9600);//设置串口通信速率为9600

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()
{
val=analogRead(changepin);//读取电位计数值并赋给val
Serial.println(val);//从串口中输出val的值
for(int i=0;i<25;i++)//为了让数字不要那么灵敏的变来变去,给他循环25次恰好满足我的需求 { //条件判断,根据val的位数分别显示 if(val>=1000)//四位数
{
//注意,这里用使用了两种取某一位上的数字的算法,我只是想试试两种算法是否都好用
val4=(val/1000)%10; /*比如1023除以1000等于1.023,
取整数得到1,此即为千位上的数字,此为第一种算法,简单.*/
val3=( val-((val/1000)%10*1000) )/100%10; /*比如523减去523除以100等于5.23,取整后乘以100得到500,
用523减去500得到23,再除以10得到2.3,取整后得到2,
此为百位上的数字,此为第二章算法,稍显复杂,不过用起来也可以*/
val2=(val-val/100%10*100)/10%10;
val1= val-val/10%10*10-val/1000%10*1000;

clearLEDs();
pickDigit(1);
pickNumber(val1);
delayMicroseconds(del);

clearLEDs();
pickDigit(2);
pickNumber(val2);
delayMicroseconds(del);

clearLEDs();
pickDigit(3);
pickNumber(val3);
delayMicroseconds(del);

clearLEDs();
pickDigit(4);
pickNumber(val4);
delayMicroseconds(del);
}
else if(val>=100 && val<1000)//三位数 { val3=(val/100)%10; val2=((val-(((val/100)%10)*100))/10)%10; val1=val-((val/100)%10)*100-((((val-((val/100)%10)*100)/10)%10)*10); clearLEDs(); pickDigit(1); pickNumber(val1); delayMicroseconds(2*del); clearLEDs(); pickDigit(2); pickNumber(val2); delayMicroseconds(del); clearLEDs(); pickDigit(3); pickNumber(val3); delayMicroseconds(del); } else if(val>=10 && val<100)//两位数 { val2=(val/10)%10; val1=val-(((val/10)%10)*10); clearLEDs(); pickDigit(1); pickNumber(val1); delayMicroseconds(del); clearLEDs(); pickDigit(2); pickNumber(val2); delayMicroseconds(del); } else if(val>=0 && val<10)//一位数 { val1=val; clearLEDs(); pickDigit(1); pickNumber(val1); delayMicroseconds(del); } } } void pickDigit(int x) //定义pickDigit(x),其作用是开启dx端口 { digitalWrite(d1, HIGH); digitalWrite(d2, HIGH); digitalWrite(d3, HIGH); digitalWrite(d4, HIGH); if(x==1) { digitalWrite(d4, LOW); } else if(x==2) { digitalWrite(d3, LOW); } else if(x==3) { digitalWrite(d2, LOW); } else if(x==4) { digitalWrite(d1, LOW); } } 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 clearLEDs() //清屏 { digitalWrite(a, LOW); digitalWrite(b, LOW); digitalWrite(c, LOW); digitalWrite(d, LOW); digitalWrite(e, LOW); digitalWrite(f, LOW); digitalWrite(g, LOW); digitalWrite(p, LOW); } /* 下面实现数字0到9以及小数点dp的显示,你也可以使用二维数组来实现这一部分, 详情请看我另一片博文:http://tahoroom.sinaapp.com/archives/5790.html */ void zero() //定义数字0时各阳极针脚的开关 { digitalWrite(a, HIGH); digitalWrite(b, HIGH); digitalWrite(c, HIGH); digitalWrite(d, HIGH); digitalWrite(e, HIGH); digitalWrite(f, HIGH); digitalWrite(g, LOW); } void one() //定义数字1时各阳极针脚的开关 { digitalWrite(a, LOW); digitalWrite(b, HIGH); digitalWrite(c, HIGH); digitalWrite(d, LOW); digitalWrite(e, LOW); digitalWrite(f, LOW); digitalWrite(g, LOW); } void two() //定义数字2时各阳极针脚的开关 { digitalWrite(a, HIGH); digitalWrite(b, HIGH); digitalWrite(c, LOW); digitalWrite(d, HIGH); digitalWrite(e, HIGH); digitalWrite(f, LOW); digitalWrite(g, HIGH); } void three() //定义数字3时各阳极针脚的开关 { digitalWrite(a, HIGH); digitalWrite(b, HIGH); digitalWrite(c, HIGH); digitalWrite(d, HIGH); digitalWrite(e, LOW); digitalWrite(f, LOW); digitalWrite(g, HIGH); } void four() //定义数字4时各阳极针脚的开关 { digitalWrite(a, LOW); digitalWrite(b, HIGH); digitalWrite(c, HIGH); digitalWrite(d, LOW); digitalWrite(e, LOW); digitalWrite(f, HIGH); digitalWrite(g, HIGH); } void five() //定义数字5时各阳极针脚的开关 { digitalWrite(a, HIGH); digitalWrite(b, LOW); digitalWrite(c, HIGH); digitalWrite(d, HIGH); digitalWrite(e, LOW); digitalWrite(f, HIGH); digitalWrite(g, HIGH); } void six() //定义数字6时各阳极针脚的开关 { digitalWrite(a, HIGH); digitalWrite(b, LOW); digitalWrite(c, HIGH); digitalWrite(d, HIGH); digitalWrite(e, HIGH); digitalWrite(f, HIGH); digitalWrite(g, HIGH); } void seven() //定义数字7时各阳极针脚的开关 { digitalWrite(a, HIGH); digitalWrite(b, HIGH); digitalWrite(c, HIGH); digitalWrite(d, LOW); digitalWrite(e, LOW); digitalWrite(f, LOW); digitalWrite(g, LOW); } void eight() //定义数字8时各阳极针脚的开关 { digitalWrite(a, HIGH); digitalWrite(b, HIGH); digitalWrite(c, HIGH); digitalWrite(d, HIGH); digitalWrite(e, HIGH); digitalWrite(f, HIGH); digitalWrite(g, HIGH); } void nine() //定义数字9时各阳极针脚的开关 { digitalWrite(a, HIGH); digitalWrite(b, HIGH); digitalWrite(c, HIGH); digitalWrite(d, HIGH); digitalWrite(e, LOW); digitalWrite(f, HIGH); digitalWrite(g, HIGH); } void dpoint() //点亮小数点 { digitalWrite(p, HIGH); } [/cc]

2条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注