实时时钟DS1302实验

实时时钟DS1302实验

实验现象

通过DS1302的读取获取年,月,日,星期,时,分,秒的值,然后串口显示在PC上
通过4个按键设定当前的时间
按键1(设置):按一下进入设置状态,在按下退出设置状态
按键2(切换):按一下切换一种设置变量,分别可以设置年,月,日,星期,时,分,秒
按键3(加1):可以对当前的设置变量进行加1操作
按键4(减1):可以对当前的设置变量进行减1操作

理论学习

在这里插入图片描述

  • DS1302 是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.0V~5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后备电源双电源引脚,同时提供了对后备电源进行涓细电流充电的能力。
  • DS1302的引脚排列,其中Vcc2为主电源,VCC1为后备电源。在主电源关闭的情况下,也能保持时钟的连续运行。DS1302由Vcc1或Vcc2两者中的较大者供电。当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。当Vcc2小于Vcc1时,DS1302由Vcc1供电。X1和X2是振荡源,外接32.768kHz晶振。RST是复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据传送的方法。当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。上电运行时,在Vcc>2.0V之前,RST必须保持低电平。只有在SCLK为低电平时,才能将RST置为高电平。I/O为串行数据输入输出端(双向),后面有详细说明。SCLK为时钟输入端。 下图为DS1302的引脚功能图:
    在这里插入图片描述

原理图

在这里插入图片描述

代码编写

#define RST 7 
#define SCLK 6
#define IO 5
//#define L(item) digitalWrite((item),LOW)
//#define H(item) digitalWrite((item),HIGH)
#define uchar unsigned char
void setup() {
  pinMode(RST,OUTPUT);
  pinMode(SCLK,OUTPUT);
  pinMode(IO,OUTPUT);
  Serial.begin(9600);
  attachInterrupt(0, settm, FALLING );
}
void writeData(unsigned char addr,unsigned char dat){
  pinMode(IO,OUTPUT);
  digitalWrite(RST,LOW); //下拉低,再拉高
  digitalWrite(SCLK,LOW) ; //SCLK的上升沿, 芯片会读取IO端口
  delayMicroseconds(1);
  digitalWrite(RST,HIGH); 
  int i;
  for(i =0;i<8;i++){
    digitalWrite(SCLK,LOW);
    digitalWrite(IO, addr&1);
    addr =addr>>1;
    digitalWrite(SCLK,HIGH);
    delayMicroseconds(1);
  }
  for(i =0;i<8;i++){
      digitalWrite(SCLK,LOW);
      digitalWrite(IO, dat&1);
      dat =dat>>1;
      digitalWrite(SCLK,HIGH);
      delayMicroseconds(1);
  }
  digitalWrite(RST,LOW);
}
uchar readData(uchar addr){
  addr = addr | 1; //读操作最低位置为1 
  pinMode(IO,OUTPUT);
  digitalWrite(RST,LOW); //下拉低,再拉高
  digitalWrite(SCLK,LOW) ; //SCLK的上升沿, 芯片会读取IO端口
  delayMicroseconds(1);
  digitalWrite(RST,HIGH); 
  int i;
  for(i =0;i<8;i++){
    digitalWrite(SCLK,LOW);
    digitalWrite(IO, addr&1);
    addr =addr>>1;
    digitalWrite(SCLK,HIGH);
    delayMicroseconds(1);
  }
  pinMode(IO,INPUT);
  int dat = 0;
  for(i =0;i<8;i++){
      digitalWrite(SCLK,LOW);
      delayMicroseconds(10);
      uchar b = digitalRead(IO);
      dat = dat >>1; //先向右平移     
      dat = dat | (b<<7); //将所得放入最高位
      digitalWrite(SCLK,HIGH);
      delayMicroseconds(1);
  }
  digitalWrite(RST,LOW);  
  return dat ;
}
#define SECOND  0x80
#define MIN 0x82
#define HOUR 0x84
#define DAY 0x86
#define MONTH 0x88
#define YEAR 0x8C
#define WEEK 0x8A
void writeTimeUnit(uchar TYPE,uchar data){
  uchar high = data / 10;
  uchar low = data % 10;
  uchar d = ((data /10) << 4) | (data % 10);
  writeData(TYPE,data);
}
uchar readTimeUnit(uchar TYPE){
  uchar r = readData(TYPE);
  r = 10*(r >> 4)+ (r & 0xf);
  return r;
}
void writeAllTm(uchar tm[]){
  uchar s = SECOND;
  for(uchar i=0;i<5;i++){
    writeTimeUnit(s,tm[5-i]);
    s+=2;
  }
  writeTimeUnit(YEAR,tm[0]);
}
void readAllTm(uchar tm[]){
  uchar s = SECOND;
  for(uchar i=0;i<5;i++){
    tm[5-i] = readTimeUnit(s);
    s+=2;
  }  
  tm[0] = readTimeUnit(YEAR);
  tm[6] = readTimeUnit(WEEK);
}
void printTm(uchar tm[]){
  Serial.print(tm[0]);
  Serial.print("-");
  Serial.print(tm[1]);
  Serial.print("-");
  Serial.print(tm[2]);
  Serial.print(" ");
  Serial.print(tm[3]);
  Serial.print(":");
  Serial.print(tm[4]);
  Serial.print(":");
  Serial.print(tm[5]);
  Serial.print(" week ");
  Serial.print(tm[6]);
  Serial.println();
}
uchar st = 0;
void loop() {
    uchar tm[7] = {0}; 
    readAllTm(tm);
    printTm(tm);
    delay(1000);
}
void settm()//中断函数
{
    uchar tm[] = {11,12,13,4,5,6 ,0}; // 2011-12-22 3:4:1
    Serial.println("set tm ...");
      writeAllTm(tm);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_45671732

你们鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值