[PIC] Interface PIC24K40 with DS1307 Using MPLAB X IDE

Status
Not open for further replies.

ajit_nayak87

Member level 5
Joined
Oct 30, 2017
Messages
86
Helped
1
Reputation
2
Reaction score
1
Trophy points
8
Activity points
981
Dear all,

I am trying to migrate PIC16F886 Mplab V8.86 to PIC18F24K40 with MPLAB X v3.61.

The Pin configration of Both IC are same. I have working code on PIC16F886 with DS1307. I am trying to communicate DS1307 with PIC18F24K40. I tried Use same syntax .I found slave wont send any acknowledged when master send request.
For PIC18F24K40 using internal Oscilator with 8Mhz clock frequency. I am testing code in I2C slave mode. I could see start bit , followed by slave address. As per Ds1307 datasheet i need to read acknowledge , but i am receiveing no ack signal from device. Kindly help any solution for below issue.




Code C (Mac) - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/i2c1.h"
 
I2C1_MESSAGE_STATUS status = I2C1_MESSAGE_PENDING;
# define LED RC7
 
unsigned int i;
unsigned int count;
unsigned int x;
unsigned short sec;
unsigned short min;
unsigned short hour;
unsigned short date;
unsigned short month;
unsigned short year;
unsigned short day;
unsigned short int temp=0;
unsigned short r_data;
#define Seg1 0x01
#define Seg2 0x02
#define Seg3 0x04
#define Seg4 0x08
#define Seg5 0x10
#define Seg6 0x20
 
#define DS1307_RETRY_MAX  100  // define the retry count
#define DS1307_ADDRESS    0xD0 // slave device address
#define SLAVE_I2C_GENERIC_RETRY_MAX     100       
#define SLAVE_ADDRESS 0X68
  
 
unsigned char SSP_Buffer[16];
 
 
    unsigned int PT_MSG_STATUS;
 
 
 
    void SetSeg(unsigned short data, unsigned  short segno)
    
    { 
                     switch(data) 
                      { 
                          case 0: PORTB = 0x3F; break; 
                          case 1: PORTB = 0x06; break; 
                         case 2: PORTB = 0x5B; break; 
                          case 3: PORTB = 0x4F; break; 
                          case 4: PORTB = 0x66; break;
                          case 5: PORTB = 0x6D; break; 
                          case 6: PORTB = 0x7D; break; 
                          case 7: PORTB = 0x07; break;
                          case 8: PORTB = 0x7F; break; 
                          case 9: PORTB = 0x6F; break; 
                          default : PORTB = 0X00; break;
                     } 
      
              if(segno==1)
                   {
                      PORTA = Seg4; 
                   } 
             if(segno==2)
                   {
                      PORTA = Seg3; 
                   } 
             if(segno==3)
                   {
                      PORTA = Seg2;  
                   } 
             if(segno==4)
                   {
                      PORTA = Seg1;  
                   } 
 
           
     }
    
 
  unsigned int bcdtodecimal(unsigned int bcd) 
{
    unsigned int decimal;
    decimal = (((bcd & 0xF0) >> 4) * 10) + (bcd & 0x0F);
    return decimal;
}
 
 
void ds1307_write(unsigned char addr ,unsigned char data)
{
SSP1CON2bits.SEN =1; 
 
//SSP1BUF = 0XD0; //slave address(address of ds1307) + write bit
SSP1BUF =0X68;
SSP1BUF =addr;
SSP1BUF = data; 
SSP1CON2bits.PEN =1; //stop bit
 
}
 
 
unsigned int ds1307_read(unsigned char addr)
{
SSP1CON2bits.RSEN =1;
 
//SSP1BUF =0XD0; //slave address(address of ds1307) + write bit;
  SSP1BUF =0X68;
SSP1BUF =addr;
 
SSP1CON2bits.RSEN =1;
 
//SSP1BUF =0XD1; //slave address(address of ds1307) + read bit;
 
  SSP1BUF =0X69;
SSP1CON2bits.RCEN =1;
 
SSP1CON2bits.ACKDT=1;
SSP1CON2bits.ACKEN =1;
SSP1CON2bits.PEN=1;
 
x = SSP1BUF;
return (x);
}
 
 
void SetDateTime()
{
           ds1307_write(0X00,0x03);
             ds1307_write(0X01,0X07);
           ds1307_write(0X02,0X00);
              ds1307_write(0X3,0X01);
            ds1307_write(0X04,0x07);
             ds1307_write(0X5,0X08);
           ds1307_write(0X6,0X10);
}
 
void GetDateTime()
{
             sec = ds1307_read(0X00);
               sec=bcdtodecimal(sec);
                 min = ds1307_read(0X01);
              min = bcdtodecimal(min);
                 hour = ds1307_read(0X02);
             hour=bcdtodecimal(    hour);
                 day= ds1307_read(0X03);
                 day = bcdtodecimal(day);
                 date= ds1307_read(0X04);
                 date=bcdtodecimal(date);
                 month= ds1307_read(0X05);
                month = bcdtodecimal( month);
                 year= ds1307_read(0X06);
                 year=  bcdtodecimal(year);  
}
 
