Arduino, SPI and the DS1306 RTC

 

Converting BCD to Decimal

As we'll need a similar conversion for several of the other DS1306 regisers, it's neater to write it as a separate function.

void loop() {
  digitalWrite(chipEnablePin, HIGH);
  SPI.transfer(0x00);
  byte seconds = SPI.transfer(0x00); 

  seconds = bcd2dec(seconds);  
  digitalWrite(chipEnablePin, LOW); 
 
  Serial.println(seconds, DEC);
  delay(1000);  
}

byte bcd2dec(byte value) {
  byte units = value & B00001111;       // For the units, we only want bits 0 to 3 so mask off the rest.
  byte tens = (value >> 4) * 10;        // Shift the top 4 bits to the right, 4 times. Then
                                        // multiply by 10 to make decimal 'tens'.
  return  tens + units;                 // Return the sum.
}  

As can be seen from the Arduino Serial Monitor, the result is almost correct but not quite. Ideally we need to add a leading '0' when the value is less than 10. As the project will ultimately be using a Liquid Crystal Display, I think it's best to add the '0' later, as and when required.

 

It also makes sense to put the actual reading of the register into a function of its own because we'll obviously be reading other registers.


#include <SPI.h>

     // The DS1306 CE (chip enable) pin is connected to Arduino digital pin 10.
int chipEnablePin = 10;

void setup() {

     // Set the Chip enable pin as OUTPUT.
  pinMode(chipEnablePin, OUTPUT);

     // The DS1306 datasheet states the chip enable signal must be asserted HIGH 
     // during a read or a write so set it LOW before the SPI interface is set up.

  digitalWrite(chipEnablePin, LOW);

  SPI.begin();

     // The DS1306 datasheet states that data is clocked into or out of the registers
     // Most Significant Bit first and that it Supports Motorola SPI Modes 1 and 3. We'll use 
     // Mode 1.

  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE1);           // or SPI_MODE3
  
     // Initialize RTC Control Register
  digitalWrite(chipEnablePin, HIGH);    // Enable the Chip Enable by taking it HIGH
  SPI.transfer(0x8f);                   // Address the Control Register for a Write.
  SPI.transfer(B00000100);              // bit 2 set = 1Hz (pin 7) ON
  digitalWrite(chipEnablePin, LOW);     // All done so take the Chip Enable LOW.
}


void loop() {
  byte seconds = readRegister(0x00);  
  seconds = bcd2dec(seconds);
  if (seconds < 10) {
    Serial.print("0");
  }
  Serial.println(seconds);
  delay(1000);
}

byte readRegister(byte Reg) {
  digitalWrite(chipEnablePin, HIGH);
  SPI.transfer(Reg);
  byte getByte = SPI.transfer(Reg);
  digitalWrite(chipEnablePin, LOW);
  return getByte;
}  

byte bcd2dec(byte value) {
  byte units = value & B00001111;       // We only want bits 0 to 3 so mask off the rest.
  byte tens = (value >> 4) * 10;        // Shift the top 4 bits to the right, 4 times. Then
                                        // multiply by 10 to make decimal 'tens'.
  return  tens + units;                 // Return the sum.
}  

Back to Index | Page 1 | Page 2 | Page 3 | Page 4 | Page 5 |

 


This site and its contents are © Copyright 2005 - All Rights Reserved.