CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

I2C Master & Slave problem with 16F1827

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kenken



Joined: 10 Feb 2011
Posts: 5
Location: Japan

View user's profile Send private message

I2C Master & Slave problem with 16F1827
PostPosted: Thu Feb 10, 2011 6:58 am     Reply with quote

Hello everyone,

I'm testing I2C communication circuit with two PIC16F1827.
But it seems not work. I checked on SDA and SCL line by oscilloscope.
I tried to find what is wrong. But It's too difficult.

This is test code.
Code:

//-------------Master--------------------------
#include <16F1827.H>
#fuses NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#FUSES INTRC_IO
#FUSES PLL
#use delay(clock = 32000000) 

#use i2c(MASTER, SDA=PIN_B1, SCL=PIN_B4, fast, FORCE_HW)

#use fast_io(A)
#use fast_io(b)
#byte PORTA = 5
#byte PORTB = 6
#byte APFCON0 = 0x11D //ALTERNATE PIN FUNCTION CONTROL REGISTER 0
#byte APFCON1 = 0x11E //ALTERNATE PIN FUNCTION CONTROL REGISTER 1
   
#define SLAVE1_WRT_ADDR   0x12
#define SLAVE1_READ_ADDR  0x13
//====================================
void main()
{
int8 data;

while(1)
  {
   i2c_start();
   i2c_write(SLAVE1_READ_ADDR);
   data = i2c_read(0);
   i2c_stop();
   delay_ms(1000);
  }
}





///------------------Slave-------------------------
#include <16F1827.h>
#device adc=8
#fuses NOWDT,PUT,BROWNOUT,NOLVP
#FUSES INTRC_IO
#FUSES PLL
#use delay(clock = 32000000) 
#use i2c(SLAVE, SDA=PIN_B1, SCL=PIN_B4, ADDRESS=0x12, fast, FORCE_HW)
#byte APFCON0 = 0x11D //ALTERNATE PIN FUNCTION CONTROL REGISTER 0
#byte APFCON1 = 0x11E //ALTERNATE PIN FUNCTION CONTROL REGISTER 1

int8 test_result;
#INT_SSP
void ssp_interrupt()
{
int8 incoming, state;

state = i2c_isr_state();
if(state < 0x80)     // Master is sending data
  {
   incoming = i2c_read(); 
  }
if(state >= 0x80)   // Master is requesting data from slave
  {
   i2c_write(test_result);
  }
}
//======================================
void main ()
{
setup_adc_ports(NO_ANALOGS);//
test_result = 30;//ex,30

enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
   
while(1)
  {
   test_result = 30;//ex,30
   delay_ms(500);
  }

}


This is my situation. Compiler v4.119 MPLAB v8.63 .
I know this PIC has many functions therefore I need set some REGISTERs for work well.
Please let me know how to use the I2C of 1827.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Feb 10, 2011 2:49 pm     Reply with quote

Quote:
#use fast_io(A)
#use fast_io(b)

If you use fast i/o mode, you need to set the TRIS with lines of code,
such as set_tris_a(xx) and set_tris_b(xx). You're not doing that, and
that will cause a problem. But my advice is to delete both of the #use
fast_io lines. If you delete them, the compiler will use standard i/o mode
and it will set the tris for you. It's much easier to do it that way.

Quote:

#byte PORTA = 5
#byte PORTB = 6

These addresses are wrong. Download the 16F1827 data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/41391C.pdf
Look at this table on page 25:
Quote:

TABLE 3-3: PIC16F/LF1826/27 MEMORY MAP, BANKS 0-7

It shows the correct addresses for Ports A and B. Remember that
these are "Enhanced" 16F PICs. Much of the register sets and everything
else are changed from the normal 16F parts.

With regard to the i2c testing:

1. There may be bugs in the CCS library code for this PIC and your
compiler version. Initially, you should test your Master/Slave code with
PICs that are known to work. Test your hardware and prove that it
works. Then substitute one PIC (the Master) with the new 16F1827. Try
to make that work. When you get that working, then insert the 16F1827
for the slave and test it.

2. Microchip doesn't guarantee that an i2c Slave will work in Fast mode.
See this note on page 280 of the PIC data sheet:
Quote:

Note 1:
The I2C interface does not conform to the 400 kHz I2C specification
(which applies to rates greater than 100 kHz) in all details, but may be
used with care where higher rates are required by the application.

My advice is, initially, don't use FAST mode.

3. You are using 32 MHz PLL mode. Have you tested that the PIC is
running at the correct frequency, by making an LED blinking program ?
Even if it is running at the correct frequency, my advice is don't use PLL
mode for initial testing of i2c. Run it at 8 MHz, and test that the PIC is
really running at 8 MHz.

4. What is the value of your pull-up resistors on SCL and SDA ?
For 100 KHz mode, you can use 4.7K ohms.
kenken



Joined: 10 Feb 2011
Posts: 5
Location: Japan

View user's profile Send private message

I made 16F88 I2C test circuit for the 16f1827 issue
PostPosted: Fri Feb 11, 2011 4:01 am     Reply with quote

Thank you PCM programmer!
I completely agree with your comment. I should make normal 16F I2C method at first.
I obeyed your suggestion and fixed this program and tested it in other PIC. 16F88.(This is not "Enhanced" pic and I only have this pic now.)

I thought it should work well. But It's not working......Maybe my code is wrong again.

I changed the MASTER setting FORCE_HW to FORCE_SW.
Then the SCL signal appeared. I think this 16f88 has SSP module, It should be ok with FORCE_HW. Why? Question

