☛ 功能说明

使用 Arduino 开发板读取 DS1302 时钟芯片应用电路的日期时间,以 Serial Monitor 视窗显示日期时间及调整日期时间,并将 DS1302 的时间显示在 MAX7219 八位数的七段显示器上。

☛ 使用材料

Arduino UNO R3  开发板 × 1、MAX7219 八位数七段显示器模块、电阻 10KΩ × 3、DS1302 时钟芯片 × 1、32.768kHz 晶振 × 1、DS1302 函式库MAX7219 LED 控制函式库

☛ 电路图及面包板接线图

☛ 程序码

#include <stdio.h>
#include <string.h>
#include <DS1302.h>
#include <LedControl.h>

uint8_t CE_PIN   = 5;                     // CE(DS1302 pin5) -> Arduino D5
uint8_t IO_PIN   = 6;                     // IO(DS1302 pin6) -> Arduino D6
uint8_t SCLK_PIN = 7;                     // SCLK(DS1302 pin7) -> Arduino D7

// pin 12 is connected to the DataIn 
// pin 11 is connected to the CLK 
// pin 10 is connected to LOAD 

LedControl lc=LedControl(12,11,10,1);

char buf[50];                             // 日期变量缓存
char day[10];
String comdata = "";                      // 序列埠数据缓存
int numdata[7] ={0}, j = 0, mark = 0;

char timeData[8];                         // 时间显示的资料格式 00-00-00
DS1302 rtc(CE_PIN, IO_PIN, SCLK_PIN);     // 创建 DS1302 对象


void print_time()
{
    Time t = rtc.time();                   // 从 DS1302 获取当前时间
    memset(day, 0, sizeof(day));           // 将星期从数字转换为名称
    switch (t.day)
    {
            case 1: strcpy(day, "Sunday"); break;
            case 2: strcpy(day, "Monday"); break;
            case 3: strcpy(day, "Tuesday"); break;
            case 4: strcpy(day, "Wednesday"); break;
            case 5: strcpy(day, "Thursday"); break;
            case 6: strcpy(day, "Friday"); break;
            case 7: strcpy(day, "Saturday"); break;
    }
    // 将日期代码格式化凑成buf等待输出
    snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d", day, t.yr, t.mon, t.date, t.hr, t.min, t.sec);
    Serial.println(buf);          // 输出日期到序列埠
}

void setup()
{
     Serial.begin(9600);          //设定序列埠传输速率为 9600bps
     rtc.write_protect(false);
     rtc.halt(false);
     
     lc.shutdown(0,false);        // The MAX72XX is in power-saving mode on startup,we have to do a wakeup call
     lc.setIntensity(0,8);        // Set the brightness to a medium values and clear the display
     lc.clearDisplay(0);
}

void loop()
{
    while (Serial.available() > 0)                  // 当序列埠有数据的时候,将数据拼接到变量comdata
    {
           comdata += char(Serial.read());
           delay(2);
           mark = 1;
    }
    // 以逗号分隔分解comdata的字符串,分解结果变成转换成数字到numdata[]数组
    if(mark == 1)
    {
        Serial.print("You inputed : ");
        Serial.println(comdata);
        for(int i = 0; i < comdata.length() ; i++)
        {
            if(comdata[i] == ',' || comdata[i] == 0x10 || comdata[i] == 0x13)
            {
                j++;
            }
            else
            {
                numdata[j] = numdata[j] * 10 + (comdata[i] - '0');
            }
        }
        // 将转换好的numdata凑成时间格式,写入DS1302
        Time t(numdata[0], numdata[1], numdata[2], numdata[3], numdata[4], numdata[5], numdata[6]);
        rtc.time(t);
        mark = 0;j=0;
        comdata = String("");               // 清空 comdata 变量,以便等待下一次输入
        /* 清空 numdata */
        for(int i = 0; i < 7 ; i++) numdata[i]=0;
    }
    
    print_time();                            // 打印当前时间
    getTime();                               // 取得 DS1302 的时间
    displayTime();                           // 显示时间
    delay(1000);                             // 延迟 1 秒
}

char transChar(int number)                   // 数值转换成字元函式
{
     char value;

     switch(number)
     {
            case 0: value='0'; break;
            case 1: value='1'; break;
            case 2: value='2'; break;
            case 3: value='3'; break;
            case 4: value='4'; break;
            case 5: value='5'; break;
            case 6: value='6'; break;
            case 7: value='7'; break;
            case 8: value='8'; break;
            case 9: value='9'; break;
     }
     return value;
}

void getTime()                             // 取得 DS1302 时钟芯片的时间,转换成显示的时间格式
{
     Time t = rtc.time();
     timeData[0]=transChar(t.hr/10);       // 时
     timeData[1]=transChar(t.hr%10);
     timeData[2]='-';
     timeData[3]=transChar(t.min/10);      // 分
     timeData[4]=transChar(t.min%10);
     timeData[5]='-';
     timeData[6]=transChar(t.sec/10);      // 秒
     timeData[7]=transChar(t.sec%10);
}

void displayTime()                         // 显示时间函式
{
     for(int i=7;i>=0;i--)
         lc.setChar(0,7-i,timeData[i],false);
}