【项目15-任务19-小组20】四位数码管显示时间
需要的组件
4位7段数码管
74HC595
DS3231 RTC模块
Arduino UNO
面包板
连接跳线
四位七段数码管
四位七段数码管有四个七段数码管连接在一起。它们用于显示数值以及一些带小数和冒号的字母。显示屏可以双向使用。四位数码管可用于制作数字时钟或类似于0到9999之间的计数器。下面是四位七段数码管的内部图。
每个部分都有一个带独立控制的LED。七段数码管显示有两种类型,共阳极和共阴极。上图显示了共阳极七段数码管。
共阳极
在共阳极中,所有8个LED的所有正极(阳极)连接在一起,命名为COM。并且所有负极端都保持断开或连接到微控制器引脚。通过使用微控制器,逻辑低电平用于点亮特定LED段,逻辑高电平熄灭LED。
74HC595移位寄存器IC
74HC595也称为8位串行输入 - 并行输出移位寄存器。该IC可以串行接收数据输入,并行控制8个输出引脚。这对于减少微控制器使用的引脚非常有用。
74HC595 IC的工作原理:
该IC使用三个引脚(如时钟、数据和锁存器)与微控制器来控制IC的8个输出引脚。时钟用于连续提供来自微控制器的脉冲,数据引脚用于发送数据,例如在相应的时钟时间需要将输出打开或关闭的数据。
DS3231 RTC模块
DS3231是一款RTC模块。 RTC代表实时时钟。即使电路未通电,该模块也用于记住时间和日期。它有一个备用电池CR2032,可在没有外部电源的情况下运行模块。该模块还包括温度传感器。该模块可用于嵌入式项目,如制作带温度指示器的数字时钟等.
该模块的一些功能和参数:
RTC,计算秒、分、小时和年
数字温度传感器,精度为±3ºC
400Khz I2C接口
功耗低
CR2032备用电池,具有两到三年的使用寿命
工作电压:2.3至5.5V
电路原理图
DS3231 RTC和Arduino UNO之间的电路连接:
编程Arduino UNO
在本文的末尾处给出了完整的代码。在编程部分中,将说明如何以24小时格式从RTC模块获取时间(小时和分钟),然后将其转换成用于在4位7段显示中显示它们的相应格式。
要将DS3231 RTC模块与Arduino UNO连接,使用Arduino UNO的I2C总线。程序中包含一个名为的库,用于访问设置和读取时间、日期、温度数据等功能。下载DS3231 RTC模块Arduino库。由于RTC模块使用I2C接口,因此程序中也使用库。
在本文中,小时和分钟首先从RTC获取,它们像0930(09:30 pm)一样被组合在一起然后将各个数字分开,如千、百、十、单位,并且把各个数字转换成二进制格式,如0到63(0111111)。将该二进制代码发送到移位寄存器,然后从移位寄存器发送到七段,成功地在七段显示中显示数字0。这样,四位数码管姐可以显示小时和分钟。
首先,包括必要的库,例如DS3231库和Wire库(I2C库)。
#include
#include<DS3231.h>
定义控制七段数码管的引脚。这些控制将在复用数码管中发挥重要作用。
#define latchPin 5 //定义控制七段数码管的引脚
#define clockPin 6 //定义控制七段数码管的引脚
#define dataPin 4 //定义控制七段数码管的引脚
#define dot 2 //定义控制七段数码管的引脚
声明变量存储从RTC获取的转换结果或原始结果。
int h;
int m;
int thousands;
int hundreds;
int tens;
int unit;
bool h24;
bool PM;
接下来,声明类DS3231的对象为RTC,以简化在以后代码中的使用。
DS3231 RTC;
由于RTC模块通过I2C通信与Arduino连接。因此,wire.begin()用于在RTC的默认地址中启动I2C通信,因为没有其他I2C模块。
Wire.begin();
定义引脚模式,确定GPIO是作为输出还是输入。
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(dot,OUTPUT);
loop函数将无限运行,首先需要从RTC DS3231模块读取以小时和分钟为单位的时间。 'h24'表示24小时格式变量。
int h= RTC.getHour(h24, PM); //读取小时
int m = RTC.getMinute(); //读取分钟
然后将小时和分钟组合为一个数字(例如,如果小时为10,则min为60,则数字为10 * 100 = 1000 + 60 = 1060)。
int number = h*100+m; //把4位数字转换小时和分钟
获得数字的各个位的数字(示例1060-1是千位,0是百位,1是十位,0是最后一个数字)。为了分开数字,使用模数运算符。例如,在1060得到1然后1060/1000 = 1.06%10 = 1)。因此,单独的数字存储在单独的变量中。
int thousands = number/1000%10; //从4位数中获取千位数
int hundreds = number/100%10; //从4位数中获取百位数
int tens = number/10%10; //从4位数中获取十位数
int unit = number%10; //从4位数中获取个位数
之后,定义每个数字的switch-case语句,用于将它们转换为相应的格式(二进制格式),并通过移位寄存器发送到7段显示。例如(对于1位数,它将转换为06(0000 0110))。因此它通过移位发出,1位数显示在7段(0表示LOW,1表示HIGH)。
switch (t)
{
case 0:
unit = 63;
break;
case 1:
unit = 06;
break;
case 2:
unit =91;
break;
case 3:
unit=79;
break;
case 4:
unit=102;
break;
case 5:
unit = 109;
break;
case 6:
unit =125;
case 7:
unit = 07;
break;
case 8:
unit = 127;
break;
case 9:
unit =103;
break;
}
然后,通过'shiftout'函数以先MSB的方式发送二进制格式的数字,相应的数字引脚变为高电平,锁存引脚变为高电平。
digitalWrite(9, LOW); // 定义电平
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST,thousands); // 发送千位数
digitalWrite(latchPin, HIGH); // 将latchPin置为高电平以存储输入
digitalWrite(9, HIGH);
delay(5); // 延时5ms执行
这样就完成了完整的代码。大多数函数说明都在代码注释部分的代码行旁边给出。时钟的频率将决定多路复用的时间和质量的。如果使用的时钟低,那么可以看到闪烁,如果时钟速度高,那么就不会有这样的闪烁,可以看到稳定的时间。