Hi All,
I tried to use IO expansion chip that can controls up to 16 output by just using 2 wires (SDA and SCL). I'm using PCF8575 and interface with 8051 microcontroller (P89C51RD2HBA). I've connected 16 LED at the output side to see the result for the testing purpose. However, I'm stuck in the writing to the slave process, where i need to send 3 bytes of data to the slave.
Based on my findings :
1. We need to send 3 bytes of data : First is to determine slave address. In this case (0x40) as slave address based on PCF8575 datasheets.
2. Second byte is the data P0-P7 . (0xAA)
3. Third byte is the data P10-P17 . (0xF0)
4. The LED should turn ON at P0-P7 (10101010) and at P10-P17 (11110000)
But, the LED did not turn ON at all. The voltage at the output pin was around (1.1-1.3) which were not sufficient to turn on the LED.
Below, i attached the sourcecode, and appreciate any help to see which part i go wrong.
#include <REG51F.H>
#include <stdio.h>
#include <INPUT_OUTPUT.h>
#include <delay1.h>
// Function declarations
void initRS();
void initPort();
void I2C_Init();
void I2C_Start();
void I2C_Restart();
void I2C_Stop();
void I2C_SendAck();
void I2C_SendNack();
unsigned char I2C_Write(unsigned char Data);
unsigned char I2C_Read();
#define SDA p1_0
#define SCL p1_1
//Main function
void main()
{
initRS();
initPort();
I2C_Init();
//unsigned char RxByte = 0;
I2C_Start();
I2C_Write(0x40);
I2C_Write(0xAA);
I2C_Write(0xF0);
I2C_Read();
I2C_SendAck();
I2C_Stop();
}
//Function : I2C Write Byte transfer 3 bytes
unsigned char I2C_Write(unsigned char Data)
{
unsigned char i; // Variable to be used in for loop
for(i=0;i<8;i++) // Repeat for every bit
{
SCL = 0; // Make SCL pin low
delay1(); // Data pin should change it's value,
// when it is confirm that SCL is low
if ((Data & 0x40) == 0) //
SDA = 1;
else
SDA = 0;
delay1();
SCL = 1;
Data<<=1;
}
//Get ACK from slave
SCL = 0;
SDA = 1;
delay1();
SCL = 1;
SCL = 0;
return SDA;
//
for(i=0;i<8;i++) // Repeat for every bit
{
SCL = 0; // Make SCL pin low
delay1(); // Data pin should change it's value,
// when it is confirm that SCL is low
if ((Data & 0xAA) == 0) //10101010
SDA = 1;
else
SDA = 0;
delay1();
SCL = 1;
Data<<=1;
}
//Get ACK from slave
SCL = 0;
SDA = 1;
delay1();
SCL = 1;
SCL = 0;
return SDA;
//
for(i=0;i<8;i++) // Repeat for every bit
{
SCL = 0; // Make SCL pin low
delay1(); // Data pin should change it's value,
// when it is confirm that SCL is low
if ((Data & 0xF0) == 0) //11110000
SDA = 1;
else
SDA = 0;
delay1();
SCL = 1;
Data<<=1;
}
//Get ACK from slave
SCL = 0;
SDA = 1;
delay1();
SCL = 1;
SCL = 0;
return SDA ;
}
// Function : I2C Read Byte
unsigned char I2C_Read()
{
unsigned char i, Data=0;
for(i=0;i<8;i++){
SCL = 0;
SCL = 1;
delay1();
if(SDA)
Data |=1;
if(i<7)
Data<<=1;
}
SCL = 0;
SDA = 1;
return Data;
}
// Function : To set initial values of SDA and SCL
void I2C_Init()
{
SDA = 1; // Set SDA pin HIGH
SCL = 1; // Set SCL pin LOW
}
// Function : Master sending START condition, HIGH to LOW transition on SDA while SCL keeping high
void I2C_Start()
{
SCL = 1;
SDA = 1;
delay1();
SDA = 0;
SCL =1;
delay1();
}
void I2C_Restart()
{
SDA = 1;
SCL = 1;
SDA = 0;
}
void I2C_Stop()
{
SDA = 0;
SCL = 1;
SDA = 1;
}
void I2C_Ack()
{
SDA = 0;
SCL = 1;
SCL = 0;
}
void I2C_Nack()
{
SDA = 1;
SCL = 1;
SCL = 0;
}
// Initialize serial port
void initRS ()
{
SCON = 0x50; // SCON: mode 1, 8-bit UART, enable rcvr
TMOD = 0x20; // TMOD: timer 1, mode 2, 8-bit reload
TH1 = 253; // TH1: reload value for 9600 baud @ 11.0592MHz FDH
TR1 = 1; // TR1: timer 1 run
TI = 1; // TI: set TI to send first char of UART
}
//Initialize port
void initPort()
{
P1 = 0xFF;
P2 = 0x00;
P0 = 0x00;
}
Any help highly appreciated.
Thank you.