让我们一起爱米兰
站内搜搜:
移动设备
请扫描二维码
或访问
m.milan100.com
您所在的位置 -> 米兰百分百 -> arduino -> arduino连接DS1302模块显示或修改时钟clk、dat、rst

arduino连接DS1302模块显示或修改时钟clk、dat、rst

点击数:2011 发表时间:2016-05-29 00:01:52 作者: 来源链接:
分享到:
分享到微信

使用arduino连接DS1302模块,显示或修改时钟
新建文件DS1302.ino

/*
Arduino 连接 DS1302
代码来源:http://quadpoint.org/projects/arduino-ds1302
增加了串口调整时间代码
*/
#include <stdio.h>
#include <string.h>
#include <DS1302.h>
/* 接口定义
CE(DS1302 pin5,rst) -> Arduino D5
IO(DS1302 pin6,dat) -> Arduino D6
SCLK(DS1302 pin7,clk) -> Arduino D7
*/
uint8_t CE_PIN   = 5;
uint8_t IO_PIN   = 6;
uint8_t SCLK_PIN = 7;
/* 日期变量缓存 */
char buf[50];
char day[10];
/* 串口数据缓存 */
String comdata = "";
int numdata[7] ={0}, j = 0, mark = 0;
/* 创建 DS1302 对象 */
DS1302 rtc(CE_PIN, IO_PIN, SCLK_PIN);
void print_time()
{
    /* 从 DS1302 获取当前时间 */
    Time t = rtc.time();
    /* 将星期从数字转换为名称 */
    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);
    rtc.write_protect(false);
    rtc.halt(false);
}
void loop()
{
    /* 当串口有数据的时候,将数据拼接到变量comdata,可以设置时钟的时间,格式2016,5,29,15,13,0,1,最后一位是星期几,周日是1 */
    while (Serial.available() > 0)
    {
        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 变量,以便等待下一次输入 */
        comdata = String("");
        /* 清空 numdata */
        for(int i = 0; i < 7 ; i++) numdata[i]=0;
    }
    
    /* 打印当前时间 */
    print_time();
    delay(1000);
}


下面两个文件放入系统libraries目录,里面新建目录DS1302

DS1302.h

/*
Copyright (c) 2009, Matt Sparks
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
 * Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in
   the documentation and/or other materials provided with the
   distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
#ifndef DS1302_h
#define DS1302_h
#include "Arduino.h"
/**
 * Convenience register constants
 */
#define SEC_REG  0
#define MIN_REG  1
#define HR_REG   2
#define DATE_REG 3
#define MON_REG  4
#define DAY_REG  5
#define YR_REG   6
#define WP_REG   7
/**
 * Type for a register number
 */
typedef uint8_t reg_t;
/**
 * Class representing a particular time and date.
 */
class Time
{
public:
  uint8_t sec;
  uint8_t min;
  uint8_t hr;
  uint8_t date;
  uint8_t mon;
  uint8_t day;
  uint16_t yr;
  /**
   * Default constructor.
   *
   * Creates a time object dated to Saturday Jan 1, 2000 at 00:00:00.
   * The date and time can be changed by editing the instance variables.
   */
  Time();
  /**
   * Create a Time object with a given time.
   *
   * Args:
   *   yr: year. Range: {2000, ..., 2099}.
   *   mon: month. Range: {1, ..., 12}.
   *   date: date (of the month). Range: {1, ..., 31}.
   *   hr: hour. Range: {0, ..., 23}.
   *   min: minutes. Range: {0, ..., 59}.
   *   sec: seconds. Range: {0, ..., 59}.
   *   day: day of the week. Sunday is 1. Range: {1, ..., 7}.
   */
  Time(uint16_t yr, uint8_t mon, uint8_t date,
       uint8_t hr, uint8_t min, uint8_t sec,
       uint8_t day);
};
/**
 * Talk to a Dallas Semiconductor DS1302 Real Time Clock (RTC) chip.
 */