Code:

/****************************************
*  i2cmaster
***************************************/
#include  <16f88.h>
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP,MCLR,NOIESO,NOFCMEN,NODEBUG
#use delay(CLOCK = 20M)
#use i2c(MASTER, SDA=PIN_B1, SCL=PIN_B4, slow, FORCE_SW)//<-I don't know 16f88 can work with force_HW or not.

#define SLAVE1_WRT_ADDR   0x12
#define SLAVE1_READ_ADDR  0x13
//====================================
void main()
{
//------IO setting----
SET_TRIS_A(0b00000000);//
SET_TRIS_B(0b11111111);//
int8 data;
   while(1)
   {
      i2c_start();
      i2c_write(SLAVE1_READ_ADDR);
      data = i2c_read(0);
      i2c_stop();
      delay_ms(500);
      output_toggle(pin_a2);//check LED
   }
}





/****************************************
*  i2c slave
***************************************/
#include  <16f88.h>
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP,MCLR,NOIESO,NOFCMEN,NODEBUG,
#use delay(CLOCK = 20000000)
#use i2c(SLAVE, SDA=PIN_B1, SCL=PIN_B4, ADDRESS=0xa8, slow, FORCE_HW)
//#use i2c(SLAVE, SDA=PIN_B1, SCL=PIN_B4, ADDRESS=0xa8, slow, FORCE_SW) //I also tested SW but not work...

int8 test_result;
#INT_SSP
void ssp_interrupt()
{
int8 incoming, state;
state = i2c_isr_state();
if(state < 0x80)     // Master is sending data
  {
   incoming = i2c_read(); 
  }
if(state >= 0x80)   // Master is requesting data from slave
  {
   i2c_write(test_result);
  }
output_toggle(pin_a2);   
}
//======================================
void main ()
{
//------IO setting----
SET_TRIS_A(0b00000000);//
SET_TRIS_B(0b11111111);//

setup_adc_ports(NO_ANALOGS);//
test_result = 30;//ex,30
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
output_low(pin_a2);//check LED   
while(1)
  {
   test_result = 30;//ex,30
   delay_ms(500);
  }
}

I put 4.7K ohm pull_up resistor on SCL and SDA.
The master's check LED is blinking well on master side.
But I can't see Slave check LED... Crying or Very sad
I think it means the #INT_SSP doesn't work.

I will shift to 16F1827 if I can fix this 16f88 issue.
Please help me for my I2C problem.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Feb 11, 2011 1:06 pm     Reply with quote

Quote:
Ichanged the MASTER setting FORCE_HW to FORCE_SW.
Then the SCL signal appeared. I think this 16f88 has SSP module,
It should be ok with FORCE_HW. Why?

The 16F88 only has an SSP module. It doesn't have an MSSP module.
Therefore, it can't work as a hardware master, only as a slave.
But, it's OK for this test, to use a software master.

I see a problem with your slave. You have different addresses specified in the Master code and in the Slave code. The slave address must be the same in both programs. Use 0x12 as the slave address in both.

Also, you don't need to set the TRIS. The compiler will do it.
Delete all the set_tris_x() lines in both programs.
kenken



Joined: 10 Feb 2011
Posts: 5
Location: Japan

View user's profile Send private message

Thank you PCM programmer!
PostPosted: Mon Feb 14, 2011 2:20 am     Reply with quote

It works now ! I'm sooooo happy now.
The issue points was exactly PCM programmer's comments. You so great!
This below is correct code for just in case.

Code:




//-------------Master--------------------------
#include <16F1827.H>
#fuses NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#FUSES INTRC_IO
#FUSES PLL
#use delay(clock = 32000000) 
#use i2c(MASTER, SDA=PIN_B1, SCL=PIN_B4, fast, FORCE_HW)

#byte APFCON0 = 0x11D //ALTERNATE PIN FUNCTION CONTROL REGISTER 0
#byte APFCON1 = 0x11E //ALTERNATE PIN FUNCTION CONTROL REGISTER 1
   
#define SLAVE1_WRT_ADDR   0xa0
#define SLAVE1_READ_ADDR  0xa1
//====================================
void main()
{
int8 data;
while(1)
{
   i2c_start();
   i2c_write(SLAVE1_wrt_ADDR);
   i2c_write(0x00);
   i2c_write('s'); //just test
   delay_us(10);   
   i2c_stop();
   delay_ms(200);
   output_toggle(pin_a2);//check LED
}
}//main



///------------------Slave-------------------------
#include <16F1827.h>
#fuses NOWDT,PUT,BROWNOUT,NOLVP
#FUSES INTRC_IO
#FUSES PLL
#use delay(clock = 32000000) 
#use i2c(SLAVE, SDA=PIN_B1, SCL=PIN_B4, ADDRESS=0xa0, fast, FORCE_HW)

int8 test_result;
int8 incoming, state;
#INT_SSP
void ssp_isr(void)
{
state = i2c_isr_state();
if(state < 0x80)     // Master is sending data
  {
   incoming = i2c_read(); 
  }
if(state >= 0x80)   // Master is requesting data from slave
  {
   i2c_write(test_result);
  }
output_toggle(pin_a2);//ssp_isr check LED
}
//======================================
void main ()
{
setup_adc_ports(NO_ANALOGS);//
test_result = 30;//ex,30
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
output_low(pin_a2);//check LED off
while(1){}
} //main


Thanks evey one!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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