Hardware Setup: I'm using the curiosity development
Which one? There are many Curiosity boards.
Is it the DM164137 ?https://www.microchip.com...etails/PartNO/DM164137
Right now the code is in C, after getting this to work, I will translate it to assembly. The reason I don't write in assembly from the beginning is because I need to pick up assembly again after almost 10 years...
Why bother re-coding? The output from XC8 is pretty compact.
It's easy to write small functions in inline assembly if you need the best possible speed for any small bit of code.
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
This oscillator mode requires an external crystal.
If it is the Curiosity board I think you have, there is no crystal on the board, and you should use one of the internal oscillator modes.
Have you tried just flashing an LED slowly first?
ANSELC = 0x0C;
This is good. My first guess was you had left RC0/SCL and/or RC1/SDA in analog mode.
They do both have to be in digital mode.
while ((SSP1STAT & 0x08) || (SSP1CON2 & 0x1F)); // wait for start bit to clear in SSPSTAT and bits 0 to 4 in SSPCON2
Is this straight from some tutorial code?
The S bit will be set in the middle of any normal transaction, so waiting for it to be clear is NOT correct.
void I2C_start (void)
SSP1CON2 |= 0x01; // SEN=1 -> initiate the START condition on SDA and SCL pins
There are much easier ways to access bits in C, which also allow syntax checking to work
With the I2C peripheral, I find it makes much more sense to initiate an action, then wait for that action to finish.
void I2C_start (void)
SSP1CON2bits.SEN = 1; // initiate a START condition
while (SSP1CON2bits.SEN); // wait until the START condition has been sent
void I2C_stop (void)
SSP1CON2bits.PEN = 1; // initiate a STOP condition
while (SSP1CON2bits.PEN); // wait until the STOP condition has been sent
void I2C_restart (void)
SSP1CON2bits.RSEN = 1; // initiate a REPEATED START condition
while (SSP1CON2bits.RSEN); // wait until the REPEATED START condition has been sent
Where you i nthe middle of writing this code?
// read data
I2C_start (); // start I2C
I2C_write (0x76); // using 0x76 slave address
I2C_repeated_start(); // repeated start
I2C_write (0x1E); // reset
__delay_ms (2000); // 2sec delay
//data = I2C_read (1); // read data and send NACK
The repeated start should NOT be before the reset command. You are still writing commands, you don't send a repeated start until you want to swap to read mode. The next byte sent after a repeated start MUST be a slave address (usually the "read" form of the address, so 0x77 in your case)
If you have to wait a long time before doing the read, I woudn't bother using repeated start at all. Just do the command the initiates a read, then do a standalone read cycle (START/slave address+read/READ/STOP).
Also, you SHOULD check the ACKSTAT bit after sending a slave address. That is what tells you if the slave acknowledged the address, which is what tells you it is all working.