View previous topic :: View next topic |
Author |
Message |
crukid88
Joined: 04 Oct 2007 Posts: 14
|
DS1307 & 16F877 problem: BCD displaying and wrong values |
Posted: Thu Oct 04, 2007 9:09 am |
|
|
I have this code below it has 2 major errors. I have tried to do variety of thought solutions but I haven't still gotten my expected answers. This code is communicating with a DS1307 RTC through I2C protocol. The code below has compiled successfully but when I try to display it on a Parallax serial LCD on 19200 Baud it strangely gives out unexpected output and minutes doesnt increment every 60 seconds. I am still a newbie on using CCS compiler.
At initialization my LCD displays like this:
==============================
Time is :
03 : 01 : 10
==============================
I was wondering why the hour value and minutes didnt follow my assigned values which is hour = 0b01101010 or 10 PM and minutes = 0x20 or 32. The worst part of all is that I couldnt successfully decode BCD of my seconds value. I tried to search already and copied functions like bin2bcd() function in my code but I couldnt really get. This has been halting me for about a month already I am not making progress on my thesis project.
here are the values of seconds during counting:
00...09,16..25,32..41,48..57,64..73,80..89
Pls help me out with this one,here is my code below:
//////////////////////////////////////////////////////////////////////////////
#include "C:\Documents and Settings\Crux\Desktop\Design Thesis Research & Development Files\DS1307 PIC16F877 CCS\DS1307 PIC16F877 CCS.h"
#use rs232(stream=printf,stream=putc,baud=19200, xmit=PIN_C6,rcv=PIN_C7)
#use I2C(master, scl=PIN_C3, sda=PIN_C4)
int bin2bcd(int binary_value);
int time_data[3];
void main()
{
int i;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
// TODO: USER CODE!!
putc(21);
Delay_ms(50);
putc(22);
Delay_ms(50);
putc(17);
putc(128);
printf("Hello World!");
Delay_ms(50);
i2c_start(); // Start condition
i2c_write(0xD0); // Device address write
i2c_write(0x0); // point to seconds register
i2c_write(0b00001010); // sec = 10
i2c_write(0x20); // min = 32
i2c_write(0b01101010); // hr = 10: 12 hour mode PM
i2c_write(0x1); // day = 1 (sun-sat)
i2c_write(0x4); // date = 4
i2c_write(0xA); // month = 10
i2c_write(0x7); // yr = 2007
i2c_write(0b00000000);// control
i2c_stop();
putc(22);
putc(12);
Delay_ms(5);
putc(128);
printf("Time is : ");
do
{
//Loop to assign values to time_data array
for(i=0;i < 3;i++)
{
i2c_start(); // Start condition
i2c_write(0xD0); // Device address write
i2c_write(i); // point to seconds register
i2c_start(); // Start condition
i2c_write(0xD1); // Device address read
time_data[i] = bin2bcd(i2c_read()); // Read datas from DS1307 RAM
i2c_stop();
}
// adjust cursor location of LCD
putc(150);
// print retrieved data to LCD
//Display data into HEX format
// Hour Mins Seconds
printf("%2X : %2X : %2X",time_data[2],time_data[1],time_data[0]);
Delay_ms(50);
}while(1);
}
int bin2bcd(int binary_value)
{
int temp;
int retval;
temp = binary_value;
retval = 0;
while(1)
{
// Get the tens digit by doing multiple subtraction
// of 10 from the binary value.
if(temp >= 10)
{
temp -= 10;
retval += 0x10;
}
else // Get the ones digit by adding the remainder.
{
retval += temp;
break;
}
}
return(retval);
}
//////////////////////////////////////////////////////////////////////////////// |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
|
crukid88
Joined: 04 Oct 2007 Posts: 14
|
|
Posted: Thu Oct 04, 2007 10:00 am |
|
|
I didnt see the implementation of bin2bcd() and bcd2bin(),is it a built in function in the compiler?My version is 4 |
|
|
crukid88
Joined: 04 Oct 2007 Posts: 14
|
|
Posted: Thu Oct 04, 2007 10:02 am |
|
|
sorry I wasnt able to see it at first,but I see it the function's implementation already. Whats the difference between making a function as defined compared to the used way of declaring a prototype and implementing it?but I still have to test this code,its already late here in my country |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 04, 2007 10:41 am |
|
|
Quote: | for(i=0;i < 3;i++)
{
i2c_start(); // Start condition
i2c_write(0xD0); // Device address write
i2c_write(i); // point to seconds register
i2c_start(); // Start condition
i2c_write(0xD1); // Device address read
time_data[i] = bin2bcd(i2c_read()); // Read datas from DS1307 RAM
i2c_stop();
} |
You're writing your own driver, instead of using an existing working
driver, and you're not following the i2c protocol in the data sheet.
Here's the data sheet:
http://datasheets.maxim-ic.com/en/ds/DS1307.pdf
Look at page 12 of the data sheet:
Quote: |
2. Data transfer from a slave transmitter to a master receiver.
The first byte (the slave address) is transmitted by the master. The
slave then returns an acknowledge bit. This is followed by the slave
transmitting a number of data bytes. The master returns an acknowledge
bit after all received bytes other than the last byte. At the end of
the last received byte, a “not acknowledge” is returned. |
Also look at Figure 5 (on page 12):
It shows the last byte read has a "Not Acknowledge" after it. This is
shown as the letter 'A' with a bar on top of it.
In CCS, a NAK is done by giving a 0x00 parameter to the i2c_read()
function. Example:
Quote: | data = i2c_read(0); |
This is in the CCS manual.
My advice is:
1. Use an existing working driver if one is available.
2. If you want to write your own driver, read the data sheet, in detail.
3. Also, look at other drivers to make sure you're doing it correctly. |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
|
|