class DS1302
{
public:
  /**
   * Constructor.
   *
   * Args:
   *   ce_pin: CE pin number
   *   io_pin: IO pin number
   *   sclk_pin: SCLK pin number
   */
  DS1302(uint8_t ce_pin, uint8_t io_pin, uint8_t sclk_pin);
  /**
   * Read register byte value.
   *
   * Args:
   *   reg: register number
   *
   * Returns:
   *   register value
   */
  uint8_t read_register(reg_t reg);
  /**
   * Write byte into register.
   *
   * Args:
   *   reg: register number
   *   value: byte to write
   */
  void write_register(reg_t reg, uint8_t value);
  /**
   * Enable or disable write protection on chip.
   *
   * Args:
   *   enable: true to enable, false to disable.
   */
  void write_protect(bool enable);
  /**
   * Set or clear clock halt flag.
   *
   * Args:
   *   value: true to set halt flag, false to clear.
   */
  void halt(bool value);
  /**
   * Get individual pieces of the time and date.
   */
  uint8_t seconds();
  uint8_t minutes();
  uint8_t hour();
  uint8_t date();
  uint8_t month();
  uint8_t day();
  uint16_t year();
  /**
   * Get the current time and date in a Time object.
   *
   * Returns:
   *   Time object.
   */
  Time time();
  /**
   * Individually set pieces of the date and time.
   *
   * The arguments here follow the rules specified above in Time::Time(...).
   */
  void seconds(uint8_t sec);
  void minutes(uint8_t min);
  void hour(uint8_t hr);
  void date(uint8_t date);
  void month(uint8_t mon);
  void day(uint8_t day);
  void year(uint16_t yr);
  /**
   * Set the time and date to the instant specified in a given Time object.
   *
   * Args:
   *   t: Time object to use
   */
  void time(Time t);
private:
  uint8_t _ce_pin;
  uint8_t _io_pin;
  uint8_t _sclk_pin;
  /**
   * Shift out a value to the IO pin.
   *
   * Side effects: sets _io_pin as OUTPUT.
   *
   * Args:
   *   value: byte to shift out
   */
  void _write_out(uint8_t value);
  /**
   * Read in a byte from the IO pin.
   *
   * Side effects: sets _io_pin to INPUT.
   *
   * Returns:
   *   byte read in
   */
  uint8_t _read_in();
  /**
   * Get a binary-coded decimal register and return it in decimal.
   *
   * Args:
   *   reg: register number
   *   high_bit: number of the bit containing the last BCD value ({0, ..., 7})
   *
   * Returns:
   *   decimal value
   */
  uint8_t _register_bcd_to_dec(reg_t reg, uint8_t high_bit);
  uint8_t _register_bcd_to_dec(reg_t reg);
  /**
   * Set a register with binary-coded decimal converted from a given value.
   *
   * Args:
   *   reg: register number
   *   value: decimal value to convert to BCD
   *   high_bit: highest bit in the register allowed to contain BCD value
   */
  void _register_dec_to_bcd(reg_t reg, uint8_t value, uint8_t high_bit);
  void _register_dec_to_bcd(reg_t reg, uint8_t value);
};
#endif


DS1302.cpp

