|
|
View previous topic :: View next topic |
Author |
Message |
ghostmanzero
Joined: 01 Jan 2017 Posts: 12
|
ds1302 doesn't work properly. Can anyone help? |
Posted: Sun Mar 12, 2017 9:08 am |
|
|
Hi everyone. I have a problem about ds1302. I'm trying to make a circuit that i can turn on and turn off a led with pwm signal. I print the date and time on lcd.
My code. There are some words which are not in english :D Sorry for that, but this code work on Proteus.
Code: |
#include <16f877A.h> //Kullanılacak pic
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP
#FUSES XT
#use delay(crystal=4MHz)
#define LCD_ENABLE_PIN PIN_B0
#define LCD_RS_PIN PIN_B1
#define LCD_RW_PIN PIN_B2
#define LCD_DATA4 PIN_B4
#define LCD_DATA5 PIN_B5
#define LCD_DATA6 PIN_B6
#define LCD_DATA7 PIN_B7
#define d1 PIN_A0
#define d2 PIN_A1
#define d3 PIN_A2
#define d4 PIN_A3
#define d5 PIN_A5
#define d6 PIN_E0
#define b_sabah PIN_c1
#define b_aksam PIN_d0
#define f_transistor PIN_d1
#include "lcd.c" //lcd ait fonksiyonlar programa eklenir
#include "ds1302.C"
int8 s_saat1;//sabah ilk saat 6
int8 s_saat2;// sabah son saat 8
int8 a_saat1;// aksam ilk saat 5
int8 a_saat2;// aksam son saat 8
int8 saniye,dakika,saat,gun,ay,hafta,yil=0;
int16 a;
int16 b;
void delay_min(b)
{
for(a=0;a<(b*60);a++)
{
delay_ms(1000);
}
}
void lcd()
{
lcd_gotoxy(1,1);
printf(lcd_putc,"%02d/%02d/%02d",gun,ay,yil);
lcd_gotoxy(1,2);
printf(lcd_putc,"%02d:%02d:%02d",saat,dakika,saniye);
lcd_gotoxy(11,1);
switch(hafta)
{
case 1: printf(lcd_putc,"Pzts"); break;
case 2: printf(lcd_putc,"SALI"); break;
case 3: printf(lcd_putc,"CARS"); break;
case 4: printf(lcd_putc,"PERS"); break;
case 5: printf(lcd_putc,"CUMA"); break;
case 6: printf(lcd_putc,"Cmts"); break;
case 7: printf(lcd_putc,"Pzar"); break;
}
}
int yandi1=0;
int yandi2=0;
int turn1=0;
int turn2=0;
int ayar1=1;
int ayar2=1;
int anahtar=0;
void main()
{
lcd_init();
lcd_putc("\f");
rtc_init(); //saat entegresini hazırla
delay_ms(5);
// rtc_set_datetime(24,02,17,05,15,59); //rtc_set_datetime(gun,ay,yil,hafta,saat,dakika); //değişkenleri saat entegresine aktar.
delay_ms(20);
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16,170,1);
while (1)
{
if(input(pin_e2) && anahtar==0) { set_pwm1_duty(0); anahtar=1; }
rtc_get_time(saat,dakika,saniye); rtc_get_date(gun,ay,yil,hafta);
/////////////////sıcaklık dusurme ////////////////////////////////
lcd();
///////////////////////sabah mod ayarı//////////////////////////
if(input(b_sabah))
{
while(input(b_sabah)) {}
ayar1++;
if(ayar1>3) {ayar1=1;}
write_eeprom(1,ayar1);
}
ayar1=read_eeprom(1);
if(ayar1==1){s_saat1=4; s_saat2=7;output_high(d6);output_low(d5);output_low(d4);}// yaz için sabah saati
if(ayar1==2){s_saat1=6; s_saat2=8;output_high(d6);output_high(d5);output_low(d4);}// kış için sabah saati
if(ayar1==3){s_saat1=5; s_saat2=8;output_high(d6);output_high(d5);output_high(d4);}// genel için sabah saati ve sayac sıfırlandı
///////////////////////////////////////////////////////////////////////////////////
/////////////////////////akşam mod ayarı////////////////////////////////////
if(input(b_aksam))
{
while(input(b_aksam)) {}
ayar2++;
if(ayar2>3){ayar2=1;}
write_eeprom(2,ayar2);
}
ayar2=read_eeprom(2);
if(ayar2==1){a_saat1=16; a_saat2=18;output_high(d3);output_low(d2);output_low(d1);}// yaz için sabah saati
if(ayar2==2){a_saat1=18; a_saat2=20;output_high(d3);output_high(d2);output_low(d1);}// kış için sabah saati
if(ayar2==3){a_saat1=17; a_saat2=19;output_high(d3);output_high(d2);output_high(d1);}// genel için sabah saati ve sayac sıfırlandı
////////////////////////////////////////////////////////////////////////////////
//////////////////////akşamdan sabaha//////////////////////////////////////
if ((saat>a_saat2 && saat<=24) || (saat>=0 && saat<s_saat1)){ if(read_eeprom(4)==1){ set_pwm1_duty(170); } if(read_eeprom(4)==0){goto seviyeli_yak;} }
///////////////////////////////////////////////////////////////////////////
////////////////////sabahtan aksama///////////////////////////////////////
if (saat>s_saat2 && saat<a_saat1){if(read_eeprom(3)==1){ set_pwm1_duty(0); } if(read_eeprom(3)==0){goto seviyeli_sondur;} }
////////////////////////////////////////////////////////////////////////////
if(turn2==0 && saat==s_saat2){goto seviyeli_sondur;}
if(turn1==0 && saat==a_saat2){goto seviyeli_yak;}
/////////////akşam saati ayarı///////////////////////////////////////
if(!input(f_transistor) && saat>=a_saat1 && saat<=a_saat2 && turn1==0)
{
seviyeli_yak:
for(int i=0;i<=170;i+=3 ){ //pwm1 ayarları for döngüsü ile arttırılacak
set_pwm1_duty(i);
delay_ms(100);
if(i>165){set_pwm1_duty(170);
turn1 =1;
turn2=0;
yandi1=1;
yandi2=0;
write_eeprom(4,yandi1);
break;
}
}
}
////////////////////////////////////////////////////////////////////
///////////////////sabah saati ayarı///////////////////////////
if(input(f_transistor) && saat>=s_saat1 && saat<=s_saat2 && turn2==0)
{
seviyeli_sondur:
for(int i=170;i>=0;i-=5) { //pwm1 ayarları for döngüsü ile arttırılacak
set_pwm1_duty(i);
delay_ms(100);
if(i<=5) {
set_pwm1_duty(0);
turn1=0;
turn2=1;
yandi2=1;
yandi1=0;
write_eeprom(3,yandi2);
break;
}
}
}
///////////////////////////////////////////////////////////////////////
}
} |
library
Code: | //////////////////////////////////////////////////////////////////////////
//// DS1302.C ////
//// Driver for Real Time Clock ////
//// ////
//// rtc_init() Call after power up////
//// ////
//// rtc_set_datetime(day,mth,year,dow,hour,min) Set the date/time ////
//// ////
//// rtc_get_date(day,mth,year,dow) Get the date ////
//// ////
//// rtc_get_time(hr,min,sec) Get the time ////
//// ////
//// rtc_write_nvr(address,data) Write to NVR ////
//// ////
//// data = rtc_read_nvr(address) Read from NVR ////
//// ////
//// get_bcd(data) Convert data to BCD ////
//// ////
//// rm_bcd(data) Convert data to int ////
//// ////
//////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2003 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
//////////////////////////////////////////////////////////////////////////
#ifndef RTC_SCLK
#define RTC_SCLK PIN_C3
#define RTC_IO PIN_C4
#define RTC_RST PIN_C5
#endif
void write_ds1302_byte(BYTE cmd) {
BYTE i;
for(i=0;i<=7;++i) {
output_bit(RTC_IO, shift_right(&cmd,1,0) );
output_high(RTC_SCLK);
output_low(RTC_SCLK);
}
}
void write_ds1302(BYTE cmd, BYTE data) {
output_high(RTC_RST);
write_ds1302_byte(cmd);
write_ds1302_byte(data);
output_low(RTC_RST);
}
BYTE read_ds1302(BYTE cmd) {
BYTE i,data;
output_high(RTC_RST);
write_ds1302_byte(cmd);
input(RTC_IO);
delay_us(1);
for(i=0;i<=7;++i) {
shift_right(&data,1,input(RTC_IO));
output_high(RTC_SCLK);
delay_us(2);
output_low(RTC_SCLK);
delay_us(2);
}
output_low(RTC_RST);
return(data);
}
void rtc_init() {
BYTE x;
output_low(RTC_RST);
delay_us(2);
output_low(RTC_SCLK);
write_ds1302(0x8e,0);
write_ds1302(0x90,0xa4);
x=read_ds1302(0x81);
if((x & 0x80)!=0)
write_ds1302(0x80,0);
}
byte get_bcd(BYTE data)
{
byte nibh;
byte nibl;
nibh=data/10;
nibl=data-(nibh*10);
return((nibh<<4)|nibl);
}
byte rm_bcd(BYTE data)
{
byte i;
i=data;
data=(i>>4)*10;
data=data+(i<<4>>4);
return data;
}
void rtc_set_datetime(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min) {
write_ds1302(0x86,get_bcd(day));
write_ds1302(0x88,get_bcd(mth));
write_ds1302(0x8c,get_bcd(year));
write_ds1302(0x8a,get_bcd(dow));
write_ds1302(0x84,get_bcd(hr));
write_ds1302(0x82,get_bcd(min));
write_ds1302(0x80,get_bcd(0));
}
void rtc_get_date(BYTE& day, BYTE& mth, BYTE& year, BYTE& dow) {
day = rm_bcd(read_ds1302(0x87));
mth = rm_bcd(read_ds1302(0x89));
year = rm_bcd(read_ds1302(0x8d));
dow = rm_bcd(read_ds1302(0x8b));
}
void rtc_get_time(BYTE& hr, BYTE& min, BYTE& sec) {
hr = rm_bcd(read_ds1302(0x85));
min = rm_bcd(read_ds1302(0x83));
sec = rm_bcd(read_ds1302(0x81));
}
void rtc_write_nvr(BYTE address, BYTE data) {
write_ds1302(address|0xc0,data);
}
BYTE rtc_read_nvr(BYTE address) {
return(read_ds1302(address|0xc1));
} |
I think problem is not about the code. I did solder carefully. but it didnt work :/
here it is my problem :D it doesnt show the date and time.
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Sun Mar 12, 2017 10:14 am |
|
|
Break your program into workable sections.
having -91 show up for yr,mt,dy,hr,mn,se is a clear indication 'something' is wrong. Not sure where -91 comes from...
I'd delete all the 'LED' code and see IF the LCD will display your 'default' RTC data, properly.
If it does THEN send those numbers to the RTC, then read them back and display on LCD. If they are NOT correct...'something' is wrong either wiring or code (though the CCS driver is good).
I understand the language barrier, so it is important to take small steps. Get one portion working, build upon that.
Jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
ghostmanzero
Joined: 01 Jan 2017 Posts: 12
|
|
Posted: Sun Mar 12, 2017 4:11 pm |
|
|
Thank you for the answer. I have already changed the battery. I use a CR2032 3V battery. Also i did the pull up resistors for rst, sclk and İo. But it still doesn't work :/ |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Mar 12, 2017 4:21 pm |
|
|
Check the wiring. Your schematic doesn't show a ground connection on
pin 4 of the ds1302. There needs to be such a connection.
Make sure the RST, SCLK, and IO pins are connected to the correct pins
on the PIC.
Also, you could post a sharp, clear, hi-res, in-focus photo of your
breadboard. Then we could see the connections. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Sun Mar 12, 2017 4:27 pm |
|
|
1) That device has internal pull down resistors of about 40K, so pullups are not required (that I know of...)
2) Try writing and reading some of the 31 RAM locations. If the data read back is correct, then wiring is OK and chip has 5 volts.
3) Get rid of all the 'other' code (LED and conditionals). Have just enough to set the RTC and read it back. Simplify......
4) Try another 32KHx xtal, be sure it's not overheated when soldering it.
Jay |
|
|
ghostmanzero
Joined: 01 Jan 2017 Posts: 12
|
|
Posted: Mon Mar 13, 2017 3:31 am |
|
|
I tried another 32.768 KHz. It didn't work. I removed the pull ups. And i soldered 4.7k resistors to sclk, rst and io as pull down. After this when I power it, now it shows
00/00/00
00:00:00
It doesn't change. I don't know where the mistake is :D it doesn't make sense to me :D
Any other suggestions? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Mon Mar 13, 2017 5:18 am |
|
|
1) remove the pull down resistors you added.
2) picture show a 'white breadboard'. Remove RTC and place in a different set of pins.The curent ones might be defective.
3) get rid of ALL code except for RTC, LCD and post.It should be 10-20 lines of code.
something like
...
init_lcd()
init_rtc()
set_rtc();
loop every second
dsp_rtc();
loop every second
... |
|
|
ghostmanzero
Joined: 01 Jan 2017 Posts: 12
|
|
Posted: Mon Mar 13, 2017 5:23 am |
|
|
PROBLEM SOLVED
Thank you for answers
I think problem was with pull downs. As I said, I soldered pull downs and all I could see was 00/00/00 00:00:00.
After that, I tried another ds1302 which I tried before but it was without pull downs. It's solved.
-91/-91/-91 problem solved by adding pull down resistors (4.7k) to sclk, io and ce.
00/00/00 problem solved by using another device ds1302.
Now I have another question guys right now it shows the wrong time and date when I don't set the time (I mean when it works with the default settings). But counting in background works well when I turn it off.
And on the other hand, when I set the time and date, it shows what I set but it doesn't count it when I turn it off. It starts from scratch.
How can I change the default setting? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Mon Mar 13, 2017 11:22 am |
|
|
do you have the battery for backup/power fail wired in ?
without it, RTC stops when power ( 5V) is turned off. It'll restart when power is applied.
Your real program will need some 'test' to decide if it needs to set the RTC or not and obviously NOT load the default values.
jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 13, 2017 1:06 pm |
|
|
ghostmanzero wrote: |
Right now it shows the wrong time and date when I don't set the time (I mean when it works with the default settings). But counting in background works well when I turn it off.
And on the other hand, when I set the time and date, it shows what I set but it doesn't count it when I turn it off. It starts from scratch.
How can I change the default setting?
|
This thread explains how to use an eeprom location to hold a flag
which tells you if the date/time has already been set. This is
what you need. It has sample code at the end:
http://www.ccsinfo.com/forum/viewtopic.php?t=41564 |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Mon Mar 13, 2017 1:21 pm |
|
|
You can also use the RAM located in the RTC. After you set the RTC, write 1 or 2 bytes of known data. Then your main() program can check those. If valid, then RTC has been set. If invalid then RTC is not OK....
just another way to do it...
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Tue Mar 14, 2017 3:14 am |
|
|
On the pullups, read the data sheet:
"At power-up, RST must be a logic 0 until VCC > 2.0V. Also SCLK must be at a
logic 0 when RST is driven to a logic 1 state."
Pulling these signals up with pull-up resistors, will prevent both of these requirements being true. :(
No wonder it doesn't like the resistors.... |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|