• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Problems using 16F877 and DS1307 with I2C

Status
Not open for further replies.

pmsantos

New Member
Hi everyone!

I’m trying to connect a pic16F877 with a DS1307 using I2C, but I’m getting some problems, and I can’t find what I’m doing wrong.

I’m using the next program.

Init_I2C:
movlw b'00101000'
movwf SSPCON
call membank1
bsf PORTC,sda
bsf PORTC,scl ; asegura que as portas estam a input
bcf SSPSTAT,7 ;Enabled slew rate
clrf SSPCON2
movlw BRG
movwf SSPADD ; Configura 100khz I2C clock a 4Mhz
call membank0
return

StartI2C:
call membank1
bsf SSPCON2,0
btfsc SSPCON2,0
goto $-1
call membank0
return

StopI2C:
call membank1
bsf SSPCON2,2
btfsc SSPCON2,2
goto $-1
call membank0
return

RestartI2C:
call membank1
bsf SSPCON2,1
btfsc SSPCON2,1
goto $-1
call membank0
return



Txbyte:
movwf SSPBUF
call membank1
bsf SSPCON2,6
btfsc SSPSTAT,2
goto $-1
btfsc SSPCON2,6
goto $-1
call membank0
return


Rxbyte:
;clrf SSPBUF
call membank1
bsf SSPCON2,3
btfsc SSPCON2,3
goto $-1
call membank0
movf SSPBUF,0
return


SetDSpointer:
call StartI2C
movlw DSaddress
call Txbyte
movf pointeradd,0
call Txbyte
call StopI2C
return


ACK:
call membank1
bcf SSPCON2,5
bsf SSPCON2,4
btfsc SSPCON2,4
goto $-1
call membank0
return

NACK:
call membank1
bsf SSPCON2,5
bsf SSPCON2,4
btfsc SSPCON2,4
goto $-1
call membank0
return


I2cinforead:
;call Wait_T1_1ms
call StartI2C
movlw DSaddress
call Txbyte
movf pointeradd,0
call Txbyte
call RestartI2C
movlw DSaddress+1
call Txbyte
call membank1
call Rxbyte
movwf DS_data
call NACK
call StopI2C
return

DSaddress =0D0h
Pointeradd = 00h
BRG= 9h


In attachement is the circuit that I’m using to test the communication. Hope that is noting wrong with it.


I had make a simulation in Proteus and I can’t get any data from de DS1307.

The 1º memory address from DS1307 should be save to the DS_data register but instead I only get 00000000, even running the simulation for over then 1 min.


Did anyone can tell me what I’m doing wrong??


Tanks!!
 

Attachments

ericgibbs

Well-Known Member
Most Helpful Member
hi,
Please post the complete program so that we can run it.:)

Also when you post the asm file, use the 'Manage Attachments' button lower down the post reply page.
 

pmsantos

New Member
Problem solved

The program only was reading de second address from de DS1307 and displaying the bits in an lcd,

I was running the program in a loop (reading, displaying, reading, displaying,…) and the loop was to fast, just put a 1ms delay after each loop and it work fine.


But seem that’s not all, simulating the circuit in Proteus, it only work if i add an I2C Debugger to the circuit, I don’t know why but it work, maybe this can someone that is having trouble with I2C and Proteus.


Tanks for the help.
 
Last edited:

engineerfaisal

New Member
DS1307 Interface Issues

Hello,

As you have mentioned that you have interfaced ds1307 with 89c..

Thats why I am contacting you. Can you look at my code and guess what i am doing wrong with my code.

I cannot read neither write to ds1307.

connected through port d bits 5 and 6

crystall oscillator 10Mhz but using hspll

have pull up resistors on both lines sda and scl



//************************************************************************************//
//************************************************************************************//
// //
// Header: 8722 Project //
// PIC used: PIC18F8722 //
// Start Date: 1st Dec 2009
// Function for I2C //
//************************************************************************************//
//************************************************************************************//
//** HEADER FILES ********************************************************************/
#include <p18F8722.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <usart.h>
#include <timers.h>
#include <delays.h>
#include <i2c.h>
//** CONFIGURATION BITS **************************************************************/
#pragma config OSC = HSPLL
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config DEBUG = ON
//** FUNCTION PROTOTYPES *************************************************************/
void Init_Ports(void);
void Configure_I2C2(void);

