|
|
View previous topic :: View next topic |
Author |
Message |
itzalak Guest
|
16F88 I2C master (software) and 16F88 Slave (hardware) |
Posted: Tue Sep 18, 2007 7:02 am |
|
|
Hello:
I've been looking for some days a solution for my I2C communication problem between two PIC16f88 Pics but I've found nothing to solve i yet so I decided to expose my problem.
As I said, there is a master PIC16F88 (software master) and other same pic as hardware slave. I'm tying to send a byte from master to slave but meanwhile the SPI (I2C) interrupt works fin I can't receive nothing. I can see that the state = i2c_isr_state() returns always 128 decimal.
My master code is as simple as this:
#use delay(clock=8000000)
#use i2c(Master,sda=PIN_B1,scl=PIN_B4,slow)
void main ()
{
reset_variables();
While(1)
{
mandar_codigo();
}
}
void reset_variables()
{
setup_adc_ports(sAN0|sAN1|sAN3|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL /*ADC_CLOCK_DIV_2*/);
setup_timer_0(T1_DISABLED /*RTCC_INTERNAL|RTCC_DIV_1*/);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_oscillator(OSC_8MHZ|OSC_INTRC);
DISABLE_INTERRUPTS(GLOBAL);
#asm
MOVLW 0b00111011; //Module enable, clock
MOVWF 0x14; //SSPCON
#endasm
}
i2c_start();
delay_us(100);
i2c_write(0xA0);
delay_us(100);
i2c_write(0xAA);
delay_us(100);
i2c_write(0x55);
delay_us(100);
i2c_stop();
delay_ms(2000);
}
And the slave code is the next one:
#use delay(clock=8000000)
#use I2C(slave,SDA=PIN_B1,SCL=PIN_B4,force_hw,slow,address=0xAA)
BYTE a;
BYTE address, buffer[0x10];
#INT_SSP
void i2c_isr ()
{
BYTE incoming, state;
clear_interrupt(INT_SSP);
disable_interrupts(GLOBAL);
disable_interrupts(INT_SSP);
state = i2c_isr_state();
if(state < 0x80) //Master is sending data
{
incoming = i2c_read();
if(state == 1) //First received byte is address
address = incoming;
if(state == 2) //Second received byte is data
buffer[address] = incoming;
}
if(state == 0x80) //Master is requesting data
{
i2c_write(buffer[address]);
}
}
void main ()
{
reset_variables();
While(1)
{
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
}
void reset_variables()
{
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc(ADC_OFF);
setup_spi(SPI_SLAVE|SPI_L_TO_H);
setup_timer_0(T1_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_vref(FALSE);
setup_oscillator(OSC_8MHZ);
// HAY UN ERROR EN EL DATASHEET DEL 16F88 PARA CONFIGURAR
// EL I2C. LO ARREGLAMOS PONIENDOLO A MANO
#asm
MOVLW 0b00111110 ;Module enable, clock, 7 bits
MOVWF 0x14; //SSPCON
#endasm
clear_interrupt(INT_SSP);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
} |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Ttelmah Guest
|
|
Posted: Tue Sep 18, 2007 1:21 pm |
|
|
The reason it doesn't work, is the slave is never addressed.
The address must be the first byte after the start. You are sending 'A0', while the slave has an address of 'AA'. Therefore there is never an address match.
Best Wishes |
|
|
itzalak Guest
|
|
Posted: Fri Sep 21, 2007 4:22 am |
|
|
I've tryed everything but nothing goes fine. I've used avery simple master code as you told. The slave cod is the ccs example code little bit modified for the pic16f88.
The firs thing I can see is that the interrupt occurs, ok. Then I dissable global and SPI interrupt at the first line. In main code I put on those again but the pic needs "a lot of time" to do an interrpt again, sometimes incusive some seconds. As I'm looking the sending data in the scope I think there is a problem on "interrupt secction".
The data received in (watching in debug mode) is only sometimes ok, but only afew times.
void main ()
{
reset_variables();
While(1)
{
mandar_codigo();
}
}
void reset_variables()
{
setup_adc_ports(sAN0|sAN1|sAN3|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL /*ADC_CLOCK_DIV_2*/);
setup_timer_0(T1_DISABLED /*RTCC_INTERNAL|RTCC_DIV_1*/);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_oscillator(OSC_8MHZ|OSC_INTRC);
DISABLE_INTERRUPTS(GLOBAL);
}
void mandar_codigo()
{
// Write the letter 'B' to the slave board.
i2c_start();
i2c_write(0xA0);
i2c_write(0x00);
i2c_write('B');
i2c_stop();
delay_ms(2000);
}
The 16F88.h library:
#include <16F88.h>
#device ICD=TRUE
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc
#FUSES NOPUT //No Power Up Timer
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOBROWNOUT //Reset when brownout detected
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES DEBUG //Debug mode for use with ICD
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOIESO //Internal External Switch Over mode disabled
#use delay(clock=8000000)
#use i2c(Master,sda=PIN_B1,scl=PIN_B4)
And the slve code:
#if defined(__PCM__)
#include <16F88.h>
#device ICD=TRUE
#fuses INTRC_IO,NOWDT,NOPROTECT,NOLVP,INTRC_IO
#use delay(clock=8000000)
#elif defined(__PCH__)
#include <18F88.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,NOLVP,INTRC_IO
#use delay(clock=8000000)
#endif
#use i2c(SLAVE, SDA=PIN_B1, SCL=PIN_B4, FORCE_HW, address=0xA0)
void reset_var();
unsigned int8 address=0;
BYTE buffer[0x04];
#INT_SSP
void ssp_interupt ()
{
BYTE incoming, state;
state = i2c_isr_state();
if(state < 0x80) //Master is sending data
{
incoming = i2c_read();
if(state == 1) //First received byte is address
address = incoming;
if(state == 2) //Second received byte is data
buffer[address] = incoming;
}
if(state == 0x80) //Master is requesting data
{
i2c_write(buffer[address]);
}
}
void main ()
{
reset_var();
while(1)
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
}
}
void reset_var()
{
unsigned int8 i=0;
for (i=0; i<0x04; i++)
buffer[i]=0;
}
Any idea?
Thanks a lot for all your help. |
|
|
|
|
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
|