项目8(任务10)利用四位数码管实现动态扫描显示(三)
2019-06-08 本文已影响5人
0214_王一铭
在之前的四位数码管的显示原理学习的基础上,本篇介绍的是利用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]);
}
四、代码分析
- 首先,定义数码管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
- 定义一个可以查询的码值表,因为使用的是共阴四位数码管,用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
};
- 利用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);
}
- 定义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在循环显示,只是速度太快,产生视觉暂留效应给我们的眼睛产生了错觉。