void I2C2_Write(unsigned char Add, unsigned char Data);
void Write(unsigned char Input_Data);
unsigned char I2C2_Read(unsigned char add);

void SCL_high(void);
void SCL_low(void);
//** DEFINITIONS *********************************************************************/
#define IniDs1307 0x00
#define AddRDs1307 0xD1
#define AddWDs1307 0xD0
#define CLEAR 0
#define SET 1
#define BRGValue 0x63

//** GLOBALS *************************************************************************/

unsigned char Second, Minutes, Hours, Day, Date, Month, Year;
//** MAIN CODE ***********************************************************************/
void main(void)
{
Init_Ports();
Configure_I2C2 ();


I2C2_Write(0x07,0x00); // control register add 07, 00 as i am not using swqe, rs0, rs1

I2C2_Write(0x00,0x05);// control register for seconds,also CH=0 initialized for first time (bit 7), add = 0x00, value assigned 0x05
I2C2_Write(0x01,0x07);// control register for minutes, add = 0x01, value assigned 0x07 (just to see whther the RTC works)
I2C2_Write(0x02,0x06);// control register for Hours, add = 0x02, value assigned 0x06

I2C2_Write(0x03,0x02);// control register for Day, add = 0x03, value assigned 0x02

I2C2_Write(0x04,0x03);// control register for Day, add = 0x04, value assigned 0x03
I2C2_Write(0x05,0x02);// control register for Month, add = 0x05, value assigned 0x02
I2C2_Write(0x06,0x04);// control register for Year, add = 0x06, value assigned 0x04

Second = I2C2_Read(0x00);
Minutes = I2C2_Read(0x01);
Hours = I2C2_Read(0x02);

Day = I2C2_Read(0x03);
Date = I2C2_Read(0x04);
Month = I2C2_Read(0x05);
Year = I2C2_Read(0x06);
StopI2C2();

while(SET)
{
Nop();
}
}

//*************************************************************************************
void Init_Ports(void)
{
PORTD = CLEAR;
LATD = 0b01100000;
TRISD = 0b01100000; // intialized RD6(SCL2) AND RD5(SDA2).
}
//*************************************************************************************
void Configure_I2C2 (void)
{
SSP2CON1 = 0b00001000;
SSP2STAT = 0b10000000;
SSP2ADD = 0x63;

//SSP2ADD = (BYTE) _I2C_BAUD_COUNT;
SSP2CON2bits.ACKSTAT = 1;
SSP2CON1bits.SSPEN = 1;
OpenI2C2(MASTER, SLEW_OFF);
}
//***********************************writes data to add***************************************************
void I2C2_Write(unsigned char Add, unsigned char Data)
{
PIR3bits.SSP2IF= CLEAR;

StartI2C2();

Write(0xD0);
IdleI2C2();

Write(Add);
IdleI2C2();

Write(Data);
IdleI2C2();

StopI2C2();
}
//***********************function of write***********************************
void Write(unsigned char Input_Data)
{
unsigned char data, i, Outbit;
data = Input_Data;

for (i = 0; i <= 7; i++)
{
Outbit=data&0x80;
PORTDbits.RD5 = Outbit;
data = data << 1;
SCL_high();
SCL_low();
}

while (SSP2CON2bits.ACKSTAT == 1) { }



}
//**************reads add and returs data**********************************
unsigned char I2C2_Read(unsigned char add)
{
unsigned char dataa;

StartI2C2();
Write(0xd1); // to write
IdleI2C2();



Write(add); // address to read
IdleI2C2();



if (DataRdyI2C2())
{
getcI2C2();
}
dataa = SSP2BUF;

while (SSP2CON2bits.ACKSTAT == 1) { }
PIR1bits.SSPIF = 0; // clear flag


NotAckI2C2();
StopI2C2();

//dataa = (dataa & 0x0f) + (dataa>>4)*10; // chuyenthanh so thap phan
return (dataa);
}
//*************************************************
void SCL_high(void)
{
PORTDbits.RD6 = 1;
Delay1KTCYx(1000);
}

