|
|
View previous topic :: View next topic |
Author |
Message |
ahmed-agt
Joined: 24 Oct 2014 Posts: 9
|
Reading seconds value from ds1307 skipping with dspic30f4013 |
Posted: Mon Nov 05, 2018 8:22 am |
|
|
Code: | #include <testdspccs.h>
//----LCD Driver and Port
#include <Flex_LCD420.C>
#define USE_RW_PIN 1
#define LCD_BL PIN_D1
//----------FAST = 100000 SDA = PIN_F2, SCL = PIN_F3, FORCE_HW
#define RTC_SDA PIN_F2
#define RTC_SCL PIN_F3
#use I2C(master, SDA = RTC_SDA, SCL = RTC_SCL, FAST = 100000)
//---- Analogue Control Interface
#define AMP_GAIN_SW PIN_A11
#define SENSOR_GND_SW PIN_D9
/*---------------------------------------*/
//---- Variable Names Declaration
char time[] = "TIME: : : ";
char calendar[] = "DATE: / /20 ";
unsigned int16 int_count;
unsigned int8 seconds, second, second10, minute, minute10,
hour, hour10, date, date10, month, month10,
year, year10, day;
#INT_TIMER1
void Timer1_ISR(void)
{
//IFS0 = IFS0 & 0xFFF7;
++int_count;
//if(int_count == 60) int_count = 0;
}
//----------------------------------
//
void ds1307_display(){
second10 = (second & 0x70) >> 4;
second = second & 0x0F;
minute10 = (minute & 0x70) >> 4;
minute = minute & 0x0F;
hour10 = (hour & 0x30) >> 4;
hour = hour & 0x0F;
date10 = (date & 0x30) >> 4;
date = date & 0x0F;
month10 = (month & 0x10) >> 4;
month = month & 0x0F;
year10 = (year & 0xF0) >> 4;
year = year & 0x0F;
time[12] = second + 48;
time[11] = second10 + 48;
time[9] = minute + 48;
time[8] = minute10 + 48;
time[6] = hour + 48;
time[5] = hour10 + 48;
calendar[14] = year + 48;
calendar[13] = year10 + 48;
calendar[9] = month + 48;
calendar[8] = month10 + 48;
calendar[6] = date + 48;
calendar[5] = date10 + 48;
//lcd_gotoxy(1, 1); // Go to column 1 row 1
printf(lcd_putc, time); // Display time
//lcd_gotoxy(1, 2); // Go to column 1 row 2
lcd_putc('\n');
printf(lcd_putc, calendar); // Display calendar
}
void ds1307_write(unsigned int8 address, data_)
{
i2c_start(); // Start I2C
i2c_write(0xD0); // DS1307 address
i2c_write(address); // Send register address
i2c_write(data_); // Write data to the selected register
i2c_stop(); // Stop I2C
}
void ds1307_read()
{
i2c_start(); // Start I2C
i2c_write(0xD0); // DS1307 address
i2c_write(0x00); // Send register address
i2c_start(); // Restart I2C
i2c_write(0xD1); // Initialize data read
second =i2c_read(1); // Read seconds from register 0 second
minute =i2c_read(1); // Read minuts from register 1
hour = i2c_read(1); // Read hour from register 2
day = i2c_read(1); // Read day from register 3
date = i2c_read(1); // Read date from register 4
month = i2c_read(1); // Read month from register 5
year = i2c_read(0); // Read year from register 6
i2c_stop(); // Stop I2C
}
//-------------------------------
void main()
{
int_count = restart_cause();
set_tris_a(0x0000);
set_tris_B(0X01FF);
set_tris_c(0X00);
set_tris_D(0X00);
set_tris_F(0X00);
//----initialising LCD
lcd_init();
output_high(LCD_BL);
lcd_putc('\f');
lcd_putc("Loading......\n");
printf(lcd_putc,"%u", int_count);
delay_ms(5000);
i2c_init(TRUE);
ds1307_write(0x00, 0x03);
/////-------------------------------
lcd_putc('\f');
lcd_putc("Loading......\n"); delay_ms(2000);
int_count = 0;
setup_timer1(TMR_INTERNAL|TMR_DIV_BY_256,65000);
enable_interrupts(INTR_LEVEL1);
set_timer1(0);
enable_interrupts(INT_TIMER1);
//enable_interrupts(INTR_GLOBAL);
while(TRUE)
{
ds1307_read(); // Read data from DS1307 RTCC
//int_count = get_timer1();
lcd_putc('\f');
lcd_putc("testing......\n");
printf(lcd_putc,"%u\n", int_count);
ds1307_display(); // Diaplay time and calendar
delay_ms(500);
output_toggle(AMP_GAIN_SW);
}
} |
Quote: | This attached code is use to interface dspic30f4013 with ds1307. Reading values from the rtc ds1307 was successful accept second value or reading from address 0x00 of the timer. kindly check the code if it is not having a bug. Using CCS 5.070 |
Last edited by ahmed-agt on Mon Nov 05, 2018 8:43 am; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Mon Nov 05, 2018 8:39 am |
|
|
yikes that's really complicated for just reading the RTC every second...
You can do it a whole lot easier... have the RTC generate an interrupt at a 1Hz rate. I've done that for years and none of my project 'skip seconds'.
Also by letting the RTC do it, you free up the timer1 for more important tasks.
As well the formatting to display the date/time is unneccasriy complicated. Use the CCS supplied DS1307 driver !
Jay |
|
|
ahmed-agt
Joined: 24 Oct 2014 Posts: 9
|
Thanks for your respond. |
Posted: Mon Nov 05, 2018 8:50 am |
|
|
Every things works fine timer1 interrupt, date and time. This code works on pic18f and pic16f. But on dspic30f4013, the second is reading zeros.
using mikroc, it work fine with same hardware. |
|
|
ahmed-agt
Joined: 24 Oct 2014 Posts: 9
|
Re: Reading seconds value from ds1307 skipping with dspic30f |
Posted: Mon Nov 05, 2018 9:08 am |
|
|
ahmed-agt wrote: | Code: | #include <testdspccs.h>
//----LCD Driver and Port
#include <Flex_LCD420.C>
#define USE_RW_PIN 1
#define LCD_BL PIN_D1
//----------FAST = 100000 SDA = PIN_F2, SCL = PIN_F3, FORCE_HW
#define RTC_SDA PIN_F2
#define RTC_SCL PIN_F3
#use I2C(master, SDA = RTC_SDA, SCL = RTC_SCL, FAST = 100000)
//---- Analogue Control Interface
#define AMP_GAIN_SW PIN_A11
#define SENSOR_GND_SW PIN_D9
/*---------------------------------------*/
//---- Variable Names Declaration
char time[] = "TIME: : : ";
char calendar[] = "DATE: / /20 ";
unsigned int16 int_count;
unsigned int8 seconds, second, second10, minute, minute10,
hour, hour10, date, date10, month, month10,
year, year10, day;
#INT_TIMER1
void Timer1_ISR(void)
{
//IFS0 = IFS0 & 0xFFF7;
++int_count;
//if(int_count == 60) int_count = 0;
}
//----------------------------------
//
void ds1307_display(){
second10 = (second & 0x70) >> 4;
second = second & 0x0F;
minute10 = (minute & 0x70) >> 4;
minute = minute & 0x0F;
hour10 = (hour & 0x30) >> 4;
hour = hour & 0x0F;
date10 = (date & 0x30) >> 4;
date = date & 0x0F;
month10 = (month & 0x10) >> 4;
month = month & 0x0F;
year10 = (year & 0xF0) >> 4;
year = year & 0x0F;
time[12] = second + 48;
time[11] = second10 + 48;
time[9] = minute + 48;
time[8] = minute10 + 48;
time[6] = hour + 48;
time[5] = hour10 + 48;
calendar[14] = year + 48;
calendar[13] = year10 + 48;
calendar[9] = month + 48;
calendar[8] = month10 + 48;
calendar[6] = date + 48;
calendar[5] = date10 + 48;
//lcd_gotoxy(1, 1); // Go to column 1 row 1
printf(lcd_putc, time); // Display time
//lcd_gotoxy(1, 2); // Go to column 1 row 2
lcd_putc('\n');
printf(lcd_putc, calendar); // Display calendar
}
void ds1307_write(unsigned int8 address, data_)
{
i2c_start(); // Start I2C
i2c_write(0xD0); // DS1307 address
i2c_write(address); // Send register address
i2c_write(data_); // Write data to the selected register
i2c_stop(); // Stop I2C
}
void ds1307_read()
{
i2c_start(); // Start I2C
i2c_write(0xD0); // DS1307 address
i2c_write(0x00); // Send register address
i2c_start(); // Restart I2C
i2c_write(0xD1); // Initialize data read
second =i2c_read(1); // Read seconds from register 0 second
minute =i2c_read(1); // Read minuts from register 1
hour = i2c_read(1); // Read hour from register 2
day = i2c_read(1); // Read day from register 3
date = i2c_read(1); // Read date from register 4
month = i2c_read(1); // Read month from register 5
year = i2c_read(0); // Read year from register 6
i2c_stop(); // Stop I2C
}
//-------------------------------
void main()
{
int_count = restart_cause();
set_tris_a(0x0000);
set_tris_B(0X01FF);
set_tris_c(0X00);
set_tris_D(0X00);
set_tris_F(0X00);
//----initialising LCD
lcd_init();
output_high(LCD_BL);
lcd_putc('\f');
lcd_putc("Loading......\n");
printf(lcd_putc,"%u", int_count);
delay_ms(5000);
i2c_init(TRUE);
ds1307_write(0x00, 0x03);
/////-------------------------------
lcd_putc('\f');
lcd_putc("Loading......\n"); delay_ms(2000);
int_count = 0;
setup_timer1(TMR_INTERNAL|TMR_DIV_BY_256,65000);
enable_interrupts(INTR_LEVEL1);
set_timer1(0);
enable_interrupts(INT_TIMER1);
//enable_interrupts(INTR_GLOBAL);
while(TRUE)
{
ds1307_read(); // Read data from DS1307 RTCC
//int_count = get_timer1();
lcd_putc('\f');
lcd_putc("testing......\n");
printf(lcd_putc,"%u\n", int_count);
ds1307_display(); // Diaplay time and calendar
delay_ms(500);
output_toggle(AMP_GAIN_SW);
}
} |
Quote: | This attached code is use to interface dspic30f4013 with ds1307. Reading values from the rtc ds1307 was successful accept second value or reading from address 0x00 of the timer. kindly check the code if it is not having a bug. Using CCS 5.070 |
|
Please, can any one test this code for bug? Because, it works on other chip, and also on Mikroc. But on dspic30f4013 it return zeros for seconds while other values are ok. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Mon Nov 05, 2018 10:29 am |
|
|
Is Vbat of the DS1307 connected to a good coin cell battery ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Mon Nov 05, 2018 11:23 am |
|
|
You claim the interrupts are working, but they are not enabled in what you post. You have also left out the chip configuration, so we cannot tell if it is setup reasonably.
What clock are you running?.
How is this generated?.
What voltage are you running?.
What pullups on the I2C bus?. |
|
|
ahmed-agt
Joined: 24 Oct 2014 Posts: 9
|
|
Posted: Mon Nov 05, 2018 12:02 pm |
|
|
Ttelmah wrote: | You claim the interrupts are working, but they are not enabled in what you post. You have also left out the chip configuration, so we cannot tell if it is setup reasonably.
What clock are you running?.
How is this generated?.
What voltage are you running?.
What pullups on the I2C bus?. |
Note, the chip is dspic30f4013. to configure the timer1 in interrupt mode, T1IE enable it without the INTR_GLOBAL or the two together. i observed this recently when I am having Trap stack issue.
I reduce the code to only part giving me problem, however all are working accept that seconds issue.
The system running at 64Mhz using 8Mhz crystal with xt_PLL x8.
These is the configuration use from the header file--
Code: |
#include <30F4013.h>
#DEVICE ADC=12
#device ICSP=1
#fuses XT_PLL8
#use delay(clock=64000000,crystal=8000000)
#FUSES MCLR
#FUSES NOWDT //No Watch Dog Timer
//#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOCKSFSM //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES NOBROWNOUT |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Mon Nov 05, 2018 12:12 pm |
|
|
One thing to try. After every I2C_stop() in the code add delay_us(2).
I2C requires a minimum time between an I2C stop and a subsequent I2C start. Typically a couple of uSec. At normal processor speeds the time involved in leaving a routine and entering the next gives enough delay. But at 32MIPS, you probably do not have enough delay.
Update that. Make it delay_us(4). Just checked the datasheet, and the ds1307, requires a minimum of 4.7uSec, so 2uSec is not enough. |
|
|
ahmed-agt
Joined: 24 Oct 2014 Posts: 9
|
|
Posted: Mon Nov 05, 2018 12:19 pm |
|
|
temtronic wrote: | Is Vbat of the DS1307 connected to a good coin cell battery ? |
Button Battery good, minutes and hours are running fine and accurate. |
|
|
ahmed-agt
Joined: 24 Oct 2014 Posts: 9
|
|
Posted: Mon Nov 05, 2018 12:23 pm |
|
|
Ttelmah wrote: | One thing to try. After every I2C_stop() in the code add delay_us(2).
I2C requires a minimum time between an I2C stop and a subsequent I2C start. Typically a couple of uSec. At normal processor speeds the time involved in leaving a routine and entering the next gives enough delay. But at 32MIPS, you probably do not have enough delay.
Update that. Make it delay_us(4). Just checked the datasheet, and the ds1307, requires a minimum of 4.7uSec, so 2uSec is not enough. |
Thank you for these observation. i had done that before but no good outcome since ccs compiler do consider some of this timing issues. However I will retry YOUR suggestion. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Mon Nov 05, 2018 11:47 pm |
|
|
One other thing, your I2C setup should have slow=100000, not fast=100000.
Using 'fast' tells the compiler that the device supports fast timings. The DS1307, doesn't. |
|
|
ahmed-agt
Joined: 24 Oct 2014 Posts: 9
|
|
Posted: Tue Nov 06, 2018 2:14 am |
|
|
Ttelmah wrote: | One other thing, your I2C setup should have slow=100000, not fast=100000.
Using 'fast' tells the compiler that the device supports fast timings. The DS1307, doesn't. |
Thank you for your efforts. The reply i receive from CCS support late yesterday confirm that it is a bug from the compiler version. And the message from CCS -"This issue has been corrected and the fix will be available in the next compiler release we do"
Two suggestions were given as way out, i will post it after testing! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Tue Nov 06, 2018 2:32 am |
|
|
Simple answer then, switch to using software I2C. On your chip this will make no difference at all (software can give over a MHz on a chip at this speed), and will fix the issue. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Tue Nov 06, 2018 6:33 am |
|
|
Another possible solution is to just slow down the clock. Try 8MHz, see if it performs 100%, if so X2 to 16MHz, test,works? great, try 32Mhz....
Unless you're performing a LOT of math, you may not need 64MHz speed.
What's interesting is you said both 16 and 18 series PICs worked fine but...you never said at what speed.
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Tue Nov 06, 2018 8:46 am |
|
|
Well (of course), the fastest PIC18, is only 16MIPS. Given he is running at 32MIPS, there will be big differences.... |
|
|
|
|
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
|