#include<pic.h>
#include<htc.h>
#define __PIC12F675_H //header file for ic
__CONFIG(FOSC_INTRCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & BOREN_ON & CP_OFF & CPD_OFF); //config word
#define _XLAT_FREQ 4000000 //define cpu frequency
void delay(unsigned int i)
{
while(i--);
}
// Define i2c pins
#define SDA GP4 // Data pin for i2c
#define SCK GP5 // Clock pin for i2c
#define SDA_DIR TRISIO4 // Data pin direction
#define SCK_DIR TRISIO5 // Clock pin direction
#define DataPinADCMask ANS3 // It is attached on GP4(AN3) pin
#define ClockPinADCMask ANS3 // It is not attached on any ADC pin
// 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
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;
}
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(100); // Half bit delay
Set_SDA_Low; // Make SDA Low
delay(100); // Half bit delay
}
void I2C_ReStart(void)
{
Set_SCK_Low; // Make SCK pin low
delay(100); // Data pin should change it's value,
// when it is confirm that SCK is low
Set_SDA_High; // Make SDA pin High
delay(100); // 1/4 bit delay
Set_SCK_High; // Make SCK pin high
delay(100); // 1/4 bit delay
Set_SDA_Low; // Make SDA Low
delay(100); // 1/4 bit delay
}
void I2C_Send_ACK(void)
{
Set_SCK_Low; // Make SCK pin low
delay(100); // Data pin should change it's value,
// when it is confirm that SCK is low
Set_SDA_Low; // Make SDA Low
delay(100); // 1/4 bit delay
Set_SCK_High; // Make SCK pin high
delay(100); // Half bit delay
}
void I2C_Stop(void)
{
Set_SCK_Low; // Make SCK pin low
delay(100); // Data pin should change it's value,
// when it is confirm that SCK is low
Set_SDA_Low; // Make SDA pin low
delay(100); // 1/4 bit delay
Set_SCK_High; // Make SCK pin high
delay(100); // 1/4 bit delay
Set_SDA_High; // Make SDA high
delay(100); // 1/4 bit delay
}
bit 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(100); // 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(100); // Toggle SCK pin
Set_SCK_High; // So that slave can
delay(100); // latch data bit
}
// Get ACK from slave
Set_SCK_Low;
Set_SDA_High;
delay(100);
Set_SCK_High;
delay(100);
DataPinADCMask = 0; // Make digital input
ACK = SDA; // Read data pin status
DataPinADCMask = 1; // Make analog output
return ACK;
}
unsigned char I2C_Read_Byte(void)
{
unsigned char i, RxData = 0;
for(i=0;i<8;i++)
{
Set_SCK_Low; // Make SCK pin low
Set_SDA_High; // Don't drive SDA
delay(100); // Half bit delay
Set_SCK_High; // Make SCK pin high
delay(100); // 1/4 bit delay
DataPinADCMask = 0; // Make digital input
RxData = RxData|(SDA<<(7-i)); // Captured received bit
DataPinADCMask = 1; // Make analog output
delay(100); // 1/4 bit delay
}
return RxData; // Return received byte
}
void InitCCT(void)
{
ANSEL = 0x00; // Set ports as digital I/O, not analog input
ADCON0 = 0x00; // Shut off the A/D Converter
CMCON = 0x07; // Shut off the Comparator
VRCON = 0x00; // Shut off the Voltage Reference
}
void main()
{
unsigned char RxByte = 0;
InitCCT(); // Turn off ADC and comparator to make pins digital IOs
InitI2C(); // Initialize i2c pins
I2C_Start(); // Send start bit on i2c
I2C_Write_Byte(0xA0); // Send 0xA0 on i2c
RxByte = I2C_Read_Byte(); // Read value from i2c
I2C_Send_ACK(); // Send ACK bit on i2c
I2C_Stop(); // Send stop bit on i2c
while(1)
{
}
}
No comments:
Post a Comment