The Bachelor's thesis - Design and implementation of a portable device for creating RFID tag lists
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

202 lines
4.3 KiB

#include "Arduino.h"
#include "DS1302.h"
Time::Time(const uint16_t yr, const uint8_t mon, const uint8_t date,
const uint8_t hr, const uint8_t min, const uint8_t sec,
const Day day) {
this->yr = yr;
this->mon = mon;
this->date = date;
this->hr = hr;
this->min = min;
this->sec = sec;
this->day = day;
}
DS1302::DS1302(const uint8_t ce_pin, const uint8_t io_pin,
const uint8_t sclk_pin) {
ce_pin_ = ce_pin;
io_pin_ = io_pin;
sclk_pin_ = sclk_pin;
pinMode(ce_pin, OUTPUT);
pinMode(sclk_pin, OUTPUT);
}
void DS1302::writeOut(const uint8_t value) {
pinMode(io_pin_, OUTPUT);
shiftOut(io_pin_, sclk_pin_, LSBFIRST, value);
}
uint8_t DS1302::readIn() {
uint8_t input_value = 0;
uint8_t bit = 0;
pinMode(io_pin_, INPUT);
for (int i = 0; i < 8; ++i) {
bit = digitalRead(io_pin_);
input_value |= (bit << i);
digitalWrite(sclk_pin_, HIGH);
delayMicroseconds(1);
digitalWrite(sclk_pin_, LOW);
}
return input_value;
}
uint8_t DS1302::registerBcdToDec(const Register reg, const uint8_t high_bit) {
const uint8_t mask = (1 << (high_bit + 1)) - 1;
uint8_t val = readRegister(reg);
val &= mask;
val = (val & 15) + 10 * ((val & (15 << 4)) >> 4);
return val;
}
uint8_t DS1302::registerBcdToDec(const Register reg) {
return registerBcdToDec(reg, 7);
}
void DS1302::registerDecToBcd(const Register reg, uint8_t value,
const uint8_t high_bit) {
const uint8_t mask = (1 << (high_bit + 1)) - 1;
uint8_t regv = readRegister(reg);
// Convert value to bcd in place.
uint8_t tvalue = value / 10;
value = value % 10;
value |= (tvalue << 4);
// Replace high bits of value if needed.
value &= mask;
value |= (regv &= ~mask);
writeRegister(reg, value);
}
void DS1302::registerDecToBcd(const Register reg, const uint8_t value) {
registerDecToBcd(reg, value, 7);
}
uint8_t DS1302::readRegister(const Register reg) {
uint8_t cmd_byte = 129; // 1000 0001
uint8_t reg_value;
cmd_byte |= (reg << 1);
digitalWrite(sclk_pin_, LOW);
digitalWrite(ce_pin_, HIGH);
writeOut(cmd_byte);
reg_value = readIn();
digitalWrite(ce_pin_, LOW);
return reg_value;
}
void DS1302::writeRegister(const Register reg, const uint8_t value) {
uint8_t cmd_byte = (128 | (reg << 1));
digitalWrite(sclk_pin_, LOW);
digitalWrite(ce_pin_, HIGH);
writeOut(cmd_byte);
writeOut(value);
digitalWrite(ce_pin_, LOW);
}
void DS1302::writeProtect(const bool enable) {
writeRegister(kWriteProtectReg, (enable << 7));
}
void DS1302::halt(const bool enable) {
uint8_t sec = readRegister(kSecondReg);
sec &= ~(1 << 7);
sec |= (enable << 7);
writeRegister(kSecondReg, sec);
}
uint8_t DS1302::seconds() {
return registerBcdToDec(kSecondReg, 6);
}
uint8_t DS1302::minutes() {
return registerBcdToDec(kMinuteReg);
}
uint8_t DS1302::hour() {
uint8_t hr = readRegister(kHourReg);
uint8_t adj;
if (hr & 128) // 12-hour mode
adj = 12 * ((hr & 32) >> 5);
else // 24-hour mode
adj = 10 * ((hr & (32 + 16)) >> 4);
hr = (hr & 15) + adj;
return hr;
}
uint8_t DS1302::date() {
return registerBcdToDec(kDateReg, 5);
}
uint8_t DS1302::month() {
return registerBcdToDec(kMonthReg, 4);
}
Time::Day DS1302::day() {
return static_cast<Time::Day>(registerBcdToDec(kDayReg, 2));
}
uint16_t DS1302::year() {
return 2000 + registerBcdToDec(kYearReg);
}
Time DS1302::time() {
return Time(year(), month(), date(),
hour(), minutes(), seconds(),
day());
}
void DS1302::seconds(const uint8_t sec) {
registerDecToBcd(kSecondReg, sec, 6);
}
void DS1302::minutes(const uint8_t min) {
registerDecToBcd(kMinuteReg, min, 6);
}
void DS1302::hour(const uint8_t hr) {
writeRegister(kHourReg, 0); // set 24-hour mode
registerDecToBcd(kHourReg, hr, 5);
}
void DS1302::date(const uint8_t date) {
registerDecToBcd(kDateReg, date, 5);
}
void DS1302::month(const uint8_t mon) {
registerDecToBcd(kMonthReg, mon, 4);
}
void DS1302::day(const Time::Day day) {
registerDecToBcd(kDayReg, static_cast<int>(day), 2);
}
void DS1302::year(uint16_t yr) {
yr -= 2000;
registerDecToBcd(kYearReg, yr);
}
void DS1302::time(const Time t) {
seconds(t.sec);
minutes(t.min);
hour(t.hr);
date(t.date);
month(t.mon);
day(t.day);
year(t.yr);
}