//*************************************************
void SCL_low(void)
{
PORTDbits.RD6= 0;
Delay1KTCYx(1000);
}
 

Shamanth

New Member
hi, please help me send the complete asm source code along with header file for "RTC using PIC 16F877A and DS1307". Even i am working on the same circuit which you had attached in your post. Please provide complete details from A to Z so that i can make it work on my side as well....i am very new to this and have to complete this project for my examination...kindly help.

Reply me back on [email protected]
 

Shamanth

New Member
ASM Source Code and Header file for project "RTC using PIC 16F877A and DS1307"

hi, please help me send the complete asm source code along with header file for "RTC using PIC 16F877A and DS1307". Even i am working on the same circuit which you had attached in your post. Please provide complete details from A to Z so that i can make it work on my side as well....i am very new to this and have to complete this project for my examination...kindly help.

Reply me back on [email protected]
 

engineerfaisal

New Member
ds1307 c coding pic18f8722

//************************************************************************************//
//************************************************************************************//
// Project: //
// Header: 8722 Project //
// PIC used: PIC18F8722 //
// Start Date: 1st Dec 2009 //
// Function for I2C2 //
// the interface of DS1307 with Pic18f8722 //
// Backup power by lithium battery(3.3v) //
// Microcontroller is in master mode, I2c has been designed for 100Khz, //
// I have connected pullup resistors(2.2 Kohm Each) with the SDA and SCl lines, //
// 32Khz Crystal oscillator for DS1307 //
//************************************************************************************//
//************************************************************************************//
//** HEADER FILES ********************************************************************/
#include <p18F8722.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <usart.h>
#include <timers.h>
#include <delays.h>
#include <i2c.h>
//** CONFIGURATION BITS **************************************************************/
#pragma config OSC = HSPLL
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config DEBUG = ON
//** FUNCTION PROTOTYPES *************************************************************/
void Init_Ports(void);
void Configure_I2C2(void);
void Day_Decision (void);
//** DEFINITIONS *********************************************************************/
#define ControlByte 0xD0 //Control is always D0 for reads (& D1 for writes)
#define CLEAR 0
#define SET 1
#define BRGValue 0x63
//** GLOBALS *************************************************************************/
unsigned char Second =0x00, Minutes=0x59, Hours=0x23, Days=0x7, Date=0x31, Month=0x12, Year=0x09;
unsigned char Day,Sec,Min,Hr,Dy,Dat,Mon,Ye;
unsigned char Monday,Tuesday,Wenesday,Thursday,Friday,Saturday,Sunday;
//** MAIN CODE ***********************************************************************/
void main(void)
{
Init_Ports();
Configure_I2C2 ();
EEByteWrite2( ControlByte, 0x07 , 0x00); // control byte 0x00;
EEByteWrite2( ControlByte, 0x00 , Second);
EEByteWrite2( ControlByte, 0x01 , Minutes);
EEByteWrite2( ControlByte, 0x02 , Hours);
EEByteWrite2( ControlByte, 0x03 , Days);
EEByteWrite2( ControlByte, 0x04 , Date);
EEByteWrite2( ControlByte, 0x05 , Month);
EEByteWrite2( ControlByte, 0x06 , Year);

while(SET)
{
Sec = EERandomRead2( 0xD0, 0x00 );
Min = EERandomRead2( 0xD0, 0x01 );
Hr = EERandomRead2( 0xD0, 0x02 );
Days= EERandomRead2( 0xD0, 0x03 );
Dat= EERandomRead2( 0xD0, 0x04 );
Mon = EERandomRead2( 0xD0, 0x05 );
Ye= EERandomRead2( 0xD0, 0x06 );
Day_Decision ();
}
}
//*************************************************************************************
void Init_Ports(void)
{
PORTD = CLEAR;
LATD = 0b01100001;
TRISD = 0b01100001; // intialized RD6(SCL2) AND RD5(SDA2).
}
//*************************************************************************************
void Configure_I2C2 (void)
{
SSP2STAT = 0x80; //Disable SMBus &
SSP2CON1 = 0x28; //Enable MSSP Master
SSP2CON2 = 0x00; //Clear MSSP Conrol Bits
SSP2ADD = 0x63;
}
///********************************************************************
* Function Name: WriteI2C2 *
* Return Value: Status byte for WCOL detection. *
* Parameters: Single data byte for I2C2 bus. *
* Description: This routine writes a single byte to the *
* I2C2 bus. *
********************************************************************/
unsigned char WriteI2C2( unsigned char data_out )
{
SSP2BUF = data_out; // write single byte to SSP2BUF
if ( SSP2CON1bits.WCOL ) // test if write collision occurred
return ( -1 ); // if WCOL bit is set return negative #
else
{
while( SSP2STATbits.BF ); // wait until write cycle is complete
return ( 0 ); // if WCOL bit is not set return non-negative #
}
}
///*********************************************************************
* Function Name: EERandomRead2 *
* Return Value: error condition status and/or data byte *
* Parameters: EE memory control byte with R/W set to 1 *
* Description: Reads 1 byte from passed address to EE memory*
* device. This routine can be used for any I2C *
* EE memory device, which only uses 1 byte of *
* address data as in the 24LC01B/02B/04B/08B. *
* *
*********************************************************************/
unsigned int EERandomRead2( unsigned char control, unsigned char address )
{
IdleI2C2(); // ensure module is idle
StartI2C2(); // initiate START condition
while ( SSP2CON2bits.SEN ); // wait until start condition is over
if ( PIR3bits.BCL2IF ) // test for bus collision
{
return ( -1 ); // return with Bus Collision error
}
else
{
if ( WriteI2C2( control ) ) // write 1 byte
{
return ( -3 ); // return with write collision error
}

IdleI2C2(); // ensure module is idle
if ( !SSP2CON2bits.ACKSTAT ) // test for ACK condition, if received
{
if ( WriteI2C2( address ) ) // WRITE word address for EEPROM
{
return ( -3 ); // return with write collision error
}

IdleI2C2(); // ensure module is idle
if ( !SSP2CON2bits.ACKSTAT ) // test for ACK condition, if received
{
RestartI2C2(); // generate I2C bus restart condition
while ( SSP2CON2bits.RSEN );// wait until re-start condition is over
if ( PIR3bits.BCL2IF ) // test for bus collision
{
return ( -1 ); // return with Bus Collision error
}

if ( WriteI2C2( control+1 ))// write 1 byte - R/W bit should be 1
{
return ( -3 ); // return with write collision error
}

IdleI2C2(); // ensure module is idle
if ( !SSP2CON2bits.ACKSTAT )// test for ACK condition, if received
{
SSP2CON2bits.RCEN = 1; // enable master for 1 byte reception
while ( SSP2CON2bits.RCEN ); // check that receive sequence is over
NotAckI2C2(); // send ACK condition
while ( SSP2CON2bits.ACKEN ); // wait until ACK sequence is over
StopI2C2(); // send STOP condition
while ( SSP2CON2bits.PEN ); // wait until stop condition is over
if ( PIR3bits.BCL2IF ) // test for bus collision
{
return ( -1 ); // return with Bus Collision error
}
}
else
{
return ( -2 ); // return with Not Ack error
}

}
else
{
return ( -2 ); // return with Not Ack error
}
}
else
{
return ( -2 ); // return with Not Ack error
}
}
return ( (unsigned int) SSP2BUF ); // return with data
}
//************************************************************************************
void Day_Decision (void)
{
if (Days ==1) {Dy = Monday;}
if (Days ==2) {Dy = Tuesday;}
if (Days ==3) {Dy = Wenesday;}
if (Days ==4) {Dy = Thursday;}
if (Days ==5) {Dy = Friday;}
if (Days ==6) {Dy = Saturday;}
if (Days ==7) {Dy = Sunday;}
}
 
Status
Not open for further replies.

EE World Online Articles

Loading
Top