Arduino, SPI and the DS1306 RTC | |
Converting BCD to DecimalAs 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. }
|