![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
jinggy
Joined: 20 May 2008 Posts: 9 Location: malaysia
|
DS1307 |
Posted: Sun Jun 29, 2008 5:15 am |
|
|
hello all.
I tried the DS1307 driver from this link:
http://www.ccsinfo.com/forum/viewtopic.php?t=23255&highlight=ds1307
The only changes I made are as below:
Code: |
#define RTC_SDA PIN_B0
#define RTC_SCL PIN_B1
|
And this is my code.
Code: |
#include <18F4550.h>
#fuses HSPLL,USBDIV,PLL5,CPUDIV1,VREGEN,NOWDT,NOPROTECT,NOLVP
#use delay(clock=48000000) //,RESTART_WDT
#include <ds1307.c>
#include <lcd.c>
#define LCD_RS PIN_D0
#define LCD_RW PIN_D1
#define LCD_E PIN_D2
#define LCD_DB4 PIN_D4
#define LCD_DB5 PIN_D5
#define LCD_DB6 PIN_D6
#define LCD_DB7 PIN_D7
void main()
{
BYTE sec;
BYTE min;
BYTE hrs;
BYTE day;
BYTE month;
BYTE yr;
BYTE dow;
lcd_init();
ds1307_init();
// Set date for -> 29 June 2008 Sunday
// Set time for -> 17:36:09
ds1307_set_date_time(29,6,8,7,17,36,9);
while(1)
{
delay_ms(1000);
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
lcd_putc(sec);
}
}
|
I want to display sec on LCD, but I couldnt get number. Instead I have a black block blinking on my LCD screen. I saw the original codes. It uses #device adc=8 but I didn't use it because when I compile the code, that line caused error.
Anybody has any idea why it's not working?
thanks in advance! |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Jun 29, 2008 6:32 am |
|
|
The returned seconds are ranging from 0 to 59. Writing these to the LCD with a PUTC command means you are writing raw ASCII codes to the lcd, not readable text.
Try something like: Code: | printf(lcd_putc, "\f%d", sec); | the '\f' will clear the screen and the %d converts the seconds to a readable text string.
Quote: | i saw the original codes. it uses #device adc=8 but i didnt use it because when i compile the code, that line caused error. | As long as you don't use the A/D ports you can leave out the above mentioned line. |
|
![](templates/subSilver/images/spacer.gif) |
jinggy
Joined: 20 May 2008 Posts: 9 Location: malaysia
|
|
Posted: Sun Jun 29, 2008 9:37 am |
|
|
thanks ckielstra. it works perfectly now ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
MegatroniC
Joined: 08 Dec 2009 Posts: 35
|
|
Posted: Wed Mar 31, 2010 2:53 am |
|
|
Hello,
I'm sorry I raised old theme.
I also use this driver.
My problem is: call function time_data() from main but I can not go back to main
or at least a few clicks of the button is obtained once.
Is it possible is the time delay?
Code: | void time_data(void)
{
// Set date for -> 15 June 2005 Tuesday
// Set time for -> 15:20:55
//ds1307_set_date_time(15,6,5,2,15,20,55);
do
{
delay_ms(200);
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
printf(lcd_putc, "\f%02d/%02d/%02d\n",day,month,yr);
printf(lcd_putc, "%02d:%02d:%02d", hrs,min,sec);
//lcd_gotoxy(10,2);
//lcd_putc("summer");
}While(!select_click);
} |
thanks ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19366
|
|
Posted: Wed Mar 31, 2010 3:32 am |
|
|
Have you got the pull up resistors on the two I2C lines?.
Without these, the I2C commands will hang, and never return...
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
MegatroniC
Joined: 08 Dec 2009 Posts: 35
|
|
Posted: Wed Mar 31, 2010 4:01 am |
|
|
![](http://j.imagehost.org/t/0196/Clipboard03.jpg) |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Mar 31, 2010 5:23 am |
|
|
Don't connect SQW/OUT (pin 7) of the DS1307 directly to ground. This is an open collector output so probably nothing will be destroyed, but it makes no sense and you are wasting power. Remove the connection to ground and optionally you can get rid of R13 to save a component and a little bit power.
The problem of detecting multiple keys can not be caused by the 200ms delay, this is too short to press multiple keys.
How do you detect the keys? Is it interrupt based?
If possible post the routine for detecting the keys. |
|
![](templates/subSilver/images/spacer.gif) |
MegatroniC
Joined: 08 Dec 2009 Posts: 35
|
|
Posted: Wed Mar 31, 2010 6:00 am |
|
|
Thanks for the tips.
I think the problem comes from the delay and the method of detection of buttons.
But this delay is necessary for ds1307?
I try this:
if(counter>=xxx)
{
...
ds1307_get_time();
...
counter=0;
}
else counter++;
to avoid delay, but did not get.
I use this code for the buttons. |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Mar 31, 2010 11:08 am |
|
|
The delay is not required for the DS1307. You can leave it out if you want and should make no difference. I think the original author put it in to remove stress from the LCD; looping at maximum speed you could be doing thousands of display updates per second and the user most likely sees this as a flickering or dimmed display.
Why update at full speed if the clock only changes state every second?
The routine for scanning the keys works in the background based on a timer interrupt. This should be fine.
Quote: | ... but I can not go back to main or at least a few clicks of the button is obtained once. | This sounds suspicious to me. The switch routine does not support multiple clicks, so what are you doing in your program?
You've made a small error somewhere, and without a complete program it is impossible to tell where.
Post a complete program demonstrating your problem by stripping down your program to a maximum of about 50 lines. If you have not modified the switch.c file you can just include this in your demo program and I'll copy it from the other thread. |
|
![](templates/subSilver/images/spacer.gif) |
MegatroniC
Joined: 08 Dec 2009 Posts: 35
|
|
Posted: Wed Mar 31, 2010 12:10 pm |
|
|
Here's part of it:
Code: | #include <16F917.h>
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES PUT //Power Up Timer
#FUSES PROTECT //Code protected from reads
#FUSES CPD //Data EEPROM Code Protected
#FUSES BROWNOUT //Reset when brownout detected
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NODEBUG //No Debug mode for ICD
#use delay(clock=4MHz)
#define SET_SWITCH_PIN PIN_B7
#define SELECT_SWITCH_PIN PIN_B6
#define SCROLL_SWITCH_PIN PIN_B5
#include <switch.h>
#include <switch.c>
#include <lcd_drv16x2.c>
#include <ds1307Driver.c>
#include <DEF_bits16F914.h>
#define RTCC_PRESET (140)
signed int32 temp;
int1 wink=0;
int1 set_click, select_click, scroll_click;
int1 set_hold;
int8 adc_channel;
BYTE sec;
BYTE min;
BYTE hrs;
BYTE day;
BYTE month;
BYTE yr;
BYTE dow;
=============================================
#int_rtcc
void rtcc_isr(void)
{
set_rtcc(RTCC_PRESET);
update_switch_status();
set_hold=0; set_click=0; select_click=0; scroll_click=0;
if((set_button == SW_HELD)) set_hold=1;
else if(set_button == SW_PRESSED) set_click=1;
else if(select_button == SW_PRESSED) select_click=1;
else if(scroll_button == SW_PRESSED) scroll_click=1;
}
===============================================
void time_data(void)
{
// Set date for -> 15 June 2005 Tuesday
// Set time for -> 15:20:55
//ds1307_set_date_time(15,6,5,2,15,20,55);
do
{
delay_ms(200);
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
printf(lcd_putc, "\f%02d/%02d/%02d\n",day,month,yr);
printf(lcd_putc, "%02d:%02d:%02d", hrs,min,sec);
//lcd_gotoxy(10,2);
//lcd_putc("summer");
}While(!select_click);
}
==============================================
void detect_buttons1(void)
{
if(scroll_click)
{
switch(adc_channel)
{
case 0: adc_channel=1;
break;
case 1: adc_channel=2;
break;
case 2: adc_channel=3;
break;
case 3: adc_channel=0;
}
}
if(select_click) time_data();
if(set_hold) main_menu();
}
=============================================
void main()
{
gc_old_switch_status = read_switches(); // Read and save the initial state of the switches
setup_adc_ports(sAN0|sAN1|sAN2|sAN3|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
setup_spi(SPI_SS_DISABLED);
setup_lcd(LCD_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256); //Setup the RTCC for the 30ms timer tick that runs the multi-tasking.
set_rtcc(RTCC_PRESET);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
portb=0;
porta=0;
portc=0;
trisa=0x0F;
trisb=0xF0;
trisc=0x00;
lcd_init();
ds1307_init();
rb0=1; //BackLight on
lcd_putc(" blablabla ");
delay_ms(1000);
lcd_clear();
clear_interrupt(INT_RTCC);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
While(True)
{
detect_buttons1();
switch(adc_channel)
{
case 0: lcd_gotoxy(1,1);
lcd_putc("temp 1 is: \n");
adc_convert(0,8,'k');
break;
case 1: lcd_gotoxy(1,1);
lcd_putc(" temp 2 is: \n");
adc_convert(1,8,'v');
break;
case 2: lcd_gotoxy(1,1);
lcd_putc(" temp 3 is: \n");
adc_convert(2,8,'t');
break;
case 3: lcd_gotoxy(1,1);
lcd_putc(" temp 4 is:\n");
adc_convert(3,8,'a');
}
}
} |
Push button scroll - shows the temperature for each channel of the ADC.
Hold button set - enter the main menu. In the main menu, push button set - exit from the main menu.
Here to work without problems.
Push button select - shows date and time.
Push button select again - back to displaying the temperature.
But I press once and not returned, press a second time - again not be returned.
Sometimes returned
Sorry for my bad English ![Embarassed](images/smiles/icon_redface.gif) |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Mar 31, 2010 4:19 pm |
|
|
I'm not sure but it might have to do with the frequency you are scanning the switches. You reduced the scan period from 10ms to 30ms. A button is detected as being pressed when at least scanned 2 times. Worst case timing you press the switch just after a scan, resulting in a worst case of almost 90ms. This is slow, a quick button press can be gone by this time.
Then there is the effect of the mechanical switch contacts bouncing. When you press the switch it will not make a perfect contact at once, but vibrate a bit and make several contacts/breaks before settling. This process can take anytime from 1ms up to 50ms, depending on the switch.
For the above reasons I suggest you reduce the scan time from 30ms down again to 10ms as in the original switch.c version.
A second improvement is to reduce the 200ms delay in the display loop. As I said, you can remove the delay at all, but to prevent possible side effects on the display you could do something like this:
Code: | void time_data(void)
{
BYTE sec;
BYTE min;
BYTE hrs;
BYTE day;
BYTE month;
BYTE yr;
BYTE dow;
int8 count;
// Set date for -> 15 June 2005 Tuesday
// Set time for -> 15:20:55
//ds1307_set_date_time(15,6,5,2,15,20,55);
count = 0;
do
{
// Update the display only every 200ms.
if (count%20 == 0)
{
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
printf(lcd_putc, "\f%02d/%02d/%02d\n",day,month,yr);
printf(lcd_putc, "%02d:%02d:%02d", hrs,min,sec);
//lcd_gotoxy(10,2);
//lcd_putc("summer");
}
count++;
delay_ms(10);
} while(!select_click);
} | Note how I moved the date and time variables into the function. By making these variables local to the function you make it more clear to future programmers looking at your code that these variables are only used here. This will help to prevent bugs and the compiler can do better memory optimization. |
|
![](templates/subSilver/images/spacer.gif) |
MegatroniC
Joined: 08 Dec 2009 Posts: 35
|
|
Posted: Wed Mar 31, 2010 11:32 pm |
|
|
Š¢hanks for the advice ckielstra.
Will work on them.
Variables on the time and date I made them global, because I wanted to use them elsewhere. But if it's better to be local in this function will move there and will think of others in their place.
Again, many thanks. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|