#include "Arduino.h"
#include "DS1302.h"
/*** Time definitions ***/
Time::Time(uint16_t yr, uint8_t mon, uint8_t date,
           uint8_t hr, uint8_t min, uint8_t sec,
           uint8_t day)
{
  this->yr   = yr;
  this->mon  = mon;
  this->date = date;
  this->hr   = hr;
  this->min  = min;
  this->sec  = sec;
  this->day  = day;
}
Time::Time()
{
  Time(2000, 1, 1, 0, 0, 0, 7);
}
/*** DS1302 definitions ***/
DS1302::DS1302(uint8_t ce_pin, uint8_t io_pin, uint8_t sclk_pin)
{
  _ce_pin = ce_pin;
  _io_pin = io_pin;
  _sclk_pin = sclk_pin;
  pinMode(ce_pin, OUTPUT);
  pinMode(sclk_pin, OUTPUT);
}
void DS1302::_write_out(uint8_t value)
{
  pinMode(_io_pin, OUTPUT);
  shiftOut(_io_pin, _sclk_pin, LSBFIRST, value);
}
uint8_t DS1302::_read_in()
{
  uint8_t input_value = 0;
  uint8_t bit = 0;
  pinMode(_io_pin, INPUT);
  for (int i = 0; i < 8; ++i) {
    bit = digitalRead(_io_pin);
    input_value |= (bit << i);
    digitalWrite(_sclk_pin, HIGH);
    delayMicroseconds(1);
    digitalWrite(_sclk_pin, LOW);
  }
  return input_value;
}
uint8_t DS1302::_register_bcd_to_dec(reg_t reg, uint8_t high_bit)
{
  uint8_t val = read_register(reg);
  uint8_t mask = (1 << (high_bit + 1)) - 1;
  val &= mask;
  val = (val & 15) + 10 * ((val & (15 << 4)) >> 4);
  return val;
}
uint8_t DS1302::_register_bcd_to_dec(reg_t reg)
{
  return _register_bcd_to_dec(reg, 7);
}
void DS1302::_register_dec_to_bcd(reg_t reg, uint8_t value, uint8_t high_bit)
{
  uint8_t regv = read_register(reg);
  uint8_t mask = (1 << (high_bit + 1)) - 1;
  /* convert value to bcd in place */
  uint8_t tvalue = value / 10;
  value = value % 10;
  value |= (tvalue << 4);
  /* replace high bits of value if needed */
  value &= mask;
  value |= (regv &= ~mask);
  write_register(reg, value);
}
void DS1302::_register_dec_to_bcd(reg_t reg, uint8_t value)
{
  _register_dec_to_bcd(reg, value, 7);
}
uint8_t DS1302::read_register(reg_t reg)
{
  uint8_t cmd_byte = 129;  /* 1000 0001 */
  uint8_t reg_value;
  cmd_byte |= (reg << 1);
  digitalWrite(_sclk_pin, LOW);
  digitalWrite(_ce_pin, HIGH);
  _write_out(cmd_byte);
  reg_value = _read_in();
  digitalWrite(_ce_pin, LOW);
  return reg_value;
}
void DS1302::write_register(reg_t reg, uint8_t value)
{
  uint8_t cmd_byte = (128 | (reg << 1));
  digitalWrite(_sclk_pin, LOW);
  digitalWrite(_ce_pin, HIGH);
  _write_out(cmd_byte);
  _write_out(value);
  digitalWrite(_ce_pin, LOW);
}
void DS1302::write_protect(bool enable)
{
  write_register(WP_REG, (enable << 7));
}
void DS1302::halt(bool enable)
{
  uint8_t sec = read_register(SEC_REG);
  sec &= ~(1 << 7);
  sec |= (enable << 7);
  write_register(SEC_REG, sec);
}
/*** Get time ***/
uint8_t DS1302::seconds()
{
  return _register_bcd_to_dec(SEC_REG, 6);
}
uint8_t DS1302::minutes()
{
  return _register_bcd_to_dec(MIN_REG);
}
uint8_t DS1302::hour()
{
  uint8_t hr = read_register(HR_REG);
  uint8_t adj;
  if (hr & 128)  /* 12-hour mode */
    adj = 12 * ((hr & 32) >> 5);
  else           /* 24-hour mode */
    adj = 10 * ((hr & (32 + 16)) >> 4);
  hr = (hr & 15) + adj;
  return hr;
}
uint8_t DS1302::date()
{
  return _register_bcd_to_dec(DATE_REG, 5);
}
uint8_t DS1302::month()
{
  return _register_bcd_to_dec(MON_REG, 4);
}
uint8_t DS1302::day()
{
  return _register_bcd_to_dec(DAY_REG, 2);
}
uint16_t DS1302::year()
{
  return 2000 + _register_bcd_to_dec(YR_REG);
}
Time DS1302::time()
{
  Time t;
  t.sec  = seconds();
  t.min  = minutes();
  t.hr   = hour();
  t.date = date();
  t.mon  = month();
  t.day  = day();
  t.yr   = year();
  return t;
}
/*** Set time ***/
void DS1302::seconds(uint8_t sec)
{
  _register_dec_to_bcd(SEC_REG, sec, 6);
}
void DS1302::minutes(uint8_t min)
{
  _register_dec_to_bcd(MIN_REG, min, 6);
}
void DS1302::hour(uint8_t hr)
{
  write_register(HR_REG, 0);  /* set 24-hour mode */
  _register_dec_to_bcd(HR_REG, hr, 5);
}
void DS1302::date(uint8_t date)
{
  _register_dec_to_bcd(DATE_REG, date, 5);
}
void DS1302::month(uint8_t mon)
{
  _register_dec_to_bcd(MON_REG, mon, 4);
}
void DS1302::day(uint8_t day)
{
  _register_dec_to_bcd(DAY_REG, day, 2);
}
void DS1302::year(uint16_t yr)
{
  yr -= 2000;
  _register_dec_to_bcd(YR_REG, yr);
}
void DS1302::time(Time t)
{
  seconds(t.sec);
  minutes(t.min);
  hour(t.hr);
  date(t.date);
  month(t.mon);
  day(t.day);
  year(t.yr);
}


0
很 好
0
一 般
0
差 劲
热门新闻
相关文章
上一篇: Arduino语音识别模块 LD3320
下一篇: Arduino 与 Raspberry Pi(树莓派)的内存及性能对比
评论区
匿名

返回首页 | 收藏本页 | 回到顶部
Copyright 2010. 米兰百分百 Powered By Bridge.
京ICP备15050557号