// Update
after messing around with the code I think that I almost got it to work the only problem is that I'm being told that there are to many initializers here is the code, its kinda long. the error is popping up here:static bit ACK = 0; on line 149
Code: Select all
// Define i2c pins
#define SDA PORTA.F0 // Data pin for i2c
#define SCK PORTA.F1 // Clock pin for i2c
#define SDA_DIR TRISA.f0 // Data pin direction
#define SCK_DIR TRISA.f1 // Clock pin direction
#define DataPinADCMask ADCON0 // It is attached on RA0 pin
#define ClockPinADCMask ADCON1
// Define i2c speed
#define I2C_SPEED 1 // kbps
#define HalfBitDelay 500/I2C_SPEED // usec
// Define macros
#define Set_SDA_Low SDA_DIR = 0
#define Set_SDA_High SDA_DIR = 1
#define Set_SCK_Low SCK_DIR = 0
#define Set_SCK_High SCK_DIR = 1
//Function Declarations
void InitI2C(void);
void I2C_Start(void);
void I2C_ReStart(void);
void I2C_Stop(void);
void I2C_Send_ACK(void);
void I2C_Send_NACK(void);
unsigned I2C_Write_Byte(unsigned char);
unsigned char I2C_Read_Byte(void);
/* main explained
note: may have to turn off adc and comparator
i2c pins are initialized using InitI2C() function.
Then I2C_Start() function sends a start bit S on i2c
bus. Then a value of 0xA0 is written on the i2c bus
using I2C_Write_Byte(0xA0); statement. After that,
I2C_Read_Byte() function reads a byte from the i2c
bus, because there is no slave attached on the i2c
bus, that is why RxByte will receive a value of 0xFF*.
*
Because SDA pin is pulled up normally and when PIC
is not driving it, then it will always stay high
because of the pull up. That is why when there is
no slave, then a value of 0xFF will be read.
*
After that, an ACK 'A' is transmitted on i2c bus
using I2C_Send_ACK() function. And in the end a
stop bit 'P' is transmitted on i2c bus using
I2C_Stop() function.
*/
void main(){
unsigned char RxByte = 0;
InitI2C(); //Initialize i2c pins
I2C_Start();
I2C_Write_Byte(0xA0); // send 0A0 in i2c
RxByte = I2C_Read_byte(); // Read from i2c
I2C_Send_ACK(); // send acknolage bit on i2c
I2C_Stop(); // Send stop bit on I2c
}
// Function Purpose: Set initial values of SCK and SDA pins
void InitI2C(void)
{
DataPinADCMask = 1; // Make analog output
ClockPinADCMask = 1; // Make analog output
// Make SDA and SCK pins input initially
SDA_DIR = 1;
SCK_DIR = 1;
// Write zero in output register of SDA and SCK pin
SDA = 0;
SCK = 0;
}
// Function Purpose: I2C_Start sends start bit sequence
void I2C_Start(void)
{
SDA = 0; // Write zero in output register
SCK = 0; // of SDA and SCK pin
Set_SCK_High; // Make SCK pin high
Set_SDA_High; // Make SDA pin High
Delay_us(HalfBitDelay); // Half bit delay
Set_SDA_Low; // Make SDA Low
Delay_us(HalfBitDelay); // Half bit delay
}
// Function Purpose: I2C_ReStart sends start bit sequence
void I2C_ReStart(void)
{
Set_SCK_Low; // Make SCK pin low
Delay_us(HalfBitDelay/2); // Data pin should change it's value,
// when it is confirm that SCK is low
Set_SDA_High; // Make SDA pin High
Delay_us(HalfBitDelay/2); // 1/4 bit delay
Set_SCK_High; // Make SCK pin high
Delay_us(HalfBitDelay/2); // 1/4 bit delay
Set_SDA_Low; // Make SDA Low
Delay_us(HalfBitDelay/2); // 1/4 bit delay
}
//Function : I2C_Stop sends stop bit sequence
void I2C_Stop(void)
{
Set_SCK_Low; // Make SCK pin low
Delay_us(HalfBitDelay/2); // Data pin should change it's value,
// when it is confirm that SCK is low
Set_SDA_Low; // Make SDA pin low
Delay_us(HalfBitDelay/2); // 1/4 bit delay
Set_SCK_High; // Make SCK pin high
Delay_us(HalfBitDelay/2); // 1/4 bit delay
Set_SDA_High; // Make SDA high
Delay_us(HalfBitDelay/2); // 1/4 bit delay
}
//Function : I2C_Send_ACK sends ACK bit sequence
void I2C_Send_ACK(void)
{
Set_SCK_Low; // Make SCK pin low
Delay_us(HalfBitDelay/2); // Data pin should change it's value,
// when it is confirm that SCK is low
Set_SDA_Low; // Make SDA Low
Delay_us(HalfBitDelay/2); // 1/4 bit delay
Set_SCK_High; // Make SCK pin high
Delay_us(HalfBitDelay); // Half bit delay
}
//Function : I2C_Send_NACK sends NACK bit sequence
void I2C_Send_NACK(void)
{
Set_SCK_Low; // Make SCK pin low
Delay_us(HalfBitDelay/2); // Data pin should change it's value,
// when it is confirm that SCK is low
Set_SDA_High; // Make SDA high
Delay_us(HalfBitDelay/2); // 1/4 bit delay
Set_SCK_High; // Make SCK pin high
Delay_us(HalfBitDelay); // Half bit delay
}
// Function Purpose: I2C_Write_Byte transfers one byte
unsigned I2C_Write_Byte(unsigned char Byte)
{
static bit ACK = 0;
unsigned char i; // Variable to be used in for loop
for(i=0;i<8;i++) // Repeat for every bit
{
Set_SCK_Low; // Make SCK pin low
Delay_us(HalfBitDelay/2); // Data pin should change it's value,
// when it is confirm that SCK is low
if((Byte<<i)&0x80) // Place data bit value on SDA pin
Set_SDA_High; // If bit is high, make SDA high
else // Data is transferred MSB first
Set_SDA_Low; // If bit is low, make SDA low
Delay_us(HalfBitDelay/2); // Toggle SCK pin
Set_SCK_High; // So that slave can
Delay_us(HalfBitDelay); // latch data bit
}
// Get ACK from slave
Set_SCK_Low;
Set_SDA_High;
Delay_us(HalfBitDelay);
Set_SCK_High;
Delay_us(HalfBitDelay);
DataPinADCMask = 0; // Make digital input
ACK = SDA; // Read data pin status
DataPinADCMask = 1; // Make analog output
return ACK;
}
// Function Purpose: I2C_Read_Byte reads one byte
unsigned char I2C_Read_Byte(void)
{