Real-time clock DS1302 experiment

Real-time clock DS1302 experiment

Experimental phenomena

Get the year, month, day, week, hour, minute, second value through DS1302 reading, and then display the serial port on the PC.
Set the current time through 4 buttons.
Button 1 (setting): Press once to enter the setting state. Press to exit the setting state.
Button 2 (switch): Press to switch a setting variable. You can set the year, month, day, week, hour, minute, and second.
Button 3 (plus 1): You can add the current setting variable 1 operation
Button 4 (minus 1): You can subtract 1 from the current setting variable

Theoretical study

Insert picture description here

  • DS1302 is a high-performance, low-power, RAM-equipped real-time clock circuit introduced by DALLAS, USA. It can time the year, month, day, week, hour, minute, and second, and has a leap year compensation function. 2.0V~5.5V. A three-wire interface is used for synchronous communication with the CPU, and multiple bytes of clock signals or RAM data can be transmitted at a time in a burst mode. There is a 31×8 RAM register for temporarily storing data inside DS1302. DS1302 is an upgraded product of DS1202, compatible with DS1202, but adds dual power supply pins for main power supply/backup power supply, and provides the ability to trickle current charge the backup power supply.
  • The pin arrangement of DS1302, Vcc2 is the main power supply, and VCC1 is the backup power supply. The continuous operation of the clock can be maintained even when the main power supply is turned off. DS1302 is powered by the larger of Vcc1 or Vcc2. When Vcc2 is greater than Vcc1+0.2V, Vcc2 supplies power to DS1302. When Vcc2 is less than Vcc1, DS1302 is powered by Vcc1. X1 and X2 are the oscillation sources, and an external 32.768kHz crystal oscillator. RST is the reset/chip select line. All data transfers are started by driving the RST input to high. RST input has two functions: First, RST turns on the control logic, allowing the address/command sequence to be sent to the shift register; second, RST provides a method to terminate single-byte or multi-byte data transmission. When RST is high, all data transfers are initialized, allowing operations on the DS1302. If RST is set to low level during the transfer, the data transfer will be terminated and the I/O pin will become high impedance. During power-on operation, RST must remain low before Vcc>2.0V. Only when SCLK is low, can RST be set high. I/O is a serial data input and output terminal (two-way), which will be described in detail later. SCLK is the clock input terminal. The following picture shows the pin function diagram of DS1302:
    Insert picture description here

Schematic diagram

Insert picture description here

Code writing

#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);
}

Guess you like

Origin blog.csdn.net/qq_45671732/article/details/109615276