The circuit works now.
The last problem was related with pull-up resistors on PORTB, because I did not use any external resistors attached to the dipswitches.
It works also if I use 4.7K resistors for MCLR instead of 10K and if I use 4.7K resistors of I2C resistors instead of 3.3K. It works also if I use the VDD/VCC connections on only 1 side of the PIC16F1937.
To recap, the problems were as following: Atmega MCU instead of PIC16F1937, then OSCCON=0x7A; - mistakes on the given original examples and the last one, my mistake, pull-up resistors on PORTB.
PIC16F1937 allows setting individual pull-up resistor on each pin of PORTB.
Because I do no use a dipswitch with 8 positions, but only with 6, connected to the pins RB7-RB2, then I set up the pull-up resistors on PORTB only for RB2-RB7, so instead of WPUB=0b11111111=0xFF, I used WPUB=0b11111100=0xFC;
Here is a photo with the working circuit on breadboard:
- I2C PIC16F1937_breadboard_good.JPG (134.54 KiB) Viewed 20854 times
Here is the oscilloscope screenshot with I2C bus working signals:
Here are explanations to the above oscilloscope screenshot with I2C bus working signals:
These explanations may help to debug I2C:
- The Master always starts and stops the communication. The Master is the only one providing the clock.
- The Slave can also control the SCL/SDA lines.
- It may be clock stretch situations, when if the Master is too fast with the clock, then the Slave tells to slow done the clock, otherwise no communication can take place.
- I find next file very good:
http://opensat.cc/wiki/_media/ko:contri ... oscope.pdf
Particularly to the above oscilloscope screenshot:
- The Master initiates the communication (Start) with the falling edge of the SDA while the SCL is HIGH.
- The it follows 9bits, from which 8bits are Slave Address 0x54 combined with a Read operation (R=1, which is the 8bit, because is a 7bit address), so we have 0x54 bitwise OR 0x1 = 0x55.
- The next bit is Acknowledge bit sent by Slave, saying that received the correct address and info that the Master wants to Read.
- Then follows 8bits of Data sent by the Slave.
- At the end of Data bits, the Master sent Not Acknowledge as indication that received the requested 1byte of data.
- In the end the Master closes the communication (Stop) with the raising edge of SDA while SCL is HIGH.
Now everything works fine, but still remain 2 open questions:
- My initial 3):
Is it possible to provide an example where instead of “cal_i2c1” component to use I2C Master and I2C Slave?
http://www.matrixtsl.com/blog/simplifie ... c-and-spi/
- Right now the Slave code checks for the Slave status continuously in a While loop.
- Most of the XC8 examples from Microchip use the MSSP interrupt.
Could you change the code to use MSSP interrupts, so the Slave to be free to do something else and to not be busy in that While loop?