void Blink_Count()
{
   if(PIR0bits.TMR0IF == 1)
  { 
       PIR0bits.TMR0IF =0;
       count=count+1;
       if(count>=12)
       {
           LED=!LED;
           count=0;
                     
          
                           
       }
       
   }
    
}
 
 
void I2C_Intialize()
{ 
    SSP1CON1bits.CKP=1;
    SSP1STAT=0X80;
    SSP1CON1 = 0x38;
    SSP1CON3 = 0x00;
    SSP1ADD = 0x27;
}
 
 
void main(void)
{
    // Initialize the device
    SYSTEM_Initialize();
      I2C_Intialize();
    
      
         uint8_t write_value;
    uint8_t  *pt_write_value;
    pt_write_value = &write_value;
    
       
        uint8_t read_values;
        uint8_t write_values[2]; //create a two-byte array 
        write_values[0] = 0x88; // 0x80
        write_values[1] = 0x89; // 0x01
    
    SSP1CLKPPS = 0x0E;   //RB6->MSSP:SCL;
    SSP1DATPPS = 0x0C;   //RB4->MSSP:SDA;
    RB6PPS = 0x10;   //RB6->MSSP:SCL;
    RB4PPS = 0x11;   //RB4->MSSP:SDA;
    
      SetDateTime(); 
    
      I2C1_MasterWrite(write_values,1,SLAVE_ADDRESS,&status); 
    while (1)
    {
  
       GetDateTime(); 
  
     
          SetSeg(min/10,4);
                 SetSeg(min%10,3); 
                   SetSeg(sec/ 10,2);
                    SetSeg(sec%10,1); 
       
     
      // I2C1_MasterRead(read_values,1,SLAVE_ADDRESS,&status);
         
       // sec=read_values;
        
        
        
   
    }
}

 

Attachments

  • PIC16.txt
    4.9 KB · Views: 72
  • PIC18.TXT
    10.7 KB · Views: 69
Last edited by a moderator:

Hi,

No ACK means you sent the wrong address.

--> verify your code:
With PIC16, PIC 18 you used 0b 1101 000x
with PIC24 you use 0b 0110 100x

Klaus
 

Code:
SSP1BUF =0X68;
SSP1BUF =addr;
SSP1BUF = data;
Besides wrong address value of 0x68, you can't write new data to SSPBUF before the previous action has finished.
 

SSP1BUF =0XD0; or 11010000 for write and 11010000 for read
SSP1BUF =addr;
SSP1BUF = data;

but slave wont responding

- - - Updated - - -

I have tried calling this function. Code will hang when wait function being called.



Code C (Mac) - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
void wait_mssp(void)
{
while(!SSP1IF);
SSP1IF=0;
}
unsigned int ds1307_read(unsigned char addr)
{
    unsigned int x;
SSP1CON2bits.RSEN = 1;
wait_mssp();
SSP1BUF =0b11010000; //slave address(address of ds1307) + write bit;
wait_mssp();
SSP1BUF =addr;
wait_mssp();
SSP1CON2bits.RSEN = 1;
wait_mssp();
SSP1BUF =0b11010001; //slave address(address of ds1307) + read bit;
wait_mssp();
SSP1CON2bits.RCEN = 1;
wait_mssp (); 
 
SSP1CON2bits.ACKDT=1;
SSP1CON2bits.ACKEN =1;
SSP1CON2bits.PEN=1;
wait_mssp ();
x = SSP1BUF;
return (x);
}
 
 
void ds1307_write(unsigned char addr ,unsigned char data)
{
SSP1CON2bits.SEN =1; //Start bit
wait_mssp();
SSP1BUF = 0b11010000; //slave address(address of ds1307) + write bit
wait_mssp();
SSP1BUF =addr;
wait_mssp();
SSP1BUF = data; 
wait_mssp();
SSP1CON2bits.PEN =1; //stop bit
wait_mssp();
}

 
Last edited by a moderator:

I have tried calling this function. Code will hang when wait function being called.
O.K, but that doesn't prove you don't need to wait for I2C completion.

I must confess that I'm using compiler libraries, e.g. XC8 plib for I2C operation, thus I'm not aware of the exact register level protocol.
 

O.K, but that doesn't prove you don't need to wait for I2C completion.

I must confess that I'm using compiler libraries, e.g. XC8 plib for I2C operation, thus I'm not aware of the exact register level protocol.

Can you share example code that you have tried with I2C device. I found PLib is not avialble for PIC18F24K40. i gone through documentation plib available for PIC18F24k40 Series. when i compile using Plib it says it wont support PLIB functions. I have enable it in device linker setting .
 

Hi,

if the device sill doesn´t respond then use a scope and show SCL and SDA of: START, addressing, ACK, Sub_address...

Klaus
 

Thats what i am trying to tell. if i am execute above code i cann see start condition . slave addresss after that i cant get acknowledge signal . it keep repeating for device start and device slave address
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…