找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3425|回复: 4
打印 上一主题 下一主题
收起左侧

arduino+DS1302+按键制作可调时钟程序,在写按键更改时间的地方搞不懂

[复制链接]
跳转到指定楼层
楼主
40黑币
想利用arduino+DS1302制作时钟,按键可以更改时间,并且可以用串口改变时间。在写按键更改时间的地方搞不懂。没有办法把时间写进DS1302中。求助各位大神帮帮忙。。


Arduino源程序如下:
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "DS1302.h"

  4. uint8_t CE_PIN   = 5;
  5. uint8_t IO_PIN   = 6;
  6. uint8_t SCLK_PIN = 7;
  7. int stopped = A5;
  8. int min_up = A4;
  9. int min_down = A3;
  10. int hour_up = A2;
  11. int hour_down = A1;
  12. int flag = 1;


  13. /* 日期变量缓存 */
  14. char buf[50];
  15. char day[10];
  16. /* 串口数据缓存 */
  17. String comdata = "";
  18. int numdata[7] = {0}, j = 0, mark = 0;
  19. /* 创建 DS1302 对象 */
  20. DS1302 rtc(CE_PIN, IO_PIN, SCLK_PIN);
  21. void print_time()
  22. {
  23.   /* 从 DS1302 获取当前时间 */
  24.   Time t = rtc.time();
  25.   /* 将星期从数字转换为名称 */
  26.   memset(day, 0, sizeof(day));
  27.   switch (t.day)
  28.   {
  29.     case 1: strcpy(day, "Sunday"); break;
  30.     case 2: strcpy(day, "Monday"); break;
  31.     case 3: strcpy(day, "Tuesday"); break;
  32.     case 4: strcpy(day, "Wednesday"); break;
  33.     case 5: strcpy(day, "Thursday"); break;
  34.     case 6: strcpy(day, "Friday"); break;
  35.     case 7: strcpy(day, "Saturday"); break;
  36.   }
  37.   /* 将日期代码格式化凑成buf等待输出 */
  38.   snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d", day, t.yr, t.mon, t.date, t.hr, t.min, t.sec);
  39.   /* 输出日期到串口 */
  40.   Serial.println(buf);
  41. }


  42. void setup()
  43. {
  44.   Serial.begin(9600);
  45.   rtc.write_protect(false);
  46.   rtc.halt(false);
  47.   pinMode(stopped, INPUT_PULLUP);
  48.   pinMode(min_up, INPUT_PULLUP);
  49.   pinMode(min_down, INPUT_PULLUP);
  50.   pinMode(hour_up, INPUT_PULLUP);
  51.   pinMode(hour_down, INPUT_PULLUP);
  52. }

  53. void loop()
  54. {
  55.    if (digitalRead(stopped) == 0) {
  56.     flag = !flag;
  57.     if (flag == 0) {
  58.       Serial.end();
  59.     }
  60.     if (flag == 1) {
  61.       Serial.begin(9600);
  62.     }
  63.   }
  64.   if(digitalRead(min_up) == 0){
  65.    
  66.   }
  67.   /* 当串口有数据的时候,将数据拼接到变量comdata */
  68.   while (Serial.available() > 0)
  69.   {
  70.     comdata += char(Serial.read());
  71.     delay(2);
  72.     mark = 1;
  73.   }
  74.   /* 以逗号分隔分解comdata的字符串,分解结果变成转换成数字到numdata[]数组 */
  75.   if (mark == 1)
  76.   {
  77.     Serial.print("You inputed : ");
  78.     Serial.println(comdata);
  79.     for (int i = 0; i < comdata.length() ; i++)
  80.     {
  81.       if (comdata[i] == ',' || comdata[i] == 0x10 || comdata[i] == 0x13)
  82.       {
  83.         j++;
  84.       }
  85.       else
  86.       {
  87.         numdata[j] = numdata[j] * 10 + (comdata[i] - '0');
  88.       }
  89.     }
  90.     /* 将转换好的numdata凑成时间格式,写入DS1302 */
  91.     Time t(numdata[0], numdata[1], numdata[2], numdata[3], numdata[4], numdata[5], numdata[6]);
  92.     rtc.time(t);
  93.     mark = 0; j = 0;
  94.     /* 清空 comdata 变量,以便等待下一次输入 */
  95.     comdata = String("");
  96.     /* 清空 numdata */
  97.     for (int i = 0; i < 7 ; i++) numdata[i] = 0;
  98.   }

  99.   /* 打印当前时间 */
  100.   print_time();
  101.   delay(1000);
  102. }

复制代码



最佳答案

查看完整内容

