View previous topic :: View next topic |
Author |
Message |
tems
Joined: 26 Nov 2008 Posts: 8
|
I2C 16F18325 |
Posted: Mon May 06, 2019 2:35 pm |
|
|
I want to communicate tfrom an 18f46k22 to an 16f18325 but have difficulty in getting this to work. The code below is in the slave. I can get the interrupt but cannot read any data. Never passes the first read statement.
Code: |
#include <16F18325.h>
#use delay(internal=32MHz)
#pin_select SDA1=PIN_A4
#pin_select SCL1=PIN_A5
#use i2c(Slave,Fast=400000,sda=PIN_A4,scl=PIN_A5,force_hw,address=0xA0)
int8 B1;
int8 B2;
int8 B3;
int8 B4;
#INT_SSP
void ssp_isr () //I2C interrupt
{
int16 state;
disable_interrupts(global);
state = i2c_isr_state();
IF(state < 0x80) //Master is sending data
{
While (!i2c_poll()) // whether in or out does the same thing
{
}
IF(state == 0) // // 1st received byte
{
B1 = i2c_read(1);
}
IF(state == 1) //2nd received byte
{
B2 = i2c_read(1);
}
IF(state == 2) //3rd received byte
{
B3 = i2c_read(1);
}
IF(state == 3) //4th
{
B4 = i2c_read(0);
}
}
enable_interrupts(global); //Re-enable interrupts
}
void main()
{
setup_adc_ports(NO_ANALOGS);
i2c_init(1);
clear_interrupt(INT_SSP);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
while(TRUE)
{
}
} |
Master is this
Code: |
#include <18F46K22.h>
#device ICD=TRUE
#use delay(clock=32MHz,crystal=8MHz)
#use i2c(Master,Fast=400000,sda=PIN_C4,scl=PIN_C3,force_hw)
#byte SSP1CON2 =0xFC5
#byte SSP1CON1 =0xFC6
#include <test.h>
#ZERO_RAM
void write_pic_generic()
{
i2c_start();
while (bit_test(ssp1con2,0)==1) // wait for start to complete.
{
}
if (i2c_write(0xA0)==0) // chip address
{
if (i2c_write(5)==1) // value of the data
{
break;
}
if (i2c_write(1)==1) // value of the data
{
break;
}
if (i2c_write(0)==1) // value of the data
{
break;
}
if (i2c_write(64)==1) // value of the data
{
break;
}
}
i2c_stop();
}
void main()
{
int8 i;
i=0;
i2c_init(1);
while(TRUE)
{
if (i==0)
{
write_pic_generic();
i++;
}
}
}
|
I've used i2c scanner and it does find the slave device. What am i missing.
Thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon May 06, 2019 3:37 pm |
|
|
Start by using the CCS example file, ex_slave.c, instead of your code
above. Change the #include line and other initial lines to fit your board.
Use the code in the following link for the master:
http://www.ccsinfo.com/forum/viewtopic.php?t=32368&start=3
If the hardware is correct, the above test should also work.
This will prove that the test setup is good.
Then start modifying the code to suit your project. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19492
|
|
Posted: Mon May 06, 2019 11:54 pm |
|
|
and one horrible 'no no'. This:
enable_interrupts(global); //Re-enable interrupts
Must _never_ be called inside an interrupt handler.
You do not need to disable interrupts in the handler. The hardware
already does this for you. The interrupts are re-enabled on the return
from the handler. Calling an enable in the handler means the interrupts
are enabled _before_ the code exits the handler. Result can be the
interrupt being called inside itself. Disaster.... |
|
|
|