Microcontroller › 8051 › Can’t get STC12C5A60S2 to talk to DS1302 RTC
- This topic has 1 reply, 1 voice, and was last updated 9 years, 4 months ago by
Wayne.
-
AuthorPosts
-
September 16, 2015 at 1:09 am #3995
Wayne
ParticipantHi everybody. This is my first post on this forum, so please forgive me if I bend a rule or don't use correct formats. In fact, I'm having trouble figuring out this editor… but that's a problem for another day.
Please feel free to point me toward the forum rules if necessary…
I bought a "development board" on eBay, and have been slowly figuring out how to program it. But I've hit quite a stumbling block with the DS1302 Real-Time-Clock. I simply cannot get the code to work. I started by studying sample codes that I found online (mainly here) and — as best as I can tell — my code should do the same thing. But it doesn't. The board is labeled HL-1. According to the schematic, the "CE" line is on pin P2.4, the CLK line is on pin P2.1, and the I/O line is on pin P2.0.
The chip is an STC12C5A60S2; I've also tried it with an STC89C52RC and it does the same thing (nothing).
I debugged the display logic while figuring out how to interface with the keyboard; I'm am 99.9% certain the problem is in the DS1302 code. And I can plug numbers into the code and the numbers will display as expected. It is only when trying to interface with the DS1302 that it displays all zeros. Thus, all I included in this post is the code to interface with the DS1302.
I would like to use the documentation that came with the board to help out but, alas, it's in Chinese!
If one of you code experts could take a quick look at this and tell me what I did wrong, I will be forever grateful!
Here's the DS1302.h file…
************************************************************************************************************
#ifndef RTC_H
#define RTC_H
#include "bsp_cfg.h"
typedef struct
{
INT8U second;
INT8U minute;
INT8U hour;
INT8U date;
INT8U month;
INT8U day;
INT8U year;
} Time_Date;
Time_Date get_time_1302(void);
void set_time_1302(Time_Date dt);void init_1302(void);
#endif***********************************************************************************************************
and here's the DS1302.c code…
***********************************************************************************************************
#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;ACC = 0;
for (i = 8; i > 0; i–)
{
ACC = ACC >> 1;
SCLK_1302 = 1;
ACC7 = IO_1302;
SCLK_1302 = 0;
}
return ACC;
}
static void write_byte(INT8U byte)
{
INT8U i;
ACC = byte;
for (i = 0; i < 8; ++i)
{
IO_1302 = ACC0;
SCLK_1302 = 1;
SCLK_1302 = 0;
ACC = ACC >> 1;
}
}
Time_Date get_time_1302(void)
{
Time_Date dt;
SCLK_1302 = 0;
CE_1302 = 0;
CE_1302 = 1;
write_byte(BURST_READ_1302);
dt.second = read_byte();
dt.minute = read_byte();
dt.hour = read_byte();
dt.date = read_byte();
dt.month = read_byte();
dt.day = read_byte();
dt.year = read_byte();
SCLK_1302 = 0;
CE_1302 = 0;
CE_1302 = 1;
return dt;
}
void set_time_1302(Time_Date dt)
{
SCLK_1302 = 0;
CE_1302 = 0;
CE_1302 = 1;
write_byte(BURST_WRITE_1302);
write_byte(dt.second);
write_byte(dt.minute);
write_byte(dt.hour);
write_byte(dt.date);
write_byte(dt.month);
write_byte(dt.day);
write_byte(dt.year);
write_byte(0);
SCLK_1302 = 0;
CE_1302 = 0;
CE_1302 = 1;
}
void init_1302(void)
{
INT8U byte_second;
INT8U byte_hour;
//Disable Clock Halt
SCLK_1302 = 0;
CE_1302 = 0;
CE_1302 = 1;
write_byte(SECONDS_READ_1302);
byte_second = read_byte();
SCLK_1302 = 0;
CE_1302 = 0;
CE_1302 = 1;
write_byte(SECONDS_WRITE_1302);
write_byte(byte_second & 0x7f);
SCLK_1302 = 0;
CE_1302 = 0;
CE_1302 = 1;
//Set to 24 hour mode
write_byte(HOURS_READ_1302);
byte_hour = read_byte();
SCLK_1302 = 0;
CE_1302 = 0;
CE_1302 = 1;
write_byte(HOURS_WRITE_1302);
write_byte(byte_hour & 0x7f);
SCLK_1302 = 0;
CE_1302 = 0;
CE_1302 = 1;
//Disable Write Protection
write_byte(WP_WRITE_1302);
write_byte(0);
SCLK_1302 = 0;
CE_1302 = 0;
CE_1302 = 1;
}**********************************************************************************************************
Thank you!
Wayne.
September 23, 2015 at 12:54 am #13311Wayne
ParticipantWell… 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;
}**********************************************************************************************************
-
AuthorPosts
- You must be logged in to reply to this topic.