|
|
View previous topic :: View next topic |
Author |
Message |
kenken
Joined: 10 Feb 2011 Posts: 5 Location: Japan
|
I2C Master & Slave problem with 16F1827 |
Posted: Thu Feb 10, 2011 6:58 am |
|
|
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
|
|
Posted: Thu Feb 10, 2011 2:49 pm |
|
|
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
|
I made 16F88 I2C test circuit for the 16f1827 issue |
Posted: Fri Feb 11, 2011 4:01 am |
|
|
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?
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...
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
|
|
Posted: Fri Feb 11, 2011 1:06 pm |
|
|
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
|
Thank you PCM programmer! |
Posted: Mon Feb 14, 2011 2:20 am |
|
|
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! |
|
|
|
|
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
|