Arduino UNO+DS1302+ MAX7219驱动8位共阴数码管显示时间+Proteus仿真【改进版】

Arduino UNO+DS1302+ MAX7219驱动8位共阴数码管显示时间+Proteus仿真【改进版】


  • 相关篇《Arduino UNO + DS1302 + TM1638时间显示+Proteus仿真二
    在这里插入图片描述

  • 改进版内容:之前的版本需要使用物理自锁按键来控制日期和时间的切换。改进后,利用的是点动的物理按键即可。触发方式,以前是将按键检测信号放到loop循环里面轮询检测,改进后的采用中断触发方式,像Arduino UNO板子支持外部中断引脚有2和3号引脚,ESP8266除了一些特殊引脚外,其他引脚都支持。

  • 所需库
    在这里插入图片描述

  • DS1302库将和源程序一起打包。

实例代码

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

#include <stdio.h>
#include <DS1302.h>
#include <LedControl.h>//点击这里会自动打开管理库页面: http://librarymanager/All#LedControl

#define interruptPin 2
volatile byte State = LOW;//中断中的变量使用volatile 修饰词

// inputs: DIN pin, CLK pin, LOAD pin. number of chips
LedControl mydisplay = LedControl(11, 9, 10, 1);
DS1302 rtc(8, 7, 6); //对应DS1302的RST,DAT,CLK


unsigned long previousMillis = 0;
const long interval = 1000; //设置延时时间间隔
uint8\_t buf[15];//存放时间数据

void initRTCTime(void)//初始化RTC时钟
{
rtc.writeProtect(false); //关闭写保护
rtc.halt(false); //清除时钟停止标志

Time t(2021, 12, 11, 10, 34, 50, 6); //创建时间对象 最后参数位,为星期数据,周日为1,周一为2,周二为3,周四为5以此类推.
rtc.time(t);//向DS1302设置时间数据
}

/\*\*\*\*\*\*获取时间函数\*\*\*\*/
void printTime(){
//strcpy(buf, "");
Time tim = rtc.time(); //从DS1302获取时间数据
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf), "%02d%02d%02d%02d%02d%02d",
tim.hr, tim.min, tim.sec, tim.yr, tim.mon, tim.date);
if(State){
mydisplay.clearDisplay(0);
mydisplay.setChar(0, 0, buf[8], false);//年-高位
mydisplay.setChar(0, 1, buf[9], false);//年-低位
mydisplay.setChar(0, 2, '-', false);//-
mydisplay.setChar(0, 3, buf[10], false); //月-高位
mydisplay.setChar(0, 4, buf[11], false);//月-低位
mydisplay.setChar(0, 5, '-', false);//-
mydisplay.setChar(0, 6, buf[12], false);//日-高位
mydisplay.setChar(0, 7, buf[13], false); //日-低位
}else{
mydisplay.clearDisplay(0);
mydisplay.setChar(0, 0, buf[0], false);//时-高位
mydisplay.setChar(0, 1, buf[1], false);//时-低位
mydisplay.setChar(0, 2, '-', false);//-
mydisplay.setChar(0, 3, buf[2], false); //分-高位
mydisplay.setChar(0, 4, buf[3], false);//分-低位
mydisplay.setChar(0, 5, '-', false);//-
mydisplay.setChar(0, 6, buf[4], false);//秒-高位
mydisplay.setChar(0, 7, buf[5], false); //秒-低位
}
}
void setup() {
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), use, FALLING);//开中断,下降沿触发
/\*\*\*\*\*\*\*\*\*\*
//DS1302新模块第一次上电需要设置一次当前时间进去,
//下载完成后需屏蔽此函数再次下载,否则每次上电都会初始化时间数据
// initRTCTime();
\*\*\*\*\*\*\*\*\*\*/
rtc.writeProtect(true);//ds1302写保护开启
for (int i = 0; i < DS1302::kRamSize; ++i) {
rtc.writeRam(i, 0x00);
}
mydisplay.shutdown(0, false); // 初始化时设置点阵(设备)的关机(节能)模式
mydisplay.setIntensity(0, 15); //设置亮度值 0-15

}

void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
printTime();
}
}
/\*\*中断服务函数\*\*/
void use() {
State = !State;
}


  • 编译信息
1
2
3
4
5
6
使用库 ds1302 在文件夹: C:\Program Files (x86)\Arduino\libraries\ds1302 (legacy)
使用 1.0.6 版本的库 LedControl 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\LedControl
"C:\\Users\\Administrator\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-size" -A "d:\\arduino\\MyHexDir/ds1302max7219.ino.elf"
项目使用了 4374 字节,占用了 (13%) 程序存储空间。最大为 32256 字节。
全局变量使用了150字节,(7%)的动态内存,余留1898字节局部变量。最大为2048字节。

程序源码和仿真资源

1
2
3
链接:https://pan.baidu.com/s/1nlN-LtoRYJxAR5lfiz0ncQ 
提取码:7va4


不管发生什么事, 都请安静且愉快地接受人生, 勇敢地、 大胆地, 而且永远地微笑着。 —— 卢森堡