下面是从DS1302读取时间和写入时间的程序,编个按键就可以实现 按键更改时间了 char READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; char WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c}; char TIME[7] = {0};//秒分时日月周年,存储格式是用BCD码 void writeData(unsigned char addr,unsigned char dat){ //向芯片里面写数据, pinMode(IO_PIN,OUTPUT); digitalWrite(CE_PI ...
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:594925 发表于 2020-4-11 13:03 | 只看该作者
下面是从DS1302读取时间和写入时间的程序,编个按键就可以实现 按键更改时间了

char  READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
char  WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
char TIME[7] = {0};//秒分时日月周年,存储格式是用BCD码

void writeData(unsigned char addr,unsigned char dat){   //向芯片里面写数据,
  pinMode(IO_PIN,OUTPUT);
  digitalWrite(CE_PIN,LOW);   //下拉低,再拉高
  digitalWrite(SCLK_PIN,LOW) ; //SCLK的上升沿, 芯片会读取IO端口
  delayMicroseconds(1);
  digitalWrite(CE_PIN,HIGH);

  int i;
  for(i =0;i<8;i++){
    digitalWrite(SCLK_PIN,LOW);
    digitalWrite(IO_PIN, addr&1);
    addr =addr>>1;
    digitalWrite(SCLK_PIN,HIGH);
    delayMicroseconds(1);
  }

  for(i =0;i<8;i++){
      digitalWrite(SCLK_PIN,LOW);
      digitalWrite(IO_PIN, dat&1);
      dat =dat>>1;
      digitalWrite(SCLK_PIN,HIGH);
      delayMicroseconds(1);
  }
  digitalWrite(CE_PIN,LOW);
}

char readData(char addr){              //从芯片里去读源数据,但是数据还是要经过一定的格式化才行啊
  addr = addr | 1; //读操作最低位置为1     要看懂这些就需要查看芯片的手册才是呀

  pinMode(IO_PIN,OUTPUT);
  digitalWrite(CE_PIN,LOW); //下拉低,再拉高
  digitalWrite(SCLK_PIN,LOW) ; //SCLK的上升沿, 芯片会读取IO端口
  delayMicroseconds(1);
  digitalWrite(CE_PIN,HIGH);

  int i;
  for(i =0;i<8;i++){                //读取命令是先要写一些命令代码,根据代码,芯片会吐出相应的元素.
    digitalWrite(SCLK_PIN,LOW);
    digitalWrite(IO_PIN, addr&1);
    addr =addr>>1;
    digitalWrite(SCLK_PIN,HIGH);
    delayMicroseconds(1);
  }
  pinMode(IO_PIN,INPUT);               //设置io口为向内读入.这样这个引脚就可以读取数据了.

  int dat = 0;
  for(i =0;i<8;i++){
      digitalWrite(SCLK_PIN,LOW);
      delayMicroseconds(10);
      char b = digitalRead(IO_PIN);
      dat = dat >>1; //先向右平移

      dat = dat | (b<<7); //将所得放入最高位
      digitalWrite(SCLK_PIN,HIGH);
      delayMicroseconds(1);
  }
  digitalWrite(CE_PIN,LOW);  
  return dat ;
}
回复

使用道具 举报

板凳
ID:160964 发表于 2020-4-11 14:31 | 只看该作者
建议用DS321,你这个没有温度补偿,时差可能较大
回复

使用道具 举报

地板
ID:620438 发表于 2020-4-14 13:17 | 只看该作者
wudidewrf 发表于 2020-4-14 10:50
下面是从DS1302读取时间和写入时间的程序,编个按键就可以实现 按键更改时间了

char  READ_RTC_ADDR[7]  ...

谢谢。。但是我看不怎么懂这个程序。。就是你写的这个程序是直接加到我的程序里还是单独的啊?如果可以的话可以麻烦你直接在我的程序上面改动一下吗?
回复

使用道具 举报

5#
ID:594925 发表于 2020-4-14 16:05 | 只看该作者
1334479405 发表于 2020-4-14 13:17
谢谢。。但是我看不怎么懂这个程序。。就是你写的这个程序是直接加到我的程序里还是单独的啊?如果可以的 ...

把这个程序加到你那个程序里面,然后在你这里 if(digitalRead(min_up) == 0){    }这样写
if(digitalRead(min_up) == 0)
{  
      for(n=0;n<7;n++)
  {
    TIME[n]=readData(READ_RTC_ADDR[n]);
  }                          //读取DS1302里当前时间
    TIME[1]=TIME[1]+1; //分钟增加1,秒分时日月周年,分在TIME[1]里 时在TIME[2]

     for(n=0;n<7;n++)
  {
     writeData(WRITE_RTC_ADDR[n],TIME[n]);
  }                          //把更改的时间写入DS1302
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表