View previous topic :: View next topic |
Author |
Message |
murgui
Joined: 23 Dec 2015 Posts: 37
|
I2C, set up doubt |
Posted: Sat Feb 20, 2016 5:33 am |
|
|
Hello, I'm currently working on a system that reads a NTC and continuously sends it through I2C from a slave PIC(16f1826) to a master PIC(16f2685) and finally the master transmits the information trough a TTL<->USB connection to the PC.
The problem is that reading the examples in the CCS compiler and the ones posted in the forum I'm unable to establish a connection. Or at least to achieve what I want.
Right now, with the code posted the system is behaving like this:
The slave is periodically taking and converting correctly the ADC read (I know that because I sent this ADC reads by the serial connection and everything was just fine). But the Master will get stuck at the moment of sending the information to the PC, I bet the problem is in the I2C code. If I reset the slave when the master is stuck the master will send the message to the PC, but a wrong value (255, 255) no matter what voltage the slave reads.
I'm using PICkit v 3.10 and PIC C Compiler v4.114.
The codes:
Master
Main.c
Code: | #include <main.h>
#define LED PIN_B7
int8 entero, dec;
void main()
{
// setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_oscillator(OSC_8MHZ|OSC_PLL_OFF);
while(1){
output_low(pin_B7);//Set rithm---> 1 lecture/2 seconds
delay_ms(1000);
output_high(LED);
delay_ms(1000);
i2c_start();
i2c_write(0xA1);// slave->Master(1)
entero=i2c_read(1);//read first value, ack to receive the second
dec=i2c_read(0);//read second value and NACK to finish commnunication
i2c_stop();
printf("The readvalue is %u . %u volts",entero, dec);
}
}
|
Main.h
Code: | #include <18F2685.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES NOPUT //No Power Up Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES BORV21 //Brownout reset at 2.1V
#FUSES PBADEN //PORTB pins are configured as analog input channels on RESET
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES BBSIZ1K //1K words Boot Block size
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOCPB //No Boot Block code protection
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#use delay(int=8000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1,errors)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3)
|
Slave
Main.c
Code: | #include <main.h>
#include <math.h>
enable_interrupts (SSP);
float V;
int16 i;
int8 entero,dec,f1,f2;
void main()
{
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
setup_oscillator(OSC_16MHZ|OSC_TIMER1|OSC_PLL_OFF,0);
setup_adc(adc_clock_div_64);
setup_adc_ports(sAN3|VSS_VDD);
delay_ms(1);
while(true){
output_high(LED);
delay_ms(1000);
output_low(LED);
set_adc_channel(3);
delay_ms(1);
i=read_adc();
delay_ms(10);
V=(i/1024.0)*5;
f1=floor(V);
f2=floor(100*(V-f1));
entero=make8(f1,0);//necessary?
dec=make8(f2,0);//necessary?
}
}
#INT_SSP
void ssp_interrupt ()
{
int8 state,dato;
state = i2c_isr_state();
if (state>=0x80)//Master asking for info
{
i2c_write(entero);
if (state>=0x81)//transmission completed and ack received
{
i2c_write(dec);
}
}
if (state<0x80)//Master sending info
{
dato = i2c_read();
}
}
|
Main.h
Code: | #include <16LF1826.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES WDT_SW
#FUSES NOPUT //No Power Up Timer
#FUSES MCLR //Master Clear pin enabled
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOCPD //No EE protection
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOCLKOUT
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOWRT //Program memory not write protected
#FUSES PLL_SW
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES BORV19
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#device ADC=10
#use delay(int=16000000)
#define I2C_SDA PIN_B1
#define I2C_SCL PIN_B4
#use rs232(baud=9600,parity=N,xmit=PIN_B5,rcv=PIN_B2,bits=8,stream=PORT1,errors)
#use i2c(Slave,Fast,sda=PIN_B1,scl=PIN_B4,address=0xA0)
#define LED PIN_A1
#define DELAY 1000
|
Thank you very much and sorry by the length, you guys are great!
Murgui |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9216 Location: Greensville,Ontario
|
|
Posted: Sat Feb 20, 2016 6:12 am |
|
|
1) what voltages are the PIC being operated at ( Vdd = ??)
2) what value are the I2C buss pullup resistors ?
3) compile and run the I2C scanner program in the code library, results ??
Jay |
|
|
murgui
Joined: 23 Dec 2015 Posts: 37
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9216 Location: Greensville,Ontario
|
|
Posted: Sat Feb 20, 2016 6:57 am |
|
|
Yes, that's it !
If you're using I2C this a 'must run' test program. It allows you to confirm the I2C bus is correct as well as check addresses for device on the bus.
Jay |
|
|
murgui
Joined: 23 Dec 2015 Posts: 37
|
|
Posted: Sat Feb 20, 2016 7:04 am |
|
|
Nice, I will do it and come back with the results.
Thank you for the help.
Murgui |
|
|
drh
Joined: 12 Jul 2004 Posts: 192 Location: Hemet, California USA
|
|
Posted: Sat Feb 20, 2016 8:40 am |
|
|
Does your slave device require a restart before you read the data? _________________ David |
|
|
murgui
Joined: 23 Dec 2015 Posts: 37
|
|
Posted: Sat Feb 20, 2016 9:08 am |
|
|
I'm back.
After performing the test, the result is:
"Start:
Nothing Found"
So the PICs won't even communicate each other. Where do you guys think the problem is?
And it requires a restart but I think that this is because in the restart the PIC is not keeping the I2C bus busy and when I restart the master doesn't get stuck because it just won't detect anything.
Thank you. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Feb 20, 2016 10:59 am |
|
|
Quote: |
Slave:
#include <main.h>
#include <math.h>
enable_interrupts (SSP);
float V;
int16 i;
|
What is this line of code doing, floating around in space ?
Study the correct way to enable interrupts. |
|
|
murgui
Joined: 23 Dec 2015 Posts: 37
|
|
Posted: Sat Feb 20, 2016 11:02 am |
|
|
I think that this line enables the later interruption of I2C.
I edited the program adding to the slave's .c :
Code: | void main()
{
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
setup_oscillator(OSC_16MHZ|OSC_TIMER1|OSC_PLL_OFF,0);
setup_adc(adc_clock_div_64);
setup_adc_ports(sAN3|VSS_VDD);
delay_ms(1);
enable_interrupts (INT_SSP);
while(true){........ |
Last edited by murgui on Sat Feb 20, 2016 11:35 am; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Feb 20, 2016 11:34 am |
|
|
Look at the CCS example file, Ex_Slave.c, to see how to do it. |
|
|
murgui
Joined: 23 Dec 2015 Posts: 37
|
|
Posted: Sat Feb 20, 2016 11:47 am |
|
|
Thank you, the errors for some person having the same issues:
-enable_interrupts must be in void main()
-In addition of the specific interupt you must also enable_interrupts(GLOBAL)
Thank you PCM. |
|
|
|