Microcontroller › PIC › INTERFACING DS1307 RTC WITH PIC16F887 VIA I2C.
- This topic has 2 replies, 3 voices, and was last updated 6 years ago by Ashutosh Bhatt.
-
AuthorPosts
-
December 28, 2016 at 4:54 pm #4591NAVEEN JOSEPHParticipant
friends,
I am trying to interface DS1307 RTC with pic16f887 controller via i2c.. while simulation i got the time and date.. but the problem is I have to write this time to my LCD… in this program I am trying to write the "hour" value to LCD..
but nothing visible in LCD… please help me..please checkout the attachment and MPLABx code too…
PIC clock= 20Mhz
I²C clock= 100Khz
DS1307 address= 1101000
I AM NOT SURE THAT THE CODES I WRITTEN INSIDE FUNCTION –>ds1307_read() is right or wrong…please help
Actually in code I am trying to display the value of "hour" in LCD.. using functions bcd2lowerch and bcd2upperch
when I tried to debug my code in proteus::—>>>
1). when I debugged the function call-> hour=ds1307_read(0x02), inside the function, returning value of x is equal to 2. which means the address-> 0x02 which is passing as the parameter in function hour=ds1307_read(0x02), is stored inside SSPBUF and returning as such… which means a right read from the hour register of ds1307, is not taking place…
2).Similarly, when I debugged the function call-> minutes = ds1307_read(0x01);inside the function, returning value of x is equal to 1. which means the address-> 0x01 which is passing as the parameter in function minutes = ds1307_read(0x01), is stored inside SSPBUF and returning as such… which means a right read from the minute register of ds1307, is not taking place…
3).Similarly, when I debugged the function call-> seconds = ds1307_read(0x00);inside the function, returning value of x is equal to 0. which means the address-> 0x00 which is passing as the parameter in function seconds = ds1307_read(0x00), is stored inside SSPBUF and returning as such… which means a right read from the second register of ds1307, is not taking place…please checkout the 2 attached images
________________________MPLAB CODE______________________________________
#include <stdio.h>
#include <stdlib.h>
#include<htc.h>
#define _XTAL_FREQ 20000000 //20Mhz
#define RS RC5
#define RW RC6
#define E RC7
__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & MCLRE_OFF & CP_OFF & CPD_OFF & BOREN_ON & IESO_ON & FCMEN_ON & LVP_OFF);
__CONFIG(BOR4V_BOR40V & WRT_OFF);
void init_i2c(void);
void ds1307_init(void);
void ds1307_write(unsigned char ,unsigned char);
unsigned short ds1307_read(unsigned short);
void wait_mssp(void);
void init_lcd();
void set_command(unsigned char);
void set_data(unsigned char *);
unsigned short seconds,minutes,hour;
unsigned short x;
unsigned char hourVal[5]={0};
unsigned char hourVal1[5]={0};
unsigned short a;
unsigned short b;
unsigned char bcd2upperch(unsigned char bcd);
unsigned char bcd2lowerch(unsigned char bcd);
void main(){
PORTD =0x00;
TRISD =0x00;
TRISC5 =0;
TRISC6 =0;
TRISC7 = 0;
init_lcd();
__delay_ms(100);
init_i2c();
__delay_ms(100);
while(1){
seconds = ds1307_read(0x00);
minutes = ds1307_read(0x01);
hour = ds1307_read(0x02);
a = bcd2lowerch(hour);
b = bcd2upperch(hour);
sprintf(hourVal,"hour=%d",b); //sprintf used to get output as string
sprintf(hourVal1,"%d",a);
set_command(0x80); //force cursor to begin in 1st line of LCD
set_data(hourVal);
set_data(hourVal1);
__delay_ms(1000);
}
}
unsigned char bcd2upperch(unsigned char bcd)
{
return((bcd >> 4) + '0');
}
unsigned char bcd2lowerch(unsigned char bcd)
{
return((bcd & 0x0f) + '0');
}
void init_i2c(void){
SSPSTAT=0x00;
SSPCON=0x00;
SSPCON2=0x00;
SSPADD=0x00;
PORTC=0x00;
TRISC3 =1;
TRISC4 =1;
SSPCON = 0b00101000;//0x28 i2c master mode
SSPADD = 0x31;//decimal–49.//value for SSPADD found using eqn–> clock =Fosc/ 4*(SSPADD +1); clock–100Khz, Fosc =20Mhz
SSPSTAT = 0b10000000; //0x80
TRISC3 =1;
TRISC4 =1;
ds1307_write(0,0×00);
}
unsigned short ds1307_read(unsigned short addr){
RCEN =1;
wait_mssp();
SSPBUF =0b11010000; //slave address(address of ds1307) + write bit;
wait_mssp();
SSPBUF =addr;
wait_mssp();
RSEN =1;
SSPBUF =0b11010001; //slave address(address of ds1307) + read bit;
wait_mssp();
ACKDT=1;
ACKEN =1;
PEN=1;
wait_mssp();
x = SSPBUF;
return x;
}
void ds1307_write(unsigned char addr ,unsigned char data){
SEN =1; //Start bit
wait_mssp();
SSPBUF = 0b11010000; //slave address(address of ds1307) + write bit
wait_mssp();
SSPBUF =addr;
wait_mssp();
SSPBUF = data;
wait_mssp();
PEN =1; //stop bit
wait_mssp();
}
void wait_mssp(void){
while(!SSPIF);
SSPIF =0;
}
void init_lcd(){
set_command(0x01); //display clear
set_command(0x38); //Function set — 8bit data and 2lines
set_command(0x0C); //display ON cursor ON BLINK off
set_command(0x06); //Increment cursor–shift display to RIGHT
set_command(0x0E); //DISPLAY ON CURSOR BLINK
set_command(0x80); //force cursor to begin in 1st line
}
void set_command(unsigned char command){
RS = 0; //command
RW = 0; //write
PORTD=command;
E =1;
__delay_ms(100);
E =0;
}
void set_data(unsigned char *a){
RS = 1; //data
RW =0; // write
while(*a)
{
PORTD = *a;
E =1;
__delay_ms(100);
E =0;
a++;
}
}January 11, 2019 at 10:13 am #15006sumitParticipantyou need to follow this sequence as given in the datasheet –
Send Start condition
Transmit address to slave as a write command
Check for ACK from slave
Send data pointer address
Check for ACK from slave
Send Repeated Start condition
Transmit address to slave as a read command
Check for ACK from slave
Set receive enable on PIC
Generate ACK after byte is received
(repeat the previous 2 steps for every byte you want to receive)
Send Stop conditionJanuary 13, 2019 at 12:21 pm #15007Ashutosh BhattParticipantdoes your PIC16F887 supports IIC protocol?
if yes then use built in hardware and software like use direct instructions to read and send data to DS1307
if not then please read IIC protocol in detail go through some examples and then try again
-
AuthorPosts
- You must be logged in to reply to this topic.