Microcontroller › 8051 › Can’t get STC12C5A60S2 to talk to DS1302 RTC › Got it!
Well… in case anyone was wondering… after much trial and error… it appears to be working. Time will tell (pun sortof intended).
Here is the code that seems to work.
**********************************************************************************************************
#include "DS1302 RTC.h"
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
sbit CE_1302 = P2^4; // 1302 CE bit
sbit SCLK_1302 = P2^1; // 1302 Strobe Clock bit
sbit IO_1302 = P2^0; // 1302 IO bit
#define BURST_READ_1302 0xbf
#define BURST_WRITE_1302 0xbe
#define SECONDS_READ_1302 0x81
#define SECONDS_WRITE_1302 0x80
#define HOURS_READ_1302 0x85
#define HOURS_WRITE_1302 0x84
#define WP_WRITE_1302 0x8e
static INT8U read_byte(void)
{
INT8U i, dat;
dat = 0;
for (i = 0; i < 8; i++)
{
dat = dat >> 1;
if (IO_1302 == 1)
dat = dat | 0x80;
SCLK_1302 = 1;
SCLK_1302 = 0;
}
return dat;
}
static void write_byte(INT8U byte)
{
INT8U i, dat;
dat = byte;
SCLK_1302 = 0;
for (i = 0; i < 8; i++)
{
IO_1302 = dat & 0x01;
SCLK_1302 = 1;
SCLK_1302 = 0;
dat = dat >> 1;
}
}
Time_Date get_time_1302(void)
{
Time_Date dt;
CE_1302 = 0;
SCLK_1302 = 0;
CE_1302 = 1;
write_byte(BURST_READ_1302);
dt.second = read_byte();
dt.second = (((dt.second & 0x70) >> 4) * 10) + (dt.second & 0x0f);
dt.minute = read_byte();
dt.minute = (((dt.minute & 0x70) >> 4) * 10) + (dt.minute & 0x0f);
dt.hour = read_byte();
dt.hour = (((dt.hour & 0x70) >> 4) * 10) + (dt.hour & 0x0f);
dt.date = read_byte();
dt.date = (((dt.date & 0x70) >> 4) * 10) + (dt.date & 0x0f);
dt.month = read_byte();
dt.month = (((dt.month & 0x70) >> 4) * 10) + (dt.month & 0x0f);
dt.day = read_byte();
dt.year = read_byte();
dt.year = (((dt.year & 0xf0) >> 4) * 10) + (dt.year & 0x0f);
SCLK_1302 = 1;
CE_1302 = 0;
return dt;
}
void set_time_1302(Time_Date dt)
{
CE_1302 = 0;
SCLK_1302 = 0;
CE_1302 = 1;
write_byte(BURST_WRITE_1302);
write_byte((((dt.second / 10) << 4) + (dt.second % 10)) & 0x7f);
write_byte(((dt.minute / 10) << 4) + (dt.minute % 10));
write_byte((((dt.hour / 10) << 4) + (dt.hour % 10)) & 0x3f);
write_byte(((dt.date / 10) << 4) + (dt.date % 10));
write_byte(((dt.month / 10) << 4) + (dt.month % 10));
write_byte(dt.day);
write_byte(((dt.year / 10) << 4) + (dt.year % 10));
write_byte(0);
SCLK_1302 = 1;
CE_1302 = 0;
}
void init_1302(void)
{
INT8U byte_second;
INT8U byte_hour;
//Disable Clock Halt
CE_1302 = 0;
SCLK_1302 = 0;
CE_1302 = 1;
write_byte(SECONDS_READ_1302);
byte_second = read_byte();
SCLK_1302 = 0;
write_byte(SECONDS_WRITE_1302);
write_byte(byte_second & 0x7f);
SCLK_1302 = 1;
//Set to 24 hour mode
write_byte(HOURS_READ_1302);
byte_hour = read_byte();
SCLK_1302 = 0;
write_byte(HOURS_WRITE_1302);
write_byte(byte_hour & 0x3f);
SCLK_1302 = 0;
//Disable Write Protection
write_byte(WP_WRITE_1302);
write_byte(0);
SCLK_1302 = 0;
CE_1302 = 0;
}
**********************************